ForcePilot/backend/package/yuxi/channel/extensions/zoomchat/crypto.py

49 lines
1.4 KiB
Python
Raw Normal View History

import hmac
import hashlib
import time
import logging
logger = logging.getLogger(__name__)
SIGNATURE_VERSION = "v0"
WEBHOOK_TOLERANCE_SECONDS = 300
def verify_webhook_signature(
raw_body: bytes,
signature_header: str,
timestamp_header: str,
webhook_secret: str,
tolerance_seconds: int = WEBHOOK_TOLERANCE_SECONDS,
) -> bool:
if not signature_header or not signature_header.startswith(f"{SIGNATURE_VERSION}="):
logger.warning("Webhook signature header missing or invalid prefix")
return False
expected_hex = signature_header[len(SIGNATURE_VERSION) + 1 :]
try:
request_ts = int(timestamp_header)
except (ValueError, TypeError):
logger.warning("Webhook timestamp header invalid: %s", timestamp_header)
return False
current_ts = int(time.time())
if abs(current_ts - request_ts) > tolerance_seconds:
logger.warning(
"Webhook timestamp out of tolerance: request=%s, current=%s, diff=%s",
request_ts,
current_ts,
abs(current_ts - request_ts),
)
return False
message = f"{timestamp_header}.{raw_body.decode('utf-8')}"
computed_hmac = hmac.new(
webhook_secret.encode("utf-8"),
message.encode("utf-8"),
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(computed_hmac, expected_hex)