]>
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 mode
= request
. args
. get ( 'hub.mode' , '' )
19 topic
= request
. args
. get ( 'hub.topic' , '' )
20 challenge
= request
. args
. get ( 'hub.challenge' , '' )
21 until
= int ( request
. args
. get ( 'hub.lease_seconds' , '0' ))
23 # extract the first query parameter, which is either channel_id or playlist_id:
24 channel_id
= next ( iter ( parse_qs ( urlparse ( topic
). query
). values ()), [ None ])[ 0 ]
29 if time
. time () - timestamp
> int ( cf
[ 'websub' ][ 'lease' ]):
31 # TODO: implement hmac check: return '',400 unless hmac_sha1_hex("$timestamp/$nonce", $HMACKEY) eq $sig
33 if mode
!= "subscribe" :
35 # Note: channels are not purged from the websub dbtable.
37 with sqlite3
. connect ( cf
[ 'global' ][ 'database' ]) as conn
:
40 INSERT OR REPLACE INTO websub (channel_id, subscribed_until)
41 VALUES (?, datetime(?, 'unixepoch'))
42 """ , ( channel_id
, time
. time ()+ until
))
45 @app . route ( '/websub/v1/<int:timestamp>/<nonce>/<subject>/<sig>' , methods
=[ "POST" ])
46 def websub_post ( timestamp
, nonce
, subject
, sig
):
47 # TODO: implement hmac check: return '',400 unless hmac_sha1_hex("$timestamp/$nonce", $HMACKEY) eq $sig
48 # todo: # say 400 and exit unless hmac_sha1_hex($body, $HMACKEY) eq $ENV{X-Hub-Signature }
49 lease
= cf
[ 'websub' ][ 'lease' ]
50 hmackey
= cf
[ 'websub' ][ 'hmac_key' ]
52 if sig
!= websub_url_hmac ( hmackey
, subject
, timestamp
, nonce
):
53 app
. logger
. warning ( "url hmac failed (request was not authorized by us)" )
55 if request
. headers
. get ( 'X-Hub-Signature' ). replace ( "sha1=" , "" ) != websub_body_hmac ( hmackey
, request
. data
):
56 app
. logger
. warning ( "body hmac failed (request was not authenticated from websub hub)" )
59 with sqlite3
. connect ( cf
[ 'global' ][ 'database' ]) as conn
:
62 update_channel ( conn
, request
. data
)
63 except Exception as e
:
65 with
open ( '/tmp/websub-subscriptions.err' , 'ab' ) as f
:
66 #data = request.data.decode("utf-8", errors="ignore")
67 f
. write ( f
"<!-- {time.ctime()} ({int(time.time())}) --> \n " . encode ( 'ascii' ))
68 f
. write ( request
. data
+ b
" \n " )
71 if __name__
== '__main__' :