MCPcopy Index your code
hub / github.com/slackapi/python-slack-sdk / SignatureVerifier

Class SignatureVerifier

slack/signature/verifier.py:13–71  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

11
12
13class SignatureVerifier:
14 def __init__(self, signing_secret: str, clock: Clock = Clock()):
15 """Slack request signature verifier
16
17 Slack signs its requests using a secret that's unique to your app.
18 With the help of signing secrets, your app can more confidently verify
19 whether requests from us are authentic.
20 https://docs.slack.dev/authentication/verifying-requests-from-slack/
21 """
22 self.signing_secret = signing_secret
23 self.clock = clock
24
25 def is_valid_request(
26 self,
27 body: Union[str, bytes],
28 headers: Dict[str, str],
29 ) -> bool:
30 """Verifies if the given signature is valid"""
31 if headers is None:
32 return False
33 normalized_headers = {k.lower(): v for k, v in headers.items()}
34 return self.is_valid(
35 body=body,
36 timestamp=normalized_headers.get("x-slack-request-timestamp", None),
37 signature=normalized_headers.get("x-slack-signature", None),
38 )
39
40 def is_valid(
41 self,
42 body: Union[str, bytes],
43 timestamp: str,
44 signature: str,
45 ) -> bool:
46 """Verifies if the given signature is valid"""
47 if timestamp is None or signature is None:
48 return False
49
50 if abs(self.clock.now() - int(timestamp)) > 60 * 5:
51 return False
52
53 calculated_signature = self.generate_signature(timestamp=timestamp, body=body)
54 if calculated_signature is None:
55 return False
56 return hmac.compare_digest(calculated_signature, signature)
57
58 def generate_signature(self, *, timestamp: str, body: Union[str, bytes]) -> Optional[str]:
59 """Generates a signature"""
60 if timestamp is None:
61 return None
62 if body is None:
63 body = ""
64 if isinstance(body, bytes):
65 body = body.decode("utf-8")
66
67 format_req = str.encode(f"v0:{timestamp}:{body}")
68 encoded_secret = str.encode(self.signing_secret)
69 request_hash = hmac.new(encoded_secret, format_req, hashlib.sha256).hexdigest()
70 calculated_signature = f"v0={request_hash}"

Callers 15

oauth_sqlite3.pyFile · 0.90
oauth_async.pyFile · 0.90
oauth.pyFile · 0.90
steps_from_apps.pyFile · 0.90
oauth_v2.pyFile · 0.90
oauth_v2_async.pyFile · 0.90
issue_838.pyFile · 0.90
views.pyFile · 0.90
views_2.pyFile · 0.90

Calls

no outgoing calls