mirror of
https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools.git
synced 2026-06-18 15:29:36 +00:00
76 lines
2.5 KiB
Python
76 lines
2.5 KiB
Python
"""Meta WhatsApp X-Hub-Signature-256 and webhook safety helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import hmac
|
|
|
|
import pytest
|
|
from httpx import ASGITransport, AsyncClient
|
|
|
|
from api.main import create_app
|
|
from core.config.settings import get_settings
|
|
from integrations.whatsapp import WhatsAppClient
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _reset_settings_cache():
|
|
get_settings.cache_clear()
|
|
yield
|
|
get_settings.cache_clear()
|
|
|
|
|
|
def _meta_sig(body: bytes, app_secret: str) -> str:
|
|
digest = hmac.new(app_secret.encode(), body, hashlib.sha256).hexdigest()
|
|
return f"sha256={digest}"
|
|
|
|
|
|
def test_verify_signature_accepts_valid_header(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.setenv("WHATSAPP_APP_SECRET", "unit-test-secret")
|
|
app_secret = "unit-test-secret"
|
|
body = b'{"entry":[{"changes":[]}]}'
|
|
client = WhatsAppClient()
|
|
sig = _meta_sig(body, app_secret)
|
|
assert client.verify_signature(body, sig) is True
|
|
|
|
|
|
def test_verify_signature_rejects_tampered_body(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.setenv("WHATSAPP_APP_SECRET", "unit-test-secret")
|
|
get_settings.cache_clear()
|
|
client = WhatsAppClient()
|
|
sig = _meta_sig(b"original", "unit-test-secret")
|
|
assert client.verify_signature(b"tampered", sig) is False
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_whatsapp_webhook_rejects_missing_signature_on_staging(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
) -> None:
|
|
monkeypatch.setenv("APP_ENV", "staging")
|
|
monkeypatch.setenv("WHATSAPP_APP_SECRET", "staging-webhook-secret")
|
|
get_settings.cache_clear()
|
|
app = create_app()
|
|
try:
|
|
payload = {"entry": []}
|
|
async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client:
|
|
r = await client.post("/api/v1/webhooks/whatsapp", json=payload)
|
|
assert r.status_code == 403
|
|
assert r.json().get("detail") == "missing_or_invalid_signature"
|
|
finally:
|
|
get_settings.cache_clear()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_whatsapp_meta_send_blocked_when_flag_off(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
monkeypatch.setenv("WHATSAPP_ALLOW_LIVE_SEND", "false")
|
|
monkeypatch.setenv("WHATSAPP_ACCESS_TOKEN", "dummy-token")
|
|
monkeypatch.setenv("WHATSAPP_PHONE_NUMBER_ID", "123456")
|
|
get_settings.cache_clear()
|
|
try:
|
|
client = WhatsAppClient()
|
|
result = await client.send_text("+966500000001", "hello")
|
|
assert result.success is False
|
|
assert result.error == "whatsapp_allow_live_send_false"
|
|
finally:
|
|
get_settings.cache_clear()
|