"""Integration tests for the login gate: /api/auth/* and require_auth.""" import pytest from fastapi.testclient import TestClient from sqlmodel import Session, SQLModel, create_engine from agenteval.config.settings import Settings from agenteval.web.app import app from agenteval.web.deps import get_db @pytest.fixture() def client_with_db(tmp_path): from agenteval.storage.db import ( # noqa: F401 EvalResultDB, EvalRunDB, EvalTargetDB, ScenarioDB, TurnDB, ) engine = create_engine( f"sqlite:///{tmp_path / 'auth_api.db'}", connect_args={"check_same_thread": False}, ) SQLModel.metadata.create_all(engine) session = Session(engine) def override_get_db(): try: yield session finally: pass app.dependency_overrides[get_db] = override_get_db client = TestClient(app) yield client app.dependency_overrides.clear() session.close() def _patch_settings(monkeypatch, **kwargs): settings = Settings(_env_file=None, **kwargs) from agenteval.web import deps as deps_module from agenteval.web.routers import auth as auth_module monkeypatch.setattr(deps_module, "get_settings", lambda: settings) monkeypatch.setattr(auth_module, "get_settings", lambda: settings) return settings def test_no_credentials_configured_is_open(client_with_db, monkeypatch): _patch_settings(monkeypatch) assert client_with_db.get("/api/targets").status_code == 200 status = client_with_db.get("/api/auth/status").json() assert status == {"auth_required": False, "authenticated": True} def test_login_disabled_returns_400(client_with_db, monkeypatch): _patch_settings(monkeypatch) resp = client_with_db.post("/api/auth/login", json={"password": "whatever"}) assert resp.status_code == 400 def test_admin_password_gates_api(client_with_db, monkeypatch): _patch_settings(monkeypatch, admin_password="s3cret") # No credentials → 401. assert client_with_db.get("/api/targets").status_code == 401 # Wrong password → 401. assert client_with_db.post("/api/auth/login", json={"password": "nope"}).status_code == 401 # Correct password → token that unlocks the API. token = client_with_db.post("/api/auth/login", json={"password": "s3cret"}).json()["token"] resp = client_with_db.get("/api/targets", headers={"X-Auth-Token": token}) assert resp.status_code == 200 status = client_with_db.get("/api/auth/status", headers={"X-Auth-Token": token}).json() assert status == {"auth_required": True, "authenticated": True} assert client_with_db.get("/api/auth/status").json()["authenticated"] is False def test_api_key_still_works_alongside_login(client_with_db, monkeypatch): _patch_settings(monkeypatch, admin_password="s3cret", api_key="machine-key") assert client_with_db.get("/api/targets").status_code == 401 assert client_with_db.get("/api/targets", headers={"X-API-Key": "machine-key"}).status_code == 200 assert client_with_db.get("/api/targets", headers={"X-API-Key": "wrong"}).status_code == 401 def test_health_stays_open(client_with_db, monkeypatch): _patch_settings(monkeypatch, admin_password="s3cret") assert client_with_db.get("/api/health").status_code == 200