]> git.frykholm.com Git - friends.git/blobdiff - friends/server.py
Change schema to store xml directly to db
[friends.git] / friends / server.py
old mode 100644 (file)
new mode 100755 (executable)
index 853e78c..1fbff40
@@ -1,29 +1,34 @@
+#!/usr/bin/python3
 import tornado.ioloop
 import tornado.web
 import tornado.ioloop
 import tornado.web
-import os, os.path
+import os
+import os.path
 import tornado.httpserver
 import tornado.httpclient as httpclient
 import sqlite3
 import arrow
 import datetime
 from rd import RD, Link
 import tornado.httpserver
 import tornado.httpclient as httpclient
 import sqlite3
 import arrow
 import datetime
 from rd import RD, Link
-import hashlib
 import hmac
 import hmac
+from tornado.options import options, define
+import logging
 db = None
 db = None
-#insert into user (name,email) values('mikael','mikael@frykholm.com');
-#insert into entry (userid,text) values (1,'My thoughts on ostatus');
-import tornado.options
+# insert into user (name,email) values('mikael','mikael@frykholm.com');
+# insert into entry (userid,text) values (1,'My thoughts on ostatus');
+
 
 settings = {
     "static_path": os.path.join(os.path.dirname(__file__), "static"),
 
 settings = {
     "static_path": os.path.join(os.path.dirname(__file__), "static"),
-    "cookie_secret": "__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
+    "cookie_secret": "supersecret123",
     "login_url": "/login",
     "xsrf_cookies": False,
     "domain":"https://ronin.frykholm.com",
     
 }
     "login_url": "/login",
     "xsrf_cookies": False,
     "domain":"https://ronin.frykholm.com",
     
 }
-class PushHandler(tornado.web.RequestHandler):
+
 #curl -v -k "https://ronin.frykholm.com/hub" -d "hub.callback=a" -d "hub.mode=b" -d "hub.topic=c" -d "hub.verify=d"
 #curl -v -k "https://ronin.frykholm.com/hub" -d "hub.callback=a" -d "hub.mode=b" -d "hub.topic=c" -d "hub.verify=d"
+
+class PushHandler(tornado.web.RequestHandler):
     def post(self):
         """ Someone wants to subscribe to hub_topic feed"""
         hub_callback = self.get_argument('hub.callback')
     def post(self):
         """ Someone wants to subscribe to hub_topic feed"""
         hub_callback = self.get_argument('hub.callback')
@@ -38,10 +43,10 @@ class PushHandler(tornado.web.RequestHandler):
             pass #FIXME
         path = hub_topic.split(self.settings['domain'])[1]
         user = path.split('user/')[1]
             pass #FIXME
         path = hub_topic.split(self.settings['domain'])[1]
         user = path.split('user/')[1]
-        row = db.execute("select id from user where name=?",(user,)).fetchone()
+        row = db.execute("select id from author where name=?",(user,)).fetchone()
         expire = datetime.datetime.utcnow() + datetime.timedelta(seconds=int(hub_lease_seconds))
         if row:
         expire = datetime.datetime.utcnow() + datetime.timedelta(seconds=int(hub_lease_seconds))
         if row:
-            db.execute("INSERT into subscriptions (userid, expires, callback, secret, verified) "
+            db.execute("INSERT into subscriptions (author, expires, callback, secret, verified) "
                        "values (?,?,?,?,?)",(row['id'],expire,hub_callback,hub_secret,False))
             db.commit()
             self.set_status(202)
                        "values (?,?,?,?,?)",(row['id'],expire,hub_callback,hub_secret,False))
             db.commit()
             self.set_status(202)
@@ -63,13 +68,25 @@ class XrdHandler(tornado.web.RequestHandler):
     def get(self):
         self.render("templates/xrd.xml", hostname="ronin.frykholm.com", url=self.settings['domain'])
 
     def get(self):
         self.render("templates/xrd.xml", hostname="ronin.frykholm.com", url=self.settings['domain'])
 
+class apa():
+    def LookupPublicKey(self, signer_uri=None):
+        return """RSA.jj2_lJ348aNh_9s3eCHlJlbMQdnHVm9svdU2ESW86TvV-4wZId-z3M029pjPvco0UEvlUUnJytXwoTLd70pzfZ8Cu5MMwGbvm9asI9-PKUDSNFgr5T_B017qUXOG5UH1ZNI_fVA2mSAkxxfEksv4HXg43dBvEIW94JpyAtqggHM=.AQAB.Bzz_LcnoLCu7RfDa3sMizROnq0YwzaY362UZLkA0X84KspVLhhzDI15SCLR4BdlvVhK2pa9SlH7Uku9quc2ZGNyr5mEdqjO7YTbQA9UCgbobEq2ImqV_j7Y4IfjPc8prDPCKb_mO9DUlS_ZUxJYfsOuc-SVlGmPZ93uEl8i9OjE="""
+
+
+class SalmonHandler(tornado.web.RequestHandler):
+    def post(self, user):
+        sp = salmoning.SalmonProtocol()
+        sp.key_retriever = apa()
+        data = sp.ParseSalmon(self.request.body)
+        pass
+
 class FingerHandler(tornado.web.RequestHandler):
     def get(self):
         user = self.get_argument('resource')
         user = user.split('acct:')[1]
         (user,domain) = user.split('@')
 class FingerHandler(tornado.web.RequestHandler):
     def get(self):
         user = self.get_argument('resource')
         user = user.split('acct:')[1]
         (user,domain) = user.split('@')
-        rows = db.execute("select id from user where user.name=?",(user,)).fetchone()
-        if not rows:
+        row = db.execute("select id,salmon_pubkey from author where author.name=?",(user,)).fetchone()
+        if not row:
             self.set_status(404)
             self.write("Not found")
             self.finish()
             self.set_status(404)
             self.write("Not found")
             self.finish()
@@ -88,12 +105,20 @@ class FingerHandler(tornado.web.RequestHandler):
         rd.properties.append('http://spec.example.net/type/person')
         rd.links.append(lnk)
         rd.links.append(lnk2)
         rd.properties.append('http://spec.example.net/type/person')
         rd.links.append(lnk)
         rd.links.append(lnk2)
+        rd.links.append(Link(rel="magic-public-key",
+                             href="data:application/magic-public-key,RSA."+row['salmon_pubkey']))
+        rd.links.append(Link(rel="salmon",
+                             href="{}/salmon/{}".format(self.settings['domain'],user)))
+        rd.links.append(Link(rel="http://salmon-protocol.org/ns/salmon-replies",
+                             href="{}/salmon/{}".format(self.settings['domain'],user)))
+        rd.links.append(Link(rel="http://salmon-protocol.org/ns/salmon-mention",
+                             href="{}/salmon/{}".format(self.settings['domain'],user)))
         self.write(rd.to_json())
 
 class UserHandler(tornado.web.RequestHandler):
     def get(self, user):
         self.write(rd.to_json())
 
 class UserHandler(tornado.web.RequestHandler):
     def get(self, user):
-        entries = db.execute("select entry.id,text,ts from user,entry where user.id=entry.userid and user.name=?",(user,))
-        #import pdb;pdb.set_trace()
+        entries = db.execute("select entry.id,text,ts from author,entry where author.id=entry.author and author.name=?",(user,))
+        # import pdb;pdb.set_trace()
         self.set_header("Content-Type", 'application/atom+xml')
         out = self.render("templates/feed.xml",
                     user=user, 
         self.set_header("Content-Type", 'application/atom+xml')
         out = self.render("templates/feed.xml",
                     user=user, 
@@ -103,6 +128,26 @@ class UserHandler(tornado.web.RequestHandler):
                     arrow=arrow )
         #digest = hmac.new()
 
                     arrow=arrow )
         #digest = hmac.new()
 
+    def post(self, user):
+        entries = db.execute("select entry.id,text,ts from user,entry where user.id=entry.userid and user.name=?",(user,))
+
+        self.set_header("Content-Type", 'application/atom+xml')
+        out = self.render_string("templates/feed.xml",
+                          user=user,
+                          feed_url="{}/user/{}".format(self.settings['domain'], user),
+                          hub_url="{}/hub".format(self.settings['domain']),
+                          entries=entries,
+                          arrow=arrow)
+        #import pdb;pdb.set_trace()
+        # Notify subscribers
+        subscribers = db.execute("select callback, secret from subscriptions, author where author.id=subscriptions.author and author.name=?",(user,))
+        for url,secret in subscribers:
+            digest = hmac.new(secret.encode('utf8'), out, digestmod='sha1').hexdigest()
+
+            req = httpclient.HTTPRequest(url=url, allow_nonstandard_methods=True,method='POST', body=out, headers={"X-Hub-Signature":"sha1={}".format(digest),"Content-Type": 'application/atom+xml',"Content-Length":len(out)})
+            apa = httpclient.HTTPClient()
+            apa.fetch(req)
+
 application = tornado.web.Application([
     (r"/.well-known/host-meta", XrdHandler),
     (r"/.well-known/webfinger", FingerHandler),
 application = tornado.web.Application([
     (r"/.well-known/host-meta", XrdHandler),
     (r"/.well-known/webfinger", FingerHandler),
@@ -110,34 +155,49 @@ application = tornado.web.Application([
     (r"/hub", PushHandler),
     ],debug=True,**settings)
 srv = tornado.httpserver.HTTPServer(application, )
     (r"/hub", PushHandler),
     ],debug=True,**settings)
 srv = tornado.httpserver.HTTPServer(application, )
+
 def setup_db(path):
 def setup_db(path):
-    print("No db found, creating in {}".format(path))
+    gen_log = logging.getLogger("tornado.general")
+    gen_log.warn("No db found, creating in {}".format(path))
     con = sqlite3.connect(path)
     con = sqlite3.connect(path)
-    con.execute(""" create table user (id integer primary key,
+    con.execute("""create table author (id integer primary key,
+                                       uri varchar,
                                        name varchar,
                                        name varchar,
-                                       email varchar);
-                    create table entry (id integer primary key, 
-                                        userid INTEGER, 
-                                        text varchar,
+                                       email varchar,
+                                       salmon_pubkey varchar, -- base64_urlencoded public modulus +.+ base64_urlencoded public exponent
+                                       salmon_privkey varchar  -- base64_urlencoded private exponent
+                                       );""")
+    con.execute(""" create table entry (id integer primary key, 
+                                        author INTEGER, 
+                                        text varchar, -- xml atom <entry>
+                                        verb varchar,
                                         ts timestamp default current_timestamp,
                                         ts timestamp default current_timestamp,
-                                        FOREIGN KEY(userid) REFERENCES user(id));
+                                        FOREIGN KEY(author) REFERENCES author(id));""")
+    con.execute("""
                     create table subscriptions (id integer primary key,
                     create table subscriptions (id integer primary key,
-                                        userid integer,
+                                        author integer,
                                         expires datetime,
                                         callback varchar,
                                         secret varchar,
                                         verified bool,
                                         expires datetime,
                                         callback varchar,
                                         secret varchar,
                                         verified bool,
-                                        FOREIGN KEY(userid) REFERENCES user(id));""")
+                                        FOREIGN KEY(author) REFERENCES author(id));""")
     con.commit()
 
     con.commit()
 
+
+options.define("config_file", default="/etc/friends/friends.conf", type=str)
+options.define("webroot", default="/srv/friends/", type=str)
+
 if __name__ == "__main__":
     dbPath = 'friends.db'
 if __name__ == "__main__":
     dbPath = 'friends.db'
+#    options.log_file_prefix="/tmp/friends"
+    tornado.options.parse_config_file(options.config_file)
     tornado.options.parse_command_line()
     tornado.options.parse_command_line()
+    gen_log = logging.getLogger("tornado.general")
+    gen_log.info("Reading config from: %s", options.config_file,)
     if not os.path.exists(dbPath):
         setup_db(dbPath)
     db = sqlite3.connect(dbPath, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
     db.row_factory = sqlite3.Row
     if not os.path.exists(dbPath):
         setup_db(dbPath)
     db = sqlite3.connect(dbPath, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
     db.row_factory = sqlite3.Row
-    srv.listen(8080)
+    srv.listen(80)
     tornado.ioloop.IOLoop.instance().start()
     tornado.ioloop.IOLoop.instance().start()
-    #TODO hmac.new(b'5cc324285ece71e21e9554f4056563806f6ce0b7e4ab18d0133b602f8ba7e87a',open("apa.xml","rb").read(),digestmod='sha1').hexdigest()
-'b75d4733e0802629a0c15d0faa8de8fc9778cd05' queue runner
+