import hashlib
import hmac
import json
import os
from fastapi import FastAPI, HTTPException, Request
app = FastAPI()
webhook_secret = os.getenv("EMERGE_WEBHOOK_SECRET")
if not webhook_secret:
raise RuntimeError("Missing EMERGE_WEBHOOK_SECRET")
@app.post("/webhooks/emerge")
async def handle_webhook(request: Request):
body = await request.body()
signature = request.headers.get("x-signature")
if not signature:
raise HTTPException(status_code=401, detail="Missing signature")
expected = hmac.new(
webhook_secret.encode(),
body,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
raise HTTPException(status_code=401, detail="Invalid signature")
payload = json.loads(body)
if payload.get("event") == "consent.revoked":
uid = payload.get("uid")
sources = payload.get("sources", [])
await revoke_user_access(uid, sources)
return {"status": "ok"}
async def revoke_user_access(uid: str, sources: list[dict]):
for source in sources:
provider = source.get("provider", "unknown")
await delete_provider_data(uid, provider)
async def delete_provider_data(uid: str, provider: str):
print(f"Deleting {provider} data for {uid}")