]>
git.gir.st - subscriptionfeed.git/blob - app/webhooks/__init__.py
2 This is the webhook server that interfaces with Google's WebSub (formerly
3 pubsubhubbub) server. This can be run either as a module on the main frontend,
4 or as its own server, so it can live on a different host than the frontend.
9 from flask
import Flask
, Blueprint
, request
10 from urllib
.parse
import parse_qs
, urlparse
12 from ..common
.common
import *
14 frontend
= Blueprint('webhooks', __name__
)
18 app
.register_blueprint(frontend
)
21 @frontend.route('/websub/v1/<int:timestamp>/<nonce>/<subject>/<sig>', methods
=["GET"])
22 def websub(timestamp
, nonce
, subject
, sig
):
23 hmackey
= cf
['websub']['hmac_key']
24 mode
= request
.args
.get('hub.mode', '')
25 topic
= request
.args
.get('hub.topic', '')
26 challenge
= request
.args
.get('hub.challenge', '')
27 until
= int(request
.args
.get('hub.lease_seconds', '0'))
29 if sig
!= websub_url_hmac(hmackey
, subject
, timestamp
, nonce
):
32 if time
.time() - timestamp
> int(cf
['websub']['lease']):
35 if mode
!= "subscribe":
37 # Note: channels are not purged from the websub dbtable.
39 with sqlite3
.connect(cf
['global']['database']) as conn
:
42 INSERT OR REPLACE INTO websub (channel_id, subscribed_until)
43 VALUES (?, datetime(?, 'unixepoch'))
44 """, (subject
, time
.time()+until
))
47 @frontend.route('/websub/v1/<int:timestamp>/<nonce>/<subject>/<sig>', methods
=["POST"])
48 def websub_post(timestamp
, nonce
, subject
, sig
):
49 lease
= cf
['websub']['lease']
50 hmackey
= cf
['websub']['hmac_key']
51 hub_signature
= request
.headers
.get('X-Hub-Signature').replace("sha1=", "")
53 if sig
!= websub_url_hmac(hmackey
, subject
, timestamp
, nonce
):
55 if hub_signature
!= websub_body_hmac(hmackey
, request
.data
):
58 with sqlite3
.connect(cf
['global']['database']) as conn
:
61 update_channel(conn
, request
.data
, from_webhook
=True)
62 except Exception as e
:
64 with
open('/tmp/websub-subscriptions.err', 'ab') as f
:
65 f
.write(f
"<!-- {time.ctime()} ({int(time.time())}) -->\n".encode('ascii'))
66 f
.write(request
.data
+ b
"\n")
69 if __name__
== '__main__':