fix(auth): SECRET_KEY di default rifiutato, session.permanent, logout solo POST (#33)

config.py: guard_default_secret_key, verificata a ogni richiesta (prima di
create_app, TESTING/DEBUG non sono ancora impostati dai fixture di test) —
rifiuta con RuntimeError se CLIENT_SECRET_KEY è rimasto al default committato
fuori da debug/testing. auth.py: session.permanent=True al login (senza,
PERMANENT_SESSION_LIFETIME non aveva mai effetto); /auth/logout solo POST,
con CSRF. Aggiornati i tre punti che lo chiamavano: profile.html e
navbar.html (link -> form POST), auto-logout JS in base.html (fetch POST +
redirect al login).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-21 22:37:23 +02:00
parent e8a8aeed66
commit 92f130479a
8 changed files with 151 additions and 19 deletions
+10 -2
View File
@@ -54,6 +54,9 @@ class TestLoginPost:
with client.session_transaction() as sess:
assert sess.get("api_key") == "new-api-key-abc"
assert sess["user"]["username"] == "testuser"
# #33: without this, PERMANENT_SESSION_LIFETIME (8h) never applied
# and Flask used a browser-length session instead.
assert sess.permanent is True
def test_login_post_error_shows_error(self, client, mock_api_client):
"""Failed login returns the login page with error flash."""
@@ -83,13 +86,13 @@ class TestLoginPost:
class TestLogout:
"""GET/POST /auth/logout tests."""
"""POST /auth/logout tests (#33: GET is refused - logout must carry CSRF)."""
def test_logout_clears_session(self, logged_in_client, mock_api_client):
"""Logout clears session and redirects to login."""
mock_api_client.post.return_value = {}
resp = logged_in_client.get("/auth/logout", follow_redirects=False)
resp = logged_in_client.post("/auth/logout", follow_redirects=False)
assert resp.status_code == 302
assert "/auth/login" in resp.headers["Location"]
@@ -98,6 +101,11 @@ class TestLogout:
assert "api_key" not in sess
assert "user" not in sess
def test_logout_get_is_rejected(self, logged_in_client):
"""#33: a bare GET (link, prefetch, forged <img>) no longer logs anyone out."""
resp = logged_in_client.get("/auth/logout", follow_redirects=False)
assert resp.status_code == 405
class TestUnauthenticatedRedirect:
"""Protected routes redirect unauthenticated users."""