Initial commit
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
"""Webhook configuration CRUD + test notification."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from typing import List
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.database import get_db
|
||||
from app.models.webhook_config import WebhookConfig
|
||||
from app.schemas.webhook import WebhookCreate, WebhookUpdate, WebhookResponse
|
||||
from app.services.webhook_service import send_test_notification
|
||||
from app.utils.auth import get_current_user
|
||||
|
||||
router = APIRouter(prefix="/api/webhooks", tags=["webhooks"])
|
||||
|
||||
MASK = "***"
|
||||
|
||||
|
||||
def _to_response(w: WebhookConfig) -> WebhookResponse:
|
||||
return WebhookResponse(
|
||||
id=w.id,
|
||||
name=w.name,
|
||||
type=w.type,
|
||||
url=w.url,
|
||||
secret_masked=MASK if w.secret else "",
|
||||
enabled=w.enabled,
|
||||
events=json.loads(w.events_json or "[]"),
|
||||
created_at=w.created_at,
|
||||
updated_at=w.updated_at,
|
||||
)
|
||||
|
||||
|
||||
@router.get("", response_model=List[WebhookResponse])
|
||||
def list_webhooks(db: Session = Depends(get_db), _=Depends(get_current_user)):
|
||||
return [_to_response(w) for w in db.query(WebhookConfig).order_by(WebhookConfig.id).all()]
|
||||
|
||||
|
||||
@router.post("", response_model=WebhookResponse, status_code=201)
|
||||
def create_webhook(
|
||||
body: WebhookCreate,
|
||||
db: Session = Depends(get_db),
|
||||
_=Depends(get_current_user),
|
||||
):
|
||||
w = WebhookConfig(
|
||||
name=body.name,
|
||||
type=body.type,
|
||||
url=body.url,
|
||||
secret=body.secret,
|
||||
enabled=body.enabled,
|
||||
events_json=json.dumps(body.events, ensure_ascii=False),
|
||||
)
|
||||
db.add(w)
|
||||
db.commit()
|
||||
db.refresh(w)
|
||||
return _to_response(w)
|
||||
|
||||
|
||||
@router.get("/{wid}", response_model=WebhookResponse)
|
||||
def get_webhook(wid: int, db: Session = Depends(get_db), _=Depends(get_current_user)):
|
||||
w = db.query(WebhookConfig).filter(WebhookConfig.id == wid).first()
|
||||
if not w:
|
||||
raise HTTPException(404, "webhook not found")
|
||||
return _to_response(w)
|
||||
|
||||
|
||||
@router.put("/{wid}", response_model=WebhookResponse)
|
||||
def update_webhook(
|
||||
wid: int,
|
||||
body: WebhookUpdate,
|
||||
db: Session = Depends(get_db),
|
||||
_=Depends(get_current_user),
|
||||
):
|
||||
w = db.query(WebhookConfig).filter(WebhookConfig.id == wid).first()
|
||||
if not w:
|
||||
raise HTTPException(404, "webhook not found")
|
||||
data = body.model_dump(exclude_none=True)
|
||||
if "events" in data:
|
||||
w.events_json = json.dumps(data.pop("events"), ensure_ascii=False)
|
||||
if "secret" in data:
|
||||
if data["secret"] != MASK: # only update if not mask placeholder
|
||||
w.secret = data.pop("secret")
|
||||
else:
|
||||
data.pop("secret")
|
||||
for k, v in data.items():
|
||||
setattr(w, k, v)
|
||||
w.updated_at = datetime.now(timezone.utc)
|
||||
db.commit()
|
||||
db.refresh(w)
|
||||
return _to_response(w)
|
||||
|
||||
|
||||
@router.delete("/{wid}", status_code=204)
|
||||
def delete_webhook(wid: int, db: Session = Depends(get_db), _=Depends(get_current_user)):
|
||||
w = db.query(WebhookConfig).filter(WebhookConfig.id == wid).first()
|
||||
if not w:
|
||||
raise HTTPException(404, "webhook not found")
|
||||
db.delete(w)
|
||||
db.commit()
|
||||
|
||||
|
||||
@router.post("/{wid}/test")
|
||||
def test_webhook(wid: int, db: Session = Depends(get_db), _=Depends(get_current_user)):
|
||||
w = db.query(WebhookConfig).filter(WebhookConfig.id == wid).first()
|
||||
if not w:
|
||||
raise HTTPException(404, "webhook not found")
|
||||
ok, msg = send_test_notification(db, w)
|
||||
return {"success": ok, "message": msg}
|
||||
Reference in New Issue
Block a user