feat(dokumente): DOC-005 Zugriffsrechte je Dokumenttyp (Rechnungen eingeschränkt)
CI / backend-tests (push) Failing after 2m17s
CI / frontend-build (push) Successful in 28s

Rechnungen sind finanziell sensibel - nur Materialverantwortliche/
Leitungsverantwortliche/Administration dürfen sie in der Liste sehen und
herunterladen (403 bei direktem Downloadversuch), Mitarbeiter nicht.
Hochladen bleibt für alle offen (z.B. Wareneingang direkt scannen). Andere
Dokumenttypen bleiben unverändert für jeden mit Aktenzugriff sichtbar - die
werden im Feldeinsatz gebraucht. EINGESCHRAENKTE_DOKUMENTTYPEN als zentrale
Stelle für künftige weitere Einschränkungen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVgbozhYmuEhiEJHffRXCV
This commit is contained in:
2026-09-08 10:39:42 +02:00
co-authored by Claude Sonnet 5
parent 069a1ee7ee
commit 654d448e7b
5 changed files with 101 additions and 8 deletions
+60
View File
@@ -195,3 +195,63 @@ async def test_unbekannter_dokumenttyp_wird_abgelehnt(client, objekt_mit_positio
headers=auth_header(token),
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_mitarbeiter_sieht_rechnungen_nicht_in_der_liste(
client, objekt_mit_position, mitarbeiter_user, materialverantwortlicher_user
):
"""DOC-005: Rechnungen sind für Mitarbeiter unsichtbar, für Materialverantwortliche sichtbar."""
objekt, _material = objekt_mit_position
verantwortlicher_token = await login(client, "materialverantwortlicher1")
await client.post(
"/api/v1/dokumente",
data={"entitaet_typ": "objekt", "entitaet_id": str(objekt.id), "dokumenttyp": "rechnung"},
files={"datei": ("rechnung.pdf", b"%PDF-1.4 r", "application/pdf")},
headers=auth_header(verantwortlicher_token),
)
await client.post(
"/api/v1/dokumente",
data={"entitaet_typ": "objekt", "entitaet_id": str(objekt.id), "dokumenttyp": "pruefprotokoll"},
files={"datei": ("pruefung.pdf", b"%PDF-1.4 p", "application/pdf")},
headers=auth_header(verantwortlicher_token),
)
mitarbeiter_token = await login(client, "mitarbeiter1")
als_mitarbeiter = await client.get(
f"/api/v1/dokumente?entitaet_typ=objekt&entitaet_id={objekt.id}", headers=auth_header(mitarbeiter_token)
)
dateinamen = [d["dateiname"] for d in als_mitarbeiter.json()]
assert "rechnung.pdf" not in dateinamen
assert "pruefung.pdf" in dateinamen
als_verantwortlicher = await client.get(
f"/api/v1/dokumente?entitaet_typ=objekt&entitaet_id={objekt.id}", headers=auth_header(verantwortlicher_token)
)
assert len(als_verantwortlicher.json()) == 2
@pytest.mark.asyncio
async def test_mitarbeiter_kann_rechnung_nicht_direkt_herunterladen(
client, objekt_mit_position, mitarbeiter_user, materialverantwortlicher_user
):
objekt, _material = objekt_mit_position
verantwortlicher_token = await login(client, "materialverantwortlicher1")
hochgeladen = await client.post(
"/api/v1/dokumente",
data={"entitaet_typ": "objekt", "entitaet_id": str(objekt.id), "dokumenttyp": "rechnung"},
files={"datei": ("rechnung.pdf", b"%PDF-1.4 r", "application/pdf")},
headers=auth_header(verantwortlicher_token),
)
dokument_id = hochgeladen.json()["id"]
mitarbeiter_token = await login(client, "mitarbeiter1")
verweigert = await client.get(
f"/api/v1/dokumente/{dokument_id}/download", headers=auth_header(mitarbeiter_token)
)
assert verweigert.status_code == 403
erlaubt = await client.get(
f"/api/v1/dokumente/{dokument_id}/download", headers=auth_header(verantwortlicher_token)
)
assert erlaubt.status_code == 200