Skip to content

Commit d98bc1f

Browse files
committed
Add invalid signature exception and hashlib.
1 parent 32fd73c commit d98bc1f

File tree

1 file changed

+48
-9
lines changed

1 file changed

+48
-9
lines changed

convoy/utils/webhook.py

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import base64
22
from datetime import datetime
3+
import hashlib
34
import hmac
45

56
class InvalidTimestampError(Exception):
@@ -9,21 +10,51 @@ def __init__(self, *args: list) -> None:
910
@property
1011
def response(self):
1112
return self.message
13+
14+
15+
class InvalidSignature(Exception):
16+
def __init__(self, *args: list) -> None:
17+
self.message = args[0]
18+
19+
@property
20+
def response(self):
21+
return self.message
1222

1323

1424
class Webhook:
1525
def __init__(self, secret: str, encoding: str = "hex", tolerance: int = 300, hash: str = "sha256") -> None:
1626
self.secret = secret
1727
self.encoding = encoding
1828
self.tolerance = tolerance
19-
self.hash = hash
29+
self.hash = self.get_hash_function(hash)
30+
31+
def get_hash_function(self, hash: str) -> str:
32+
if str.lower(hash) == "sha256":
33+
return hashlib.sha256
34+
if str.lower(hash) == "md5":
35+
return hashlib.md5
36+
if str.lower(hash) == "sha384":
37+
return hashlib.sha384
38+
if str.lower(hash) == "sha224":
39+
return hashlib.sha224
40+
if str.lower(hash) == "sha512":
41+
return hashlib.sha512
42+
if str.lower(hash) == "sha1":
43+
return hashlib.sha1
44+
if str.lower(hash) == "sha3_256":
45+
return hashlib.sha3_256
46+
if str.lower(hash) == "sha3_224":
47+
return hashlib.sha3_224
48+
if str.lower(hash) == "sha3_512":
49+
return hashlib.sha3_512
50+
else:
51+
raise Exception("algorithm not available.")
2052

2153
def verify_timestamp(self, timestamp):
2254
try:
2355
now = round(datetime.now().timestamp())
2456
timestamp_int = int(timestamp.timestamp())
2557

26-
print("Now: ", now)
2758
diff = now - self.tolerance
2859

2960
if timestamp_int < diff:
@@ -37,9 +68,15 @@ def verify_timestamp(self, timestamp):
3768

3869
def compare_hashes(self, hash1: str, hash2: str) -> bool:
3970
if self.encoding == "hex":
40-
return hash1 == hash2
71+
valid = hmac.compare_digest(hash1, hash2)
72+
if valid is False:
73+
raise InvalidSignature("Invalid signature.")
74+
return valid
4175
if self.encoding == "base64":
42-
return hmac.compare_digest(base64.b64decode(hash1), base64.b64decode(hash2))
76+
valid = hmac.compare_digest(base64.b64decode(hash1), base64.b64decode(hash2))
77+
if valid is False:
78+
raise InvalidSignature("Invalid signature.")
79+
4380

4481
def create_signature(self, payload: str) -> str:
4582
# If the encoding is hex, create a new hex hmac digest
@@ -72,8 +109,11 @@ def verify_signature(self, payload: str, signature: str) -> bool:
72109
return self.verify_simple_signature(payload, signature)
73110

74111
def verify_simple_signature(self, payload: str, signature: str) -> bool:
75-
return self.compare_hashes(self.create_signature(payload), signature)
76-
112+
try:
113+
return self.compare_hashes(self.create_signature(payload), signature)
114+
except InvalidSignature as e:
115+
return e.response
116+
77117
def verify_advanced_signature(self, payload: str, signature: str) -> bool:
78118
timestamp, signature = self.get_timestamp_and_signatures(signature)
79119

@@ -83,6 +123,5 @@ def verify_advanced_signature(self, payload: str, signature: str) -> bool:
83123
else:
84124
return self.compare_hashes(self.create_signature(payload), signature[1])
85125

86-
except InvalidTimestampError as e:
87-
return e.response
88-
126+
except (InvalidTimestampError, InvalidSignature) as e:
127+
return e.response

0 commit comments

Comments
 (0)