feat(dsgvo): Art. 15 Auskunftsrecht – strukturierter Datenexport pro User
GET /users/{id}/export-data liefert alle personenbezogenen Daten
(Profil, Zeiterfassung, Abwesenheiten, Kommentare, Urlaubs-/Überstunden-
konto, Auszahlungen, AuditLog-Einträge über den User) als JSON-Download.
Eigenes Konto immer erlaubt, fremde Konten nur HR/Admin/Manager der
eigenen Firma. Ergänzt die bestehende Art.-17-Anonymisierung.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CviFgc739S89xS97pvjszj
This commit is contained in:
@@ -2,7 +2,7 @@ from typing import Annotated
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile
|
||||
from fastapi.responses import PlainTextResponse
|
||||
from fastapi.responses import PlainTextResponse, Response
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.database import get_db
|
||||
@@ -22,6 +22,7 @@ from app.schemas.user import (
|
||||
UserUpdate,
|
||||
)
|
||||
from app.services import user_import_service
|
||||
from app.services.gdpr_service import gdpr_service
|
||||
from app.services.user_service import user_service
|
||||
|
||||
router = APIRouter(prefix="/users", tags=["Users"])
|
||||
@@ -244,6 +245,30 @@ async def anonymize_user(
|
||||
return UserOut.model_validate(user)
|
||||
|
||||
|
||||
@router.get("/{user_id}/export-data")
|
||||
async def export_user_data(
|
||||
user_id: UUID,
|
||||
current_user: CurrentUser,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""DSGVO Art. 15 (Auskunftsrecht): strukturierter Export aller
|
||||
personenbezogenen Daten des Users als JSON. Eigenes Konto immer erlaubt,
|
||||
fremde Konten nur für HR/Admin/Manager der eigenen Firma."""
|
||||
if user_id != current_user.id and current_user.role not in _hr_roles:
|
||||
raise HTTPException(status_code=403, detail="Keine Berechtigung für dieses Konto")
|
||||
|
||||
try:
|
||||
data = await gdpr_service.export_user_data(user_id, current_user.company_id, db)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
|
||||
content = gdpr_service.to_json(data)
|
||||
return Response(
|
||||
content=content, media_type="application/json",
|
||||
headers={"Content-Disposition": f"attachment; filename=datenauskunft_{user_id}.json"},
|
||||
)
|
||||
|
||||
|
||||
@router.post("/{user_id}/kiosk-pin", response_model=MessageResponse)
|
||||
async def set_kiosk_pin(
|
||||
user_id: UUID,
|
||||
|
||||
Reference in New Issue
Block a user