X-Git-Url: https://git.frykholm.com/friends.git/blobdiff_plain/511b6ecb108d9a00340f1e58b849c3fcdb4536c9..b2b706690e67d4ff5c409902df14a8487268a561:/friends/server.py diff --git a/friends/server.py b/friends/server.py index 750ddc8..70f2f14 100644 --- a/friends/server.py +++ b/friends/server.py @@ -2,10 +2,13 @@ import tornado.ioloop import tornado.web import os, os.path import tornado.httpserver +import tornado.httpclient as httpclient import sqlite3 import arrow import datetime from rd import RD, Link +import hashlib +import hmac db = None #insert into user (name,email) values('mikael','mikael@frykholm.com'); #insert into entry (userid,text) values (1,'My thoughts on ostatus'); @@ -28,7 +31,7 @@ class PushHandler(tornado.web.RequestHandler): hub_topic = self.get_argument('hub.topic') hub_verify = self.get_argument('hub.verify') hub_lease_seconds = self.get_argument('hub.lease_seconds','') - hub_secret = self.get_argument('hub.sercret','') + hub_secret = self.get_argument('hub.secret','') hub_verify_token = self.get_argument('hub.verify_token','') print(self.request.body) if hub_mode == 'unsubscribe': @@ -36,12 +39,26 @@ class PushHandler(tornado.web.RequestHandler): path = hub_topic.split(self.settings['domain'])[1] user = path.split('user/')[1] row = db.execute("select id from user where name=?",(user,)).fetchone() + expire = datetime.datetime.utcnow() + datetime.timedelta(seconds=int(hub_lease_seconds)) if row: - db.execute("INSERT into subscriptions (userid, expires, callback, verified) values (?,?,?,?)",(row['id'],datetime.datetime.now(),hub_callback,False)) + db.execute("INSERT into subscriptions (userid, expires, callback, secret, verified) " + "values (?,?,?,?,?)",(row['id'],expire,hub_callback,hub_secret,False)) db.commit() self.set_status(202) - #TODO add GET callback with the same data we got - #TODO store secret, add it to outgoing feeds with hmac + http_client = httpclient.HTTPClient() + try: + response = http_client.fetch(hub_callback+"?hub.mode={}&hub.topic={}&hub.secret".format(hub_mode,hub_topic,hub_secret)) + print(response.body) + except httpclient.HTTPError as e: + # HTTPError is raised for non-200 responses; the response + # can be found in e.response. + print("Error: " + str(e)) + except Exception as e: + # Other errors are possible, such as IOError. + print("Error: " + str(e)) + http_client.close() + #TODO add secret to outgoing feeds with hmac + class XrdHandler(tornado.web.RequestHandler): def get(self): self.render("templates/xrd.xml", hostname="ronin.frykholm.com", url=self.settings['domain']) @@ -72,19 +89,38 @@ class FingerHandler(tornado.web.RequestHandler): rd.links.append(lnk) rd.links.append(lnk2) self.write(rd.to_json()) - #self.render("templates/user.xml", user=user) 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() self.set_header("Content-Type", 'application/atom+xml') - self.render("templates/feed.xml", + out = self.render("templates/feed.xml", user=user, feed_url="{}/user/{}".format(self.settings['domain'], user), hub_url="{}/hub".format(self.settings['domain']), entries=entries, 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() + subscribers = db.execute("select callback, secret from subscriptions, user where user.id=subscriptions.userid and user.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), @@ -92,10 +128,7 @@ application = tornado.web.Application([ (r"/user/(.+)", UserHandler), (r"/hub", PushHandler), ],debug=True,**settings) -srv = tornado.httpserver.HTTPServer(application, ssl_options={ - "certfile": "ronin.frykholm.com.pem", - "keyfile": "ronin.frykholm.com.key", - }) +srv = tornado.httpserver.HTTPServer(application, ) def setup_db(path): print("No db found, creating in {}".format(path)) con = sqlite3.connect(path) @@ -111,6 +144,7 @@ def setup_db(path): userid integer, expires datetime, callback varchar, + secret varchar, verified bool, FOREIGN KEY(userid) REFERENCES user(id));""") con.commit() @@ -122,5 +156,6 @@ if __name__ == "__main__": setup_db(dbPath) db = sqlite3.connect(dbPath, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) db.row_factory = sqlite3.Row - srv.listen(443) + srv.listen(8080) tornado.ioloop.IOLoop.instance().start() +