feat(dokumente): DOC-005 Zugriffsrechte je Dokumenttyp (Rechnungen eingeschränkt)
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:
@@ -6,8 +6,8 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.api.deps import get_current_user, require_roles
|
||||
from app.db.session import get_db
|
||||
from app.models.auth import RolleTyp
|
||||
from app.models.dokument import Dokument, DokumentTyp
|
||||
from app.models.auth import Benutzer, RolleTyp
|
||||
from app.models.dokument import EINGESCHRAENKTE_DOKUMENTTYPEN, Dokument, DokumentTyp
|
||||
from app.schemas.dokument import DokumentRead, EntitaetTyp
|
||||
from app.services.dokument import (
|
||||
DateityperlaubtError,
|
||||
@@ -31,6 +31,14 @@ _materialverantwortliche = require_roles(
|
||||
RolleTyp.administration, RolleTyp.materialverantwortlicher, RolleTyp.leitungsverantwortlicher
|
||||
)
|
||||
|
||||
_VERANTWORTLICHE_ROLLEN = {RolleTyp.administration, RolleTyp.materialverantwortlicher, RolleTyp.leitungsverantwortlicher}
|
||||
|
||||
|
||||
def _darf_eingeschraenkte_dokumente_sehen(benutzer: Benutzer) -> bool:
|
||||
"""DOC-005: Rechnungen etc. nur für Materialverantwortliche+ - siehe
|
||||
EINGESCHRAENKTE_DOKUMENTTYPEN."""
|
||||
return bool({RolleTyp(r) for r in benutzer.rollen_namen} & _VERANTWORTLICHE_ROLLEN)
|
||||
|
||||
|
||||
@router.get("/dokumente", response_model=list[DokumentRead])
|
||||
async def liste_dokumente(
|
||||
@@ -38,10 +46,14 @@ async def liste_dokumente(
|
||||
entitaet_id: str,
|
||||
dokumenttyp: DokumentTyp | None = None,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
_=Depends(get_current_user),
|
||||
current_user: Benutzer = Depends(get_current_user),
|
||||
) -> list[Dokument]:
|
||||
return await liste_fuer_entitaet(
|
||||
db, entitaet_typ=entitaet_typ, entitaet_id=entitaet_id, dokumenttyp=dokumenttyp
|
||||
db,
|
||||
entitaet_typ=entitaet_typ,
|
||||
entitaet_id=entitaet_id,
|
||||
dokumenttyp=dokumenttyp,
|
||||
darf_eingeschraenkte_sehen=_darf_eingeschraenkte_dokumente_sehen(current_user),
|
||||
)
|
||||
|
||||
|
||||
@@ -89,11 +101,17 @@ async def lade_dokument_hoch(
|
||||
|
||||
@router.get("/dokumente/{dokument_id}/download")
|
||||
async def lade_dokument_herunter(
|
||||
dokument_id: uuid.UUID, db: AsyncSession = Depends(get_db), _=Depends(get_current_user)
|
||||
dokument_id: uuid.UUID,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: Benutzer = Depends(get_current_user),
|
||||
) -> FileResponse:
|
||||
dokument = await db.get(Dokument, dokument_id)
|
||||
if dokument is None:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Dokument nicht gefunden")
|
||||
if dokument.dokumenttyp in EINGESCHRAENKTE_DOKUMENTTYPEN and not _darf_eingeschraenkte_dokumente_sehen(
|
||||
current_user
|
||||
):
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Für diesen Dokumenttyp fehlt die Berechtigung")
|
||||
pfad = dateipfad(dokument)
|
||||
if not pfad.exists():
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Datei nicht mehr vorhanden")
|
||||
|
||||
Reference in New Issue
Block a user