1
+ import hashlib
2
+ import hmac
1
3
import json
2
4
import sys
3
5
11
13
import waitress
12
14
13
15
14
- def create_app (config ):
16
+ def create_app (config , webhook_secret = None ):
15
17
app = flask .Flask (__name__ )
16
18
17
19
# The canonical URL is /webhook, but other URLs are accepted for backward
@@ -20,6 +22,20 @@ def create_app(config):
20
22
@app .route ("/newpr.py" , methods = ['POST' ])
21
23
@app .route ("/highfive/newpr.py" , methods = ['POST' ])
22
24
def new_pr ():
25
+ raw_data = flask .request .get_data ()
26
+
27
+ # Check the signature only if the secret is configured
28
+ if 'payload' in flask .request .form and webhook_secret is not None :
29
+ expected = hmac .new (str (webhook_secret ), digestmod = hashlib .sha1 )
30
+ expected .update (raw_data )
31
+ expected = expected .hexdigest ()
32
+ try :
33
+ signature = str (flask .request .headers ['X-Hub-Signature' ])
34
+ except KeyError :
35
+ return 'Error: missing signature\n ' , 400
36
+ if not hmac .compare_digest ('sha1=' + expected , signature ):
37
+ return 'Error: invalid signature\n ' , 403
38
+
23
39
try :
24
40
payload = json .loads (flask .request .form ['payload' ])
25
41
except (KeyError , ValueError ), _ :
@@ -40,15 +56,16 @@ def index():
40
56
@click .command ()
41
57
@click .option ('--port' , default = 8000 )
42
58
@click .option ('--github-token' , required = True )
43
- def cli (port , github_token ):
59
+ @click .option ("--webhook-secret" )
60
+ def cli (port , github_token , webhook_secret ):
44
61
try :
45
62
config = Config (github_token )
46
63
except InvalidTokenException :
47
64
print 'error: invalid github token provided!'
48
65
sys .exit (1 )
49
66
print 'Found a valid GitHub token for user @' + config .github_username
50
67
51
- app = create_app (config )
68
+ app = create_app (config , webhook_secret )
52
69
waitress .serve (app , port = port )
53
70
54
71
0 commit comments