3.8 KiB
#227 — HUB-22 : API machine des sessions draco (liste et révocation)
Carte : vague C du plan Hub v2.1 (HUB-22) — le Hub consomme ces
routes en 0.17.0 pour l'écran des sessions d'un utilisateur.
Version : 2.85.0. Prérequis : HUB-13 (#226) — registre des
émissions jti et garde machine.
Objet
Le Hub doit lister les sessions actives d'un utilisateur et les
révoquer une à une ou toutes, via le canal jti livré en HUB-13.
Aucune route machine « sessions » n'existait : cette livraison la crée,
sous la même garde (require_machine_admin, clé
DRACO_ADMIN_MACHINE_KEY, en-têtes X-Draco-Machine-Key /
X-Draco-Actor) et avec la même journalisation d'audit que les routes
comptes existantes. Sans la clé configurée, l'API reste inerte (404) ;
sans clé valide, 401.
Routes — /api/admin/machine/comptes/{username}/sessions
| Méthode | Chemin | Effet |
|---|---|---|
| GET | /api/admin/machine/comptes/{username}/sessions |
Sessions actives du compte |
| POST | /api/admin/machine/comptes/{username}/sessions/{jti}/revoquer |
Révocation d'une session |
| POST | /api/admin/machine/comptes/{username}/sessions/revoquer-toutes |
Révocation de toutes les sessions |
Codes : 401 sans clé machine valide, 404 compte inconnu (ou API non
configurée), 404 jti absent de l'ensemble actif du compte.
Liste — GET …/sessions
200 {"username": …, "sessions": [{"jti", "exp", "expire_le", "revoquee"}]} — une entrée par jti émis et non expiré, triée par
exp croissant ; expire_le est l'échéance en ISO 8601 UTC et
revoquee signale un jti déjà présent dans la liste des
révocations.
Révocation unitaire — POST …/sessions/{jti}/revoquer
200 {"jti", "revoquee": true}. Le jti n'est révoqué que s'il
appartient à l'ensemble émis du compte visé et n'est pas expiré :
404 sinon, jamais de révocation cross-utilisateur.
Tout révoquer — POST …/sessions/revoquer-toutes
200 {"revoquees": n} — réutilise revoke_all_for_user de HUB-13.
C'est la « déconnexion globale », distincte de la désactivation :
le compte reste actif, une nouvelle connexion émet une nouvelle
session.
Backend — backend/draco_session.py
issued_sessions_for_user(sub): sessions actives (exp > maintenant) dusub,[{jti, exp, revoquee}]triées parexpcroissant ; les entrées expirées dusubsont purgées du registre au passage.revoke_one_for_user(sub, jti): révoque via lerevoke()existant uniquement si lejtiappartient à l'ensemble émis de cesubet n'est pas expiré ; retourne un booléen.
La clé du registre est le même sub que celui de HUB-13
(_identifiant_sessions dans comptes_machine.py : id du compte,
à défaut username) — factorisée depuis _revoquer_sessions, qui
l'utilise aussi désormais.
Journalisation
Les deux écritures sont consignées dans data/audit.log via
log_compte_admin : actions session_revoquee (détail : le jti) et
sessions_revoquees (détail : nombre de jti révoqués), acteur =
identité de service X-Draco-Actor. La lecture suit le patron des
lectures existantes (non journalisée).
Tests
tests/test_draco_session.py: liste triée et marquagerevoquee, purge des expirés, révocation unitaire, refus cross-utilisateur, refus d'unjtiexpiré ; le registre des émissions est isolé en fichier temporaire dans la fixture.tests/test_comptes_machine.py(TestSessions) : liste (contenu,expire_leISO 8601 UTC), liste vide, compte inconnu 404, révocation unitaire (succès + effet surverify_token), cross-utilisateur 404 sans effet, tout-révoquer (compte toujours actif, autres comptes intacts, seconde passe à 0), garde (401 sans clé, 404 API non configurée), journalisation.