feat: HUB-19 — rôles du Hub consommés par ObsiGate (registre D3(a)) #228
CI / lint (pull_request) Successful in 1m20s
CI / security (pull_request) Successful in 16s
CI / test (pull_request) Successful in 3m55s
CI / build (pull_request) Successful in 11s
CI / e2e (pull_request) Failing after 15m26s

This commit is contained in:
Spark
2026-11-06 16:15:43 +00:00
parent 5127510509
commit c1d69af69d
15 changed files with 621 additions and 19 deletions
+33
View File
@@ -25,6 +25,17 @@
# l'expiration) pour que l'administration des comptes puisse révoquer
# toutes les sessions draco d'un utilisateur (désactivation,
# suppression, réinitialisation du mot de passe) via revoke().
#
# Rôles du Hub (HUB-19, #228) : à l'ouverture de session draco,
# `user_for_draco` consulte en plus le registre des rôles du Hub
# (`backend/hub_roles.py`, contrat D3(a) posé par le pilote ShaarIt) :
# niveau connu ``aucun`` → la session draco est refusée (l'authenti-
# fication native d'ObsiGate, émettrice, n'est jamais touchée) ;
# niveau connu → il est joint au dict utilisateur (``_hub_role``)
# pour que les routes d'administration du canal draco exigent
# ``administrateur`` ; rôle inconnu (Hub injoignable) → comportement
# actuel, aucun verrouillage nouveau. Aucun rôle dans le jeton :
# validation locale, émission et révocations sont inchangées.
from __future__ import annotations
@@ -284,6 +295,28 @@ def user_for_draco(request) -> dict | None:
user["_token_vaults"] = candidate.get("vaults", [])
user["_token_scope"] = "full"
user["_draco_sub"] = sub
# HUB-19 (#228) : rôle du registre du Hub pour ce porteur.
# Niveau connu « aucun » → pas de session établie par draco :
# le refus est consigné sur la requête pour que `require_auth`
# réponde un message explicite en français (et non un simple
# 401 générique). Rôle connu → joint au dict (`_hub_role`) ;
# rôle inconnu → `_hub_role` vaut None et le comportement
# actuel s'applique, sans verrouillage nouveau.
from backend import hub_roles
cookie = ""
try:
cookie = request.headers.get("cookie", "") or ""
except Exception: # un objet requête minimal (tests) ne casse rien
cookie = ""
role = hub_roles.role_pour(sub, cookie)
if role == "aucun":
try:
request.state.role_hub_refuse = "aucun"
except Exception: # pas d'état mutable : refus quand même
pass
return None
user["_hub_role"] = role
return user
return None