import hmac import time def _algorithm() -> str: from infrasynth.shared.settings_utils import get_setting return str(get_setting("INFRASYNTH_WEBHOOKS", "SIGNATURE_ALGORITHM", "sha256")) def sign_payload(secret: str, payload: str, timestamp: int | None = None) -> str: ts = timestamp or int(time.time()) message = f"{ts}.{payload}".encode() digest = hmac.new(secret.encode(), message, _algorithm()).hexdigest() return f"t={ts},v1={digest}" def verify_signature(secret: str, payload: str, signature_header: str, tolerance_seconds: int = 300) -> bool: try: parts = signature_header.split(",") ts_part = parts[0] sig_part = parts[1] ts = int(ts_part.split("=")[1]) sig = sig_part.split("=")[1] except (IndexError, ValueError, AttributeError): return False now = int(time.time()) if abs(now - ts) > tolerance_seconds: return False expected = sign_payload(secret, payload, timestamp=ts) expected_sig = expected.split(",")[1].split("=")[1] return hmac.compare_digest(sig, expected_sig)