ObsiGate 2.84.0 : API d'administration des comptes machine-à-machine (HUB-13, fusion #127, #226) — routes /api/admin/machine/comptes protégées par DRACO_ADMIN_MACHINE_KEY, révocation des jti draco à la désactivation, must_change_password, journalisation d'audit

This commit is contained in:
Spark
2026-11-06 00:58:16 +00:00
parent b83de53447
commit 65d01f91b8
10 changed files with 983 additions and 5 deletions
+9 -1
View File
@@ -298,6 +298,8 @@ def _issue_tokens(user: dict, username: str, remember_me: bool, response: Respon
"role": user["role"],
"vaults": user["vaults"],
"avatar": user.get("avatar"),
# HUB-13 : mot de passe temporaire — changement forcé signalé.
"must_change_password": bool(user.get("must_change_password")),
},
}
@@ -433,6 +435,8 @@ async def get_me(current_user=Depends(require_auth)):
"language": current_user.get("language", "fr"),
"last_login": current_user.get("last_login"),
"avatar": current_user.get("avatar"),
# HUB-13 : mot de passe temporaire — changement forcé signalé.
"must_change_password": bool(current_user.get("must_change_password")),
}
@@ -487,7 +491,11 @@ async def change_password(
assert user is not None, f"User {current_user['username']} not found"
if not verify_password(req.current_password, user["password_hash"]):
raise HTTPException(400, "Mot de passe actuel incorrect")
update_user(current_user["username"], {"password": req.new_password})
# HUB-13 : le changement effectif efface le marqueur de changement forcé.
update_user(current_user["username"], {
"password": req.new_password,
"must_change_password": False,
})
updated = get_user(current_user["username"])
result: dict = {"message": "Mot de passe mis à jour"}
if updated is not None:
+10 -1
View File
@@ -80,8 +80,16 @@ def create_user(
role: str = "user",
vaults: list[str] | None = None,
display_name: str | None = None,
must_change_password: bool = False,
) -> dict:
"""Create a new user. Raises ValueError if username already taken."""
"""Create a new user. Raises ValueError if username already taken.
``must_change_password`` (HUB-13) marque un mot de passe temporaire
(création/réinitialisation par l'administration machine) : le
changement est forcé à la première connexion. Les comptes créés
avant ce champ n'en portent pas — ils valent ``False`` partout où
le champ est lu via ``.get(..., False)``.
"""
with _users_lock:
data = _read()
if username in data["users"]:
@@ -95,6 +103,7 @@ def create_user(
"role": role,
"vaults": vaults or [],
"active": True,
"must_change_password": bool(must_change_password), # HUB-13
"language": "fr", # default UI language
"avatar": None, # profile picture data-URL (#113)
"created_at": datetime.now(UTC).isoformat(),