@@ -65,13 +65,15 @@ def create_webhook_signature(payload: Any, timestamp: str, secret: str) -> str:
6565 Returns:
6666 The HMAC-SHA256 signature as a hex string
6767 """
68- # Sort keys and use compact JSON format (equivalent to fast-json-stable-stringify)
68+
6969 dump = json .dumps (payload , separators = ("," , ":" ), sort_keys = True )
7070 message = f"{ timestamp } .{ dump } "
7171
7272 # Create HMAC-SHA256 signature
7373 hmac_obj = hmac .new (secret .encode (), message .encode (), hashlib .sha256 )
74- return hmac_obj .hexdigest ()
74+ signature = hmac_obj .hexdigest ()
75+
76+ return signature
7577
7678
7779def verify_webhook_event_signature (
@@ -94,20 +96,20 @@ def verify_webhook_event_signature(
9496 None if the signature is invalid, otherwise the parsed webhook event.
9597 """
9698 try :
97- # Parse body if it's a string
9899 if isinstance (body , str ):
99100 json_data = json .loads (body )
100101 else :
101102 json_data = body
102103
103- # Try to parse as each webhook type
104+ # PARSE
105+
104106 webhook_event : Optional [Webhook ] = None
105107
106- # Try test webhook first
107- try :
108- webhook_event = WebhookTest (** json_data )
109- except Exception :
110- pass
108+ if webhook_event is None :
109+ try :
110+ webhook_event = WebhookTest (** json_data )
111+ except Exception :
112+ pass
111113
112114 # Try agent task status update webhook
113115 if webhook_event is None :
@@ -119,10 +121,12 @@ def verify_webhook_event_signature(
119121 if webhook_event is None :
120122 return None
121123
122- # Create expected signature
123- expected_signature = create_webhook_signature (payload = webhook_event .payload , timestamp = timestamp , secret = secret )
124+ # Verify
125+
126+ expected_signature = create_webhook_signature (
127+ payload = webhook_event .payload .model_dump (), timestamp = timestamp , secret = secret
128+ )
124129
125- # Compare signatures using timing-safe comparison
126130 if not hmac .compare_digest (signature , expected_signature ):
127131 return None
128132
0 commit comments