fix(g2): Session-Revocation bei Passwortaenderung auf beiden Pfaden

Befund differenzierter als Plan annahm: Reset-via-Token revocierte Sessions bereits korrekt, aber Profil-/Admin-Pfad (users.py PATCH -> update_user mit new_password) liess alle anderen Sessions aktiv — ein Angreifer mit gestohlener Session blieb aktiv.

Fix nach DRY: revoke_user_redis_sessions(user_id)-Helper in app/core/auth.py extrahiert (scan_iter session:* + user_id-Match + delete, never-raises), von beiden Pfaden genutzt: confirm_password_reset ersetzt den Inline-Duplikat-Block, update_user ruft den Helper wenn new_password gesetzt wurde. Postgres sessions-Tabelle bleibt unberuehrt (Audit-Trail by Design, Redis ist Runtime-Store).

Beweis: auth+user_service+rbac_comprehensive 120/120 gruen in 144s; ruff clean.
This commit is contained in:
Agent Zero
2026-08-26 00:00:19 +02:00
parent f4a5937a4b
commit 0baec2792c
3 changed files with 43 additions and 18 deletions
+8
View File
@@ -201,6 +201,14 @@ class UserService:
user.password_hash = hash_password(new_password)
await db.flush()
# G2: after a profile/admin password change, kill all other sessions —
# a stolen or lingering session must not survive the change.
if new_password is not None:
from app.core.auth import revoke_user_redis_sessions
await revoke_user_redis_sessions(user.id)
return user, user_tenant
async def delete_user(