"""Vérification hCaptcha du formulaire public d'inscription. Point d'injection unique : `_verify_with_hcaptcha` (remplacé dans les tests, même principe que `app.email.sender.deliver_many`). Sans `HCAPTCHA_SECRET_KEY` configurée (dev/tests), la vérification est désactivée — voir `app/config.py:Settings.hcaptcha_secret_key`. """ import logging import httpx from app.config import get_settings logger = logging.getLogger("app.forms") _VERIFY_URL = "https://hcaptcha.com/siteverify" _TIMEOUT_SECONDS = 8.0 def _verify_with_hcaptcha(token: str, secret: str) -> bool: """Appel réel à l'API hCaptcha. Toute erreur réseau/serveur est traitée comme un échec de vérification (on ne laisse jamais passer par défaut).""" try: resp = httpx.post( _VERIFY_URL, data={"secret": secret, "response": token}, timeout=_TIMEOUT_SECONDS, ) resp.raise_for_status() return bool(resp.json().get("success")) except httpx.HTTPError as exc: logger.warning("Échec de la vérification hCaptcha : %s", exc.__class__.__name__) return False def verify_hcaptcha(token: str | None) -> bool: """`False` si `token` est vide, ou si la vérification hCaptcha échoue. Toujours `True` quand `HCAPTCHA_SECRET_KEY` n'est pas configurée (dev, tests) — voir l'avertissement au démarrage dans `app/main.py`.""" secret = get_settings().hcaptcha_secret_key if not secret: return True if not token: return False return _verify_with_hcaptcha(token, secret)