fix: A3–A8 — bloc « fallback admin » de l'audit sécurité (401 sans session, ACL, CSRF)
- A3 : helper `_require_user_id()` (401 sans session) sur profile/password/token/forge ; `PUT /api/user/password` exige `current_password` vérifié ; `/api/user` sorti de la liste CSRF exemptée - A4 : `POST /api/v1/token` → 401 sans session, chemin legacy `user_id=0` supprimé - A5 : CRUD membres d'espace (POST/PUT/DELETE) : session + rôle admin de l'espace (ou admin global), placeholder user créé en `is_admin=0`, GET membres sans session → 401 - A6 : `_require_view` → 404 et `_require_edit` → 401 quand il n'y a pas de session (fin du legacy single-user sur les collections) - A7 : création ET lecture de page → 401 sans session (PermissionManager conservé) ; `/board/api/pages` sorti de `EXCLUDED_PATHS` ; header CSRF manquant ajouté sur setItemIcon (local_workspace) - A8 : seed admin sans mot de passe codé en dur — aléatoire au premier boot loggé une fois, ou `FLOWDECK_ADMIN_PASSWORD` ; re-seed seulement si absent - tests : client connecté par défaut via `_TestSessionAuth` (session + CSRF injectés à la volée, jamais dans le cookie jar → plus de CookieConflict), helper `anon()` sur les 40 tests d'anonymat ; 1016/1016 verts, `ruff check app tests` OK
This commit is contained in:
@@ -8,6 +8,7 @@ import asyncio
|
||||
import os
|
||||
|
||||
import pytest
|
||||
from conftest import anon
|
||||
from fastapi import HTTPException
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
@@ -66,6 +67,7 @@ def test_api_token_lifecycle(client):
|
||||
|
||||
|
||||
def test_api_tokens_require_authentication(client):
|
||||
anon(client)
|
||||
r1 = client.get("/api/settings/tokens")
|
||||
assert r1.status_code == 401
|
||||
r2 = client.post("/api/settings/tokens", json={"name": "x"})
|
||||
@@ -88,7 +90,11 @@ def test_sessions_listed_and_revocable(client):
|
||||
|
||||
from app.db import get_conn
|
||||
with get_conn() as conn:
|
||||
count = conn.execute("SELECT COUNT(*) FROM user_sessions").fetchone()[0]
|
||||
count = conn.execute(
|
||||
"SELECT COUNT(*) FROM user_sessions WHERE user_id IN "
|
||||
"(SELECT id FROM users WHERE login IN (?, ?))",
|
||||
("[email protected]", "[email protected]"),
|
||||
).fetchone()[0]
|
||||
assert count == 2
|
||||
|
||||
# Revoke alice's session using alice's cookie (the test client now has bob's cookie).
|
||||
@@ -192,6 +198,7 @@ def test_backup_disabled_returns_none(client):
|
||||
|
||||
|
||||
def test_backup_admin_api(client):
|
||||
anon(client)
|
||||
"""The backup admin API is admin-only and snapshots on demand."""
|
||||
# Unauthenticated → forbidden.
|
||||
assert client.post("/api/settings/backups/run").status_code == 403
|
||||
|
||||
Reference in New Issue
Block a user