]>
git.gir.st - subscriptionfeed.git/blob - app/webhooks.py
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.
5 #TODO: fold update-websub.py into this?
9 from flask
import Flask
, request
10 from urllib
. parse
import parse_qs
, urlparse
12 from common
. common
import *
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' ))
24 if sig
!= websub_url_hmac ( hmackey
, subject
, timestamp
, nonce
):
27 if time
. time () - timestamp
> int ( cf
[ 'websub' ][ 'lease' ]):
30 if mode
!= "subscribe" :
32 # Note: channels are not purged from the websub dbtable.
34 with sqlite3
. connect ( cf
[ 'global' ][ 'database' ]) as conn
:
37 INSERT OR REPLACE INTO websub (channel_id, subscribed_until)
38 VALUES (?, datetime(?, 'unixepoch'))
39 """ , ( subject
, time
. time ()+ until
))
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=" , "" )
48 if sig
!= websub_url_hmac ( hmackey
, subject
, timestamp
, nonce
):
50 if hub_signature
!= websub_body_hmac ( hmackey
, request
. data
):
53 with sqlite3
. connect ( cf
[ 'global' ][ 'database' ]) as conn
:
56 update_channel ( conn
, request
. data
, from_webhook
= True )
57 except Exception as 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 " )
65 if __name__
== '__main__' :