"""Teste task #8: csrf_token prezent in TOATE raspunsurile de formular (inclusiv ramuri eroare). Lockout real in prod (web_auth_required=True, sesiune logata): eroare la confirma/upload re-randeaza template FARA csrf_token in context → campul {{ csrf_token }} devine gol → urmatorul submit trimite token gol → CsrfError 403. TDD: RED pe codul actual (token gol in eroare), GREEN dupa fix. """ from __future__ import annotations import os import re import tempfile import pytest from fastapi.testclient import TestClient def _extract_csrf(html: str) -> str: m = re.search(r'name="csrf_token" value="([^"]*)"', html) return m.group(1) if m else "" @pytest.fixture() def prod_client(monkeypatch): """Client cu web_auth_required=True + require_login monkeypatched.""" tmp = tempfile.mkdtemp() monkeypatch.setenv("AUTOPASS_DB_PATH", os.path.join(tmp, "csrf_err.db")) monkeypatch.setenv("AUTOPASS_WEB_AUTH_REQUIRED", "true") from app.config import get_settings get_settings.cache_clear() from app.main import app with TestClient(app, follow_redirects=False) as c: from app.db import get_connection from app.accounts import create_account conn = get_connection() acct = create_account(conn, "Cont Test CSRF Erori") monkeypatch.setattr("app.web.routes.require_login", lambda r: acct) yield c, conn, acct conn.close() get_settings.cache_clear() def test_confirma_batch_inexistent_contine_csrf(prod_client): """POST confirma cu batch inexistent re-randeaza _upload.html cu csrf_token negol. Flux: 1. GET / -> initializeaza csrf_token in sesiune, extragem token 2. POST /_import/99999/confirma cu token valid -> batch nu exista -> _upload.html 3. Verificam ca _upload.html din eroare contine csrf_token negol 4. POST cu tokenul din eroare -> NU 403 """ client, conn, acct = prod_client # 1. GET dashboard: initializeaza CSRF token in sesiune r_get = client.get("/") assert r_get.status_code == 200 csrf = _extract_csrf(r_get.text) assert csrf, "Dashboard nu a returnat csrf_token — problema de setup" # 2. POST confirma cu batch inexistent (ID 99999 cu siguranta nu exista) r_err = client.post( "/_import/99999/confirma", data={"n_confirmat": "1", "csrf_token": csrf}, ) assert r_err.status_code == 200 assert "inexistent" in r_err.text.lower() or "expirat" in r_err.text.lower() # 3. csrf_token in raspunsul de eroare (_upload.html) trebuie sa fie NEGOL csrf_in_error = _extract_csrf(r_err.text) assert csrf_in_error, "csrf_token gol in _upload.html de eroare — lockout garantat in prod!" # 4. Urmatorul POST cu token din eroare -> NU 403 r_retry = client.post( "/_import/99999/confirma", data={"n_confirmat": "1", "csrf_token": csrf_in_error}, ) assert r_retry.status_code != 403, f"CsrfError 403 dupa eroare — lockout confirmat! Status: {r_retry.status_code}" assert r_retry.status_code == 200