Coffre : endpoint GET /api/coffres/distribuables pour un consommateur (issue #43)

This commit is contained in:
2026-10-28 13:48:46 -04:00
parent b9db438034
commit 8c40aba850
+45
View File
@@ -57,6 +57,7 @@ from backend.coffre_store import (
SecretExpireError,
ValidationError,
compter_octrois_actifs,
est_expire,
compter_secrets,
create_coffre,
create_consommateur,
@@ -495,6 +496,50 @@ async def api_distribuer(request: Request, body: dict = Body(...)):
}
@router.get("/api/coffres/distribuables")
async def api_distribuables(request: Request):
"""Secrets distribuables pour un consommateur (issue #43).
Authentification par jeton consommateur (la même que
/distribuer), jamais par session utilisateur : c'est le
serveur agent qui appelle, pour alimenter la liste déroulante
de ses fournisseurs LLM. Retour = métadonnées seules des
secrets pour lesquels ce consommateur a un octroi ACTIF
(coffre actif, secret non expiré, octroi ni révoqué ni
expiré, y compris les octrois coffre-wide). Un consommateur
sans octroi reçoit une liste vide — jamais d'erreur
révélatrice, jamais de valeur.
"""
_exiger_actives()
auth = request.headers.get("Authorization", "")
jeton = auth[7:] if auth.startswith("Bearer ") else ""
consommateur = verifier_jeton_consommateur(jeton)
if consommateur is None:
raise HTTPException(status_code=401,
detail="consommateur_invalide")
if consommateur["statut"] != "actif":
raise HTTPException(status_code=403,
detail="consommateur_revoque")
sortie = []
for coffre in list_coffres():
if coffre["statut"] != "actif":
continue
for secret in list_secrets(coffre["id"]):
if est_expire(secret.get("expiration")):
continue
statut, _octroi = statut_octroi_consommateur(
consommateur["id"], coffre["id"], secret["id"])
if statut != "ok":
continue
sortie.append({
"reference": f"coffre:{coffre['slug']}/{secret['nom']}",
"coffre": coffre["slug"],
"nom": secret["nom"],
"version": secret["version_courante"],
})
return sortie
# ---------------------------------------------------------------------------
# Un coffre, ses secrets, ses octrois, son journal
# ---------------------------------------------------------------------------