fix(crypto): validare fail-fast a cheii Fernet la startup

O cheie AUTOPASS_CREDS_KEY setata dar invalida (format Fernet gresit)
arunca ValueError abia la primul encrypt_creds -> 500 brut pe
POST /v1/prezentari, fara mesaj util (cazul reprodus din client VFP).

crypto.validate_creds_key() valideaza cheia, apelata in main.lifespan:
o cheie invalida opreste pornirea cu mesaj clar + comanda de generare,
in loc sa explodeze la prima cerere. Cheie nesetata = OK (model efemer).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-23 13:55:12 +00:00
parent 5dc963a02c
commit 90603609a1
2 changed files with 26 additions and 0 deletions

View File

@@ -39,6 +39,28 @@ def reset_cache() -> None:
_fernet.cache_clear()
def validate_creds_key() -> None:
"""Fail-fast la startup: o cheie `creds_key` setata DAR invalida trebuie sa
opreasca pornirea, nu sa explodeze abia la primul POST /v1/prezentari (500
brut, fara mesaj util pentru client — cazul real reprodus din ROAAUTO/VFP).
Cheie nesetata = OK (modelul efemer, vezi _fernet). Cheie setata si invalida
(lungime/padding gresit) -> RuntimeError cu instructiunea de generare.
"""
key = get_settings().creds_key
if not key:
return
try:
Fernet(key.encode() if isinstance(key, str) else key)
except (ValueError, TypeError) as exc:
raise RuntimeError(
"AUTOPASS_CREDS_KEY este setata dar invalida (Fernet cere 32 bytes "
"url-safe base64, 44 caractere terminate in '='). Genereaza una cu:\n"
" python3 -c \"from cryptography.fernet import Fernet; "
"print(Fernet.generate_key().decode())\""
) from exc
def encrypt_creds(creds: dict) -> str:
"""Cripteaza un dict de creds -> token Fernet (str). Compact, fara spatii."""
blob = json.dumps(creds, separators=(",", ":"), ensure_ascii=False).encode("utf-8")