File size: 1,535 Bytes
df5b35d
 
 
 
 
 
 
 
 
 
 
 
 
 
c32691c
df5b35d
c32691c
 
 
 
 
 
 
df5b35d
c32691c
df5b35d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
"""Sécurité minimale de l'API : clé API sur l'en-tête X-API-Key.

Volontairement simple (pas d'OAuth) car ce projet est une démo/portfolio
déployée sur un Space Hugging Face public ; adapter selon le contexte réel
(JWT, SSO, etc.) avant tout usage en production avec des données sensibles.
"""
from __future__ import annotations

from fastapi import Header, HTTPException, status

from app.core.config import get_settings


async def verify_api_key(x_api_key: str | None = Header(default=None)) -> None:
    """Sur Space public, la clé est optionnelle sauf si explicitement requise."""
    settings = get_settings()
    key = (settings.app_api_key or "").strip()
    # Démo publique : pas de clé, ou valeur placeholder → accès libre.
    if (
        not key
        or key in {"change-me-please", "disabled", "none", "public"}
        or not settings.require_api_key
    ):
        return
    if x_api_key != key:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Clé API invalide ou manquante (en-tête X-API-Key).",
        )


MAX_QUESTION_LENGTH = 1000


def sanitize_question(question: str) -> str:
    question = question.strip()
    if not question:
        raise HTTPException(status_code=422, detail="La question ne peut pas être vide.")
    if len(question) > MAX_QUESTION_LENGTH:
        raise HTTPException(
            status_code=422,
            detail=f"Question trop longue (max {MAX_QUESTION_LENGTH} caractères).",
        )
    return question