55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
"""Webhook CRUD endpoints (ROADMAP #85, tranche 2).
|
|
|
|
Handlers déplacés depuis :mod:`backend.main` sans changement de
|
|
comportement : mêmes chemins (``/api/webhooks``), même modèle de réponse
|
|
(:class:`backend.schemas.WebhookModel`), même dépendance admin. La logique
|
|
métier vit déjà dans :mod:`backend.webhooks` (validation d'URL anti-SSRF,
|
|
store ``webhook_secrets.json`` — BUG-026).
|
|
"""
|
|
|
|
from fastapi import APIRouter, Body, Depends, HTTPException
|
|
|
|
from backend.auth.middleware import require_admin
|
|
from backend.schemas import StatusResponse, WebhookModel
|
|
from backend.webhooks import (
|
|
create_webhook,
|
|
delete_webhook,
|
|
get_webhooks,
|
|
update_webhook,
|
|
)
|
|
|
|
router = APIRouter(prefix="/api/webhooks", tags=["webhooks"])
|
|
|
|
|
|
@router.get("", response_model=list[WebhookModel])
|
|
async def api_webhooks_list(current_user=Depends(require_admin)):
|
|
return get_webhooks()
|
|
|
|
|
|
@router.post("", response_model=WebhookModel)
|
|
async def api_webhooks_create(body: dict = Body(...), current_user=Depends(require_admin)):
|
|
name = body.get("name", "Unnamed")
|
|
url = body.get("url", "")
|
|
events = body.get("events", [])
|
|
secret = body.get("secret")
|
|
if not url:
|
|
raise HTTPException(400, "URL is required")
|
|
return create_webhook(name, url, events, secret)
|
|
|
|
|
|
@router.patch("/{webhook_id}", response_model=WebhookModel)
|
|
async def api_webhooks_update(
|
|
webhook_id: str, body: dict = Body(...), current_user=Depends(require_admin)
|
|
):
|
|
result = update_webhook(webhook_id, body)
|
|
if not result:
|
|
raise HTTPException(404, "Webhook not found")
|
|
return result
|
|
|
|
|
|
@router.delete("/{webhook_id}", response_model=StatusResponse)
|
|
async def api_webhooks_delete(webhook_id: str, current_user=Depends(require_admin)):
|
|
if not delete_webhook(webhook_id):
|
|
raise HTTPException(404, "Webhook not found")
|
|
return {"status": "deleted"}
|