77
88sys .path .insert (1 , f"{ dirname (__file__ )} /../../.." )
99logging .basicConfig (level = logging .DEBUG )
10- # ------------------
11-
12- # ---------------------
13- # Slack Request Verification
14- # https://github.com/slackapi/python-slack-events-api
15- # ---------------------
16-
17- import hmac
18- import hashlib
19- from time import time
20-
21-
22- def verify_request (
23- signing_secret : str ,
24- request_body : str ,
25- timestamp : str ,
26- signature : str ) -> bool :
27- if abs (time () - int (timestamp )) > 60 * 5 :
28- return False
29-
30- if hasattr (hmac , "compare_digest" ):
31- req = str .encode ('v0:' + str (timestamp ) + ':' ) + request_body
32- request_hash = 'v0=' + hmac .new (
33- str .encode (signing_secret ),
34- req , hashlib .sha256
35- ).hexdigest ()
36- return hmac .compare_digest (request_hash , signature )
37- else :
38- # So, we'll compare the signatures explicitly
39- req = str .encode ('v0:' + str (timestamp ) + ':' ) + request_body
40- request_hash = 'v0=' + hmac .new (
41- str .encode (signing_secret ),
42- req , hashlib .sha256
43- ).hexdigest ()
44-
45- if len (request_hash ) != len (signature ):
46- return False
47- result = 0
48- if isinstance (request_hash , bytes ) and isinstance (signature , bytes ):
49- for x , y in zip (request_hash , signature ):
50- result |= x ^ y
51- else :
52- for x , y in zip (request_hash , signature ):
53- result |= ord (x ) ^ ord (y )
54- return result == 0
55-
5610
5711# ---------------------
5812# Slack WebClient
@@ -62,8 +16,10 @@ def verify_request(
6216
6317from slack import WebClient
6418from slack .errors import SlackApiError
19+ from slack .signature import SignatureVerifier
6520
6621client = WebClient (token = os .environ ["SLACK_API_TOKEN" ])
22+ signature_verifier = SignatureVerifier (os .environ ["SLACK_SIGNING_SECRET" ])
6723
6824# ---------------------
6925# Flask App
@@ -73,16 +29,11 @@ def verify_request(
7329from flask import Flask , request , make_response
7430
7531app = Flask (__name__ )
76- signing_secret = os .environ ["SLACK_SIGNING_SECRET" ]
7732
7833
7934@app .route ("/slack/events" , methods = ["POST" ])
8035def slack_app ():
81- if not verify_request (
82- signing_secret = signing_secret ,
83- request_body = request .get_data (),
84- timestamp = request .headers .get ("X-Slack-Request-Timestamp" ),
85- signature = request .headers .get ("X-Slack-Signature" )):
36+ if not signature_verifier .is_valid_request (request .get_data (), request .headers ):
8637 return make_response ("invalid request" , 403 )
8738
8839 if "command" in request .form \
0 commit comments