- Installierbares Package mit pyproject.toml - Client-Klasse mit Sync, Async (mit Polling), Webhook, Verify, Download - Typisierte Exception-Hierarchie - Webhook-Signatur-Verifikation (HMAC-SHA-256) - Pytest-Suite + Quickstart und Webhook-Receiver-Beispiel
48 lines
1.4 KiB
Python
48 lines
1.4 KiB
Python
"""Webhook-Signatur-Verifikation für hightrusted CAPTURE."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import hmac
|
|
|
|
|
|
def verify_webhook_signature(body: bytes, signature_header: str, secret: str) -> bool:
|
|
"""Prüft die HMAC-SHA-256-Signatur eines eingehenden Webhooks.
|
|
|
|
Der Header `X-Hightrusted-Signature` hat das Format::
|
|
|
|
sha256=<hex>
|
|
|
|
Das Webhook-Secret wird im Dashboard pro API-Key konfiguriert.
|
|
|
|
Args:
|
|
body: Roh-Body des Requests (bytes!), nicht den geparsten JSON.
|
|
signature_header: Wert des Headers `X-Hightrusted-Signature`.
|
|
secret: Dein Webhook-Secret aus dem Dashboard.
|
|
|
|
Returns:
|
|
True wenn Signatur valid, False sonst.
|
|
|
|
Beispiel::
|
|
|
|
from hightrusted_capture import verify_webhook_signature
|
|
|
|
@app.post("/webhooks/capture")
|
|
def webhook(request):
|
|
body = request.body # raw bytes!
|
|
sig = request.headers["X-Hightrusted-Signature"]
|
|
if not verify_webhook_signature(body, sig, "wh_secret_..."):
|
|
return 401
|
|
payload = json.loads(body)
|
|
...
|
|
"""
|
|
if not signature_header or not secret or not body:
|
|
return False
|
|
|
|
expected = "sha256=" + hmac.new(
|
|
secret.encode("utf-8"),
|
|
body,
|
|
hashlib.sha256,
|
|
).hexdigest()
|
|
|
|
return hmac.compare_digest(expected, signature_header)
|