gateway/gwserver/routes/mandates.py
2025-04-06 23:57:10 +02:00

206 lines
No EOL
7.2 KiB
Python

from fastapi import APIRouter, HTTPException, Depends, Body, Path
from typing import List, Dict, Any
from fastapi import status
from datetime import datetime
# Import auth module
from auth import get_current_active_user, get_user_context
# Import interfaces
from modules.gateway_interface import get_gateway_interface
from modules.gateway_model import Mandate
# Alle Attribute des Models ermitteln (außer interne/spezielle Attribute)
def get_model_attributes(model_class):
return [attr for attr in dir(model_class)
if not callable(getattr(model_class, attr))
and not attr.startswith('_')
and attr != 'metadata'
and attr != 'query'
and attr != 'query_class'
and attr != 'label'
and attr != 'field_labels']
# Modell-Attribute für Mandate
mandate_attributes = get_model_attributes(Mandate)
# Router für Mandanten-Endpunkte erstellen
router = APIRouter(
prefix="/api/mandates",
tags=["Mandates"],
responses={404: {"description": "Not found"}}
)
@router.get("", response_model=List[Dict[str, Any]])
async def get_mandates(current_user: Dict[str, Any] = Depends(get_current_active_user)):
"""Alle verfügbaren Mandanten abrufen (nur für SysAdmin-Benutzer)"""
mandate_id, user_id = await get_user_context(current_user)
# Gateway-Interface mit Benutzerkontext initialisieren
gateway = get_gateway_interface(mandate_id, user_id)
# Berechtigungsprüfung
if current_user.get("privilege") != "sysadmin":
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Nur System-Administratoren können alle Mandanten abrufen"
)
# Mandanten generisch abrufen
return gateway.get_all_mandates()
@router.post("", response_model=Dict[str, Any])
async def create_mandate(
mandate: Dict[str, Any] = Body(...),
current_user: Dict[str, Any] = Depends(get_current_active_user)
):
"""Einen neuen Mandanten erstellen (nur für SysAdmin-Benutzer)"""
mandate_id, user_id = await get_user_context(current_user)
# Gateway-Interface mit Benutzerkontext initialisieren
gateway = get_gateway_interface(mandate_id, user_id)
# Berechtigungsprüfung
if current_user.get("privilege") != "sysadmin":
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Nur System-Administratoren können Mandanten erstellen"
)
# Attribute aus dem Request dynamisch setzen
mandate_data = {}
for attr in mandate_attributes:
if attr in mandate:
mandate_data[attr] = mandate[attr]
# Standardwerte für fehlende Felder
if "name" not in mandate_data:
mandate_data["name"] = "Neuer Mandant"
if "language" not in mandate_data:
mandate_data["language"] = "de"
# Mandant erstellen
new_mandate = gateway.create_mandate(**mandate_data)
return new_mandate
@router.get("/{mandate_id}", response_model=Dict[str, Any])
async def get_mandate(
mandate_id: int,
current_user: Dict[str, Any] = Depends(get_current_active_user)
):
"""Einen bestimmten Mandanten abrufen"""
user_mandate_id, user_id = await get_user_context(current_user)
# Gateway-Interface mit Benutzerkontext initialisieren
gateway = get_gateway_interface(user_mandate_id, user_id)
# Berechtigungsprüfung
# Admin darf nur seinen eigenen Mandanten sehen, SysAdmin alle
is_admin = current_user.get("privilege") == "admin"
is_sysadmin = current_user.get("privilege") == "sysadmin"
is_own_mandate = user_mandate_id == mandate_id
if (is_admin and not is_own_mandate) and not is_sysadmin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Keine Berechtigung zum Abrufen dieses Mandanten"
)
# Mandant generisch abrufen
mandate = gateway.get_mandate(mandate_id)
if not mandate:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Mandant mit ID {mandate_id} nicht gefunden"
)
return mandate
@router.put("/{mandate_id}", response_model=Dict[str, Any])
async def update_mandate(
mandate_id: int = Path(..., description="ID des zu aktualisierenden Mandanten"),
mandate_data: Dict[str, Any] = Body(..., description="Aktualisierte Mandantendaten"),
current_user: Dict[str, Any] = Depends(get_current_active_user)
):
"""Einen bestehenden Mandanten aktualisieren"""
user_mandate_id, user_id = await get_user_context(current_user)
# Gateway-Interface mit Benutzerkontext initialisieren
gateway = get_gateway_interface(user_mandate_id, user_id)
# Mandant existiert?
mandate = gateway.get_mandate(mandate_id)
if not mandate:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Mandant mit ID {mandate_id} nicht gefunden"
)
# Berechtigungsprüfung
is_admin = current_user.get("privilege") == "admin"
is_sysadmin = current_user.get("privilege") == "sysadmin"
is_own_mandate = user_mandate_id == mandate_id
if (is_admin and not is_own_mandate) and not is_sysadmin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Keine Berechtigung zum Aktualisieren dieses Mandanten"
)
# Attribute aus dem Request dynamisch in update_data filtern
update_data = {}
for attr in mandate_attributes:
if attr in mandate_data:
update_data[attr] = mandate_data[attr]
# Mandant aktualisieren
updated_mandate = gateway.update_mandate(
mandate_id=mandate_id,
mandate_data=update_data
)
return updated_mandate
@router.delete("/{mandate_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_mandate(
mandate_id: int = Path(..., description="ID des zu löschenden Mandanten"),
current_user: Dict[str, Any] = Depends(get_current_active_user)
):
"""Einen Mandanten löschen, inklusive aller zugehörigen Benutzer und referenzierten Objekte"""
user_mandate_id, user_id = await get_user_context(current_user)
# Gateway-Interface mit Benutzerkontext initialisieren
gateway = get_gateway_interface(user_mandate_id, user_id)
# Mandant existiert?
mandate = gateway.get_mandate(mandate_id)
if not mandate:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Mandant mit ID {mandate_id} nicht gefunden"
)
# Berechtigungsprüfung
is_admin = current_user.get("privilege") == "admin"
is_sysadmin = current_user.get("privilege") == "sysadmin"
is_own_mandate = user_mandate_id == mandate_id
if (is_admin and not is_own_mandate) and not is_sysadmin:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Keine Berechtigung zum Löschen dieses Mandanten"
)
# Mandant löschen
success = gateway.delete_mandate(mandate_id)
if not success:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Fehler beim Löschen des Mandanten mit ID {mandate_id}"
)
# Kein Inhalt zurückgeben bei erfolgreichem Löschen
return None