]> git.gir.st - subscriptionfeed.git/blob - app/webhooks.py
awful hack to align last row of cards
[subscriptionfeed.git] / app / webhooks.py
1 """
2 This is the webhook server that interfaces with Google's WebSub (formerly pubsubhubbub) server. This is its own server, so it can live on a different host than the frontend.
3 """
4
5 #TODO: fold update-websub.py into this?
6
7 import time
8 import sqlite3
9 from flask import Flask, request
10 from urllib.parse import parse_qs, urlparse
11
12 from common.common import *
13
14 app = Flask(__name__)
15
16 @app.route('/websub/v1/<int:timestamp>/<nonce>/<subject>/<sig>', methods=["GET"])
17 def websub(timestamp, nonce, subject, sig):
18 hmackey = cf['websub']['hmac_key']
19 mode = request.args.get('hub.mode', '')
20 topic = request.args.get('hub.topic', '')
21 challenge = request.args.get('hub.challenge', '')
22 until = int(request.args.get('hub.lease_seconds', '0'))
23
24 if sig != websub_url_hmac(hmackey, subject, timestamp, nonce):
25 return '', 400
26
27 if time.time() - timestamp > int(cf['websub']['lease']):
28 return '', 400
29
30 if mode != "subscribe":
31 return '', 200
32 # Note: channels are not purged from the websub dbtable.
33
34 with sqlite3.connect(cf['global']['database']) as conn:
35 c = conn.cursor()
36 c.execute("""
37 INSERT OR REPLACE INTO websub (channel_id, subscribed_until)
38 VALUES (?, datetime(?, 'unixepoch'))
39 """, (subject, time.time()+until))
40 return challenge, 200
41
42 @app.route('/websub/v1/<int:timestamp>/<nonce>/<subject>/<sig>', methods=["POST"])
43 def websub_post(timestamp, nonce, subject, sig):
44 lease = cf['websub']['lease']
45 hmackey = cf['websub']['hmac_key']
46 hub_signature = request.headers.get('X-Hub-Signature').replace("sha1=", "")
47
48 if sig != websub_url_hmac(hmackey, subject, timestamp, nonce):
49 return '', 400
50 if hub_signature != websub_body_hmac(hmackey, request.data):
51 return '', 400
52
53 with sqlite3.connect(cf['global']['database']) as conn:
54 c = conn.cursor()
55 try:
56 update_channel(conn, request.data, from_webhook=True)
57 except Exception as e:
58 app.logger.error(e)
59 with open('/tmp/websub-subscriptions.err', 'ab') as f:
60 #data = request.data.decode("utf-8", errors="ignore")
61 f.write(f"<!-- {time.ctime()} ({int(time.time())}) -->\n".encode('ascii'))
62 f.write(request.data + b"\n")
63 return '', 200
64
65 if __name__ == '__main__':
66 app.run(debug=True)
Imprint / Impressum