API key unica per utente: un secondo login butta fuori la prima postazione, e il frontend non gestisce il 401 #25

Closed
opened 2026-09-21 20:14:48 +00:00 by Adriano · 3 comments
Owner

GRAVITÀ: media
FILE: src/backend/services/auth_service.py:68-85 ; src/backend/models/orm/user.py:35 ; src/backend/api/routers/users.py:96-110 ; src/frontend/flask_app/services/api_client.py:42-81 ; src/frontend/flask_app/blueprints/auth.py:12-20, 66-67
COSA: ogni login rigenera la key, il logout la azzera: lo stesso utente su 2 delle 20 postazioni invalida la prima, che resta «loggata» per Flask ma non salva più. Key in chiaro nel DB, senza scadenza. PUT /api/users/{id}/password non azzera la key (setup.py:634 sì). authenticate_user salta bcrypt se l'utente non esiste (enumerazione per tempi).
VERIFICATO: grep -rn 401 blueprints services app.py → nessuna gestione; auth_service.py:68-85 letto.

ORIGINE: revisione fable del 21/09/2026 su ramo V3.0.0, commit 8cc5e82. Documento completo: _output/2026-09-21-TieMeasureFlow-revisione.md su Wasabi.

GRAVITÀ: media FILE: src/backend/services/auth_service.py:68-85 ; src/backend/models/orm/user.py:35 ; src/backend/api/routers/users.py:96-110 ; src/frontend/flask_app/services/api_client.py:42-81 ; src/frontend/flask_app/blueprints/auth.py:12-20, 66-67 COSA: ogni login rigenera la key, il logout la azzera: lo stesso utente su 2 delle 20 postazioni invalida la prima, che resta «loggata» per Flask ma non salva più. Key in chiaro nel DB, senza scadenza. `PUT /api/users/{id}/password` non azzera la key (setup.py:634 sì). `authenticate_user` salta bcrypt se l'utente non esiste (enumerazione per tempi). VERIFICATO: `grep -rn 401 blueprints services app.py` → nessuna gestione; auth_service.py:68-85 letto. ORIGINE: revisione fable del 21/09/2026 su ramo `V3.0.0`, commit 8cc5e82. Documento completo: `_output/2026-09-21-TieMeasureFlow-revisione.md` su Wasabi.
Adriano added the bug label 2026-09-21 20:14:48 +00:00
Adriano added the assegnata:jeeg label 2026-09-21 20:23:05 +00:00
Author
Owner

⚡ jeeg — preso in carico 2026-09-21T20:23:05Z
ramo: lavoro/jeeg · capacità: docker, gpu, systemd

⚡ jeeg — **preso in carico** 2026-09-21T20:23:05Z ramo: `lavoro/jeeg` · capacità: docker, gpu, systemd
Author
Owner

ANALISI (passo 1) — ramo lavoro/jeeg, worktree ~/lavoro/TieMeasureFlow su jeeg, lotto A2+B2

MODIFICHE backend (A2): src/backend/services/auth_service.py — (a) login_user: se l'utente ha già una api_key valida la RIUSA invece di rigenerarla (più postazioni con lo stesso utente convivono); logout_user non azzera la key condivisa: nuova colonna non serve — il logout lato backend diventa no-op sulla key, a meno del parametro all_sessions=true che la azzera. (b) authenticate_user: se l'utente non esiste esegui comunque un bcrypt su hash fittizio (tempo costante). (c) src/backend/api/routers/users.py PUT /api/users/{id}/password: azzera api_key come fa setup.py:634.
NON si introduce hashing/scadenza della key in questa issue: annotalo come MANCA nel rapporto.
MODIFICHE frontend (B2): src/frontend/flask_app/services/api_client.py — su 401 dal backend: svuota la sessione Flask e segnala {"error": True, "status_code": 401, "session_expired": True}; le route HTML reindirizzano al login con flash «sessione scaduta», le route JSON rispondono 401 con {"session_expired": true}. Realizzalo in un punto solo (api_client + un errorhandler/after_request in app.py), non route per route.
TEST: backend: due login dello stesso utente → stessa key, entrambe valide; cambio password → key azzerata. frontend: backend finto che risponde 401 → sessione svuotata e 401/redirect.

ANALISI (passo 1) — ramo `lavoro/jeeg`, worktree `~/lavoro/TieMeasureFlow` su jeeg, lotto A2+B2 MODIFICHE backend (A2): src/backend/services/auth_service.py — (a) `login_user`: se l'utente ha già una `api_key` valida la RIUSA invece di rigenerarla (più postazioni con lo stesso utente convivono); `logout_user` non azzera la key condivisa: nuova colonna non serve — il logout lato backend diventa no-op sulla key, a meno del parametro `all_sessions=true` che la azzera. (b) `authenticate_user`: se l'utente non esiste esegui comunque un bcrypt su hash fittizio (tempo costante). (c) src/backend/api/routers/users.py `PUT /api/users/{id}/password`: azzera `api_key` come fa setup.py:634. NON si introduce hashing/scadenza della key in questa issue: annotalo come MANCA nel rapporto. MODIFICHE frontend (B2): src/frontend/flask_app/services/api_client.py — su 401 dal backend: svuota la sessione Flask e segnala `{"error": True, "status_code": 401, "session_expired": True}`; le route HTML reindirizzano al login con flash «sessione scaduta», le route JSON rispondono 401 con `{"session_expired": true}`. Realizzalo in un punto solo (api_client + un `errorhandler`/after_request in app.py), non route per route. TEST: backend: due login dello stesso utente → stessa key, entrambe valide; cambio password → key azzerata. frontend: backend finto che risponde 401 → sessione svuotata e 401/redirect.
Author
Owner

Soluzione

ESITO: fatto
COSA: Il login riusa la api_key esistente (più postazioni convivono), il logout non la azzera salvo all_sessions, il cambio password la azzera, bcrypt a tempo costante per utente ignoto. Frontend: su 401 sessione svuotata, redirect o JSON session_expired. Hashing e scadenza della key: issue nuova.
COMMIT (ramo lavoro/jeeg, unito su V3.0.0 a d483fa1): ac76c0a; 1fee293
PROVA: uv run --extra server --extra client --extra dev pytest -q → 622 passed, 4 skipped (erano 391); visione su Python 3.13 → 16 passed (erano 8).

**Soluzione** ESITO: fatto COSA: Il login riusa la api_key esistente (più postazioni convivono), il logout non la azzera salvo `all_sessions`, il cambio password la azzera, bcrypt a tempo costante per utente ignoto. Frontend: su 401 sessione svuotata, redirect o JSON `session_expired`. Hashing e scadenza della key: issue nuova. COMMIT (ramo lavoro/jeeg, unito su V3.0.0 a d483fa1): ac76c0a; 1fee293 PROVA: `uv run --extra server --extra client --extra dev pytest -q` → 622 passed, 4 skipped (erano 391); visione su Python 3.13 → 16 passed (erano 8).
Adriano removed the assegnata:jeeg label 2026-09-21 21:56:30 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Adriano/TieMeasureFlow#25