Files
clinica-veterinaria-formigi…/backend/app/api/booking.py

89 lines
3.4 KiB
Python

from fastapi import APIRouter, HTTPException, Request, status
from app.config import settings
from app.schemas.booking import BookingCaptchaChallenge, BookingRequestCreate, BookingRequestResponse
from app.services.booking_security import (
create_captcha_challenge,
get_client_ip,
is_rate_limited,
new_request_id,
verify_captcha,
write_booking_audit_event,
)
from app.services.mailer import MailConfigurationError, send_booking_request_email
router = APIRouter(prefix="/api", tags=["booking"])
@router.get("/booking-captcha", response_model=BookingCaptchaChallenge)
def get_booking_captcha() -> BookingCaptchaChallenge:
return create_captcha_challenge()
@router.post("/booking-request", response_model=BookingRequestResponse)
def create_booking_request(request: Request, payload: BookingRequestCreate) -> BookingRequestResponse:
request_id = new_request_id()
write_booking_audit_event("received", request_id=request_id, request=request, payload=payload)
if not settings.booking_form_enabled:
write_booking_audit_event("blocked_form_disabled", request_id=request_id, request=request, payload=payload)
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Form in aggiornamento.",
)
if payload.website:
write_booking_audit_event("blocked_honeypot", request_id=request_id, request=request, payload=payload)
return BookingRequestResponse(
message="La richiesta è stata inviata correttamente e sarà presa in carico al più presto dal team.",
)
client_ip = get_client_ip(request)
if is_rate_limited(client_ip):
write_booking_audit_event("blocked_rate_limit", request_id=request_id, request=request, payload=payload)
raise HTTPException(
status_code=status.HTTP_429_TOO_MANY_REQUESTS,
detail="Sono state inviate troppe richieste. Riprova più tardi.",
)
if not verify_captcha(payload.captcha_id, payload.captcha_answer):
write_booking_audit_event("blocked_captcha", request_id=request_id, request=request, payload=payload)
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Verifica anti-spam non valida. Ricarica il codice e riprova.",
)
try:
send_booking_request_email(payload)
except MailConfigurationError as exc:
write_booking_audit_event(
"failed_configuration",
request_id=request_id,
request=request,
payload=payload,
error=exc,
)
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Il servizio email non è ancora configurato.",
) from exc
except Exception as exc: # pragma: no cover - mail delivery path
write_booking_audit_event(
"failed_delivery",
request_id=request_id,
request=request,
payload=payload,
error=exc,
)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Si è verificato un problema durante l'invio della richiesta.",
) from exc
write_booking_audit_event("sent", request_id=request_id, request=request, payload=payload)
return BookingRequestResponse(
message="La richiesta è stata inviata correttamente e sarà presa in carico al più presto dal team.",
)