62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
import hashlib
|
|
import hmac
|
|
import time
|
|
|
|
import pytest
|
|
|
|
from gaiia import WebhookSignatureError, verify_webhook_signature
|
|
|
|
|
|
def _make_header(secret: str, timestamp: int, body: bytes) -> str:
|
|
sig = hmac.new(
|
|
secret.encode(), f"{timestamp}.{body.decode()}".encode(), hashlib.sha256
|
|
).hexdigest()
|
|
return f"t={timestamp},v1={sig}"
|
|
|
|
|
|
def test_valid_signature_passes():
|
|
secret = "whsec_test"
|
|
body = b'{"hello":"world"}'
|
|
ts = int(time.time())
|
|
header = _make_header(secret, ts, body)
|
|
verify_webhook_signature(header_value=header, raw_body=body, secret=secret)
|
|
|
|
|
|
def test_tampered_body_fails():
|
|
secret = "whsec_test"
|
|
body = b'{"hello":"world"}'
|
|
ts = int(time.time())
|
|
header = _make_header(secret, ts, body)
|
|
with pytest.raises(WebhookSignatureError):
|
|
verify_webhook_signature(
|
|
header_value=header, raw_body=b'{"hello":"WORLD"}', secret=secret
|
|
)
|
|
|
|
|
|
def test_old_timestamp_rejected():
|
|
secret = "whsec_test"
|
|
body = b'{"x":1}'
|
|
ts = int(time.time()) - 3600
|
|
header = _make_header(secret, ts, body)
|
|
with pytest.raises(WebhookSignatureError):
|
|
verify_webhook_signature(
|
|
header_value=header, raw_body=body, secret=secret, tolerance_seconds=60
|
|
)
|
|
|
|
|
|
def test_multiple_signatures_one_match():
|
|
secret = "whsec_test"
|
|
body = b"abc"
|
|
ts = int(time.time())
|
|
real = _make_header(secret, ts, body).split("v1=")[1]
|
|
header = f"t={ts},v1=ffffffff,v1={real}"
|
|
verify_webhook_signature(header_value=header, raw_body=body, secret=secret)
|
|
|
|
|
|
def test_missing_components():
|
|
with pytest.raises(WebhookSignatureError):
|
|
verify_webhook_signature(header_value="", raw_body=b"", secret="x")
|
|
with pytest.raises(WebhookSignatureError):
|
|
verify_webhook_signature(header_value="v1=abc", raw_body=b"", secret="x")
|
|
with pytest.raises(WebhookSignatureError):
|
|
verify_webhook_signature(header_value="t=123", raw_body=b"", secret="x")
|