import pytest from tests.conftest import auth_header, login @pytest.mark.asyncio async def test_api_token_anlegen_und_verwenden(client, admin_user): """FOUND-016: Token wird einmalig im Klartext zurückgegeben und funktioniert danach als Bearer-Token mit den zugewiesenen Rollen.""" admin_token = await login(client, "admin1") erstellt = await client.post( "/api/v1/api-tokens", json={"name": "CI-Zugriff", "rollen": ["mitarbeiter"]}, headers=auth_header(admin_token), ) assert erstellt.status_code == 201 body = erstellt.json() assert body["token"].startswith("mabea_pat_") assert body["rollen"] == ["mitarbeiter"] klartext = body["token"] # Funktioniert wie ein normaler Bearer-Token gegen einen mitarbeiter+-Endpunkt. me = await client.get("/api/v1/objekte", headers=auth_header(klartext)) assert me.status_code == 200 @pytest.mark.asyncio async def test_api_token_erscheint_nicht_in_benutzer_liste(client, admin_user): admin_token = await login(client, "admin1") await client.post( "/api/v1/api-tokens", json={"name": "Verstecktes Token", "rollen": []}, headers=auth_header(admin_token) ) liste = await client.get("/api/v1/benutzer", headers=auth_header(admin_token)) namen = {b["name"] for b in liste.json()} assert not any("Verstecktes Token" in n for n in namen) @pytest.mark.asyncio async def test_api_token_deaktivieren_sperrt_zugriff(client, admin_user): admin_token = await login(client, "admin1") erstellt = await client.post( "/api/v1/api-tokens", json={"name": "Wird deaktiviert", "rollen": ["administration"]}, headers=auth_header(admin_token), ) token_id = erstellt.json()["id"] klartext = erstellt.json()["token"] vorher = await client.get("/api/v1/objekte", headers=auth_header(klartext)) assert vorher.status_code == 200 deaktiviert = await client.patch( f"/api/v1/api-tokens/{token_id}", json={"aktiv": False}, headers=auth_header(admin_token) ) assert deaktiviert.status_code == 200 assert deaktiviert.json()["aktiv"] is False nachher = await client.get("/api/v1/objekte", headers=auth_header(klartext)) assert nachher.status_code == 401 @pytest.mark.asyncio async def test_api_token_reaktivieren_erlaubt_zugriff_wieder(client, admin_user): admin_token = await login(client, "admin1") erstellt = await client.post( "/api/v1/api-tokens", json={"name": "Reaktivierbar", "rollen": ["mitarbeiter"]}, headers=auth_header(admin_token), ) token_id = erstellt.json()["id"] klartext = erstellt.json()["token"] await client.patch(f"/api/v1/api-tokens/{token_id}", json={"aktiv": False}, headers=auth_header(admin_token)) gesperrt = await client.get("/api/v1/objekte", headers=auth_header(klartext)) assert gesperrt.status_code == 401 await client.patch(f"/api/v1/api-tokens/{token_id}", json={"aktiv": True}, headers=auth_header(admin_token)) wieder_erlaubt = await client.get("/api/v1/objekte", headers=auth_header(klartext)) assert wieder_erlaubt.status_code == 200 @pytest.mark.asyncio async def test_ungueltiges_api_token_wird_abgelehnt(client): response = await client.get("/api/v1/objekte", headers=auth_header("mabea_pat_frei-erfunden")) assert response.status_code == 401 @pytest.mark.asyncio async def test_api_token_rollen_werden_respektiert(client, admin_user): """Token mit mitarbeiter-Rolle darf keine admin-only-Aktion (Objekttyp anlegen) - dieselbe require_roles()-Prüfung wie bei echten Nutzern.""" admin_token = await login(client, "admin1") erstellt = await client.post( "/api/v1/api-tokens", json={"name": "Nur Mitarbeiter", "rollen": ["mitarbeiter"]}, headers=auth_header(admin_token), ) klartext = erstellt.json()["token"] verboten = await client.post( "/api/v1/objekttypen", json={"bereich_id": 1, "name": "Test", "typ": "lager"}, headers=auth_header(klartext), ) assert verboten.status_code == 403 @pytest.mark.asyncio async def test_api_token_liste_und_verwaltung_nur_admin(client, mitarbeiter_user): token = await login(client, "mitarbeiter1") liste = await client.get("/api/v1/api-tokens", headers=auth_header(token)) assert liste.status_code == 403 erstellen = await client.post( "/api/v1/api-tokens", json={"name": "x", "rollen": []}, headers=auth_header(token) ) assert erstellen.status_code == 403 @pytest.mark.asyncio async def test_api_token_liste_zeigt_rollen_und_status(client, admin_user): admin_token = await login(client, "admin1") await client.post( "/api/v1/api-tokens", json={"name": "Sichtbar", "rollen": ["materialverantwortlicher"]}, headers=auth_header(admin_token), ) liste = await client.get("/api/v1/api-tokens", headers=auth_header(admin_token)) assert liste.status_code == 200 eintrag = next(t for t in liste.json() if t["name"] == "Sichtbar") assert eintrag["rollen"] == ["materialverantwortlicher"] assert eintrag["aktiv"] is True assert eintrag["letzte_verwendung_am"] is None