11import base64
22from datetime import datetime
3+ import hashlib
34import hmac
45
56class 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
1424class 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