86 lines
3.8 KiB
Markdown
86 lines
3.8 KiB
Markdown
# #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`) du `sub`, `[{jti, exp, revoquee}]` triées par
|
|
`exp` croissant ; les entrées expirées du `sub` sont purgées du
|
|
registre au passage.
|
|
- `revoke_one_for_user(sub, jti)` : révoque via le `revoke()`
|
|
existant uniquement si le `jti` appartient à l'ensemble émis de ce
|
|
`sub` et 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 marquage `revoquee`,
|
|
purge des expirés, révocation unitaire, refus cross-utilisateur,
|
|
refus d'un `jti` expiré ; le registre des émissions est isolé en
|
|
fichier temporaire dans la fixture.
|
|
- `tests/test_comptes_machine.py` (`TestSessions`) : liste (contenu,
|
|
`expire_le` ISO 8601 UTC), liste vide, compte inconnu 404,
|
|
révocation unitaire (succès + effet sur `verify_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.
|