""" CalDAV-Konfiguration und manueller Sync-Trigger. Firmenkalender: nur COMPANY_ADMIN / SUPER_ADMIN Persönlicher Kalender: jeder eingeloggte Nutzer für sich selbst """ import uuid from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.core.dependencies import CurrentUser, require_role from app.models.caldav_config import CaldavCompanyConfig, CaldavUserConfig from app.models.user import User, UserRole from app.schemas.caldav import ( CaldavCompanyConfigOut, CaldavCompanyConfigSave, CaldavUserConfigOut, CaldavUserConfigSave, ResyncResult, ) from app.services.caldav_service import caldav_service, encrypt_password router = APIRouter(prefix="/caldav", tags=["CalDAV"]) _admin_roles = (UserRole.COMPANY_ADMIN, UserRole.SUPER_ADMIN) # ── Firmenkalender ───────────────────────────────────────────────────────────── @router.get("/company/config", response_model=CaldavCompanyConfigOut | None) async def get_company_config( current_user: User = require_role(*_admin_roles), db: AsyncSession = Depends(get_db), ): cfg = await caldav_service.get_company_config(current_user.company_id, db) return CaldavCompanyConfigOut.model_validate(cfg) if cfg else None @router.post("/company/config", response_model=CaldavCompanyConfigOut) async def save_company_config( data: CaldavCompanyConfigSave, current_user: User = require_role(*_admin_roles), db: AsyncSession = Depends(get_db), ): cfg = await caldav_service.get_company_config(current_user.company_id, db) if cfg is None: cfg = CaldavCompanyConfig(company_id=current_user.company_id, id=uuid.uuid4()) db.add(cfg) cfg.enabled = data.enabled cfg.principal_url = data.principal_url cfg.calendar_url = data.calendar_url cfg.username = data.username cfg.calendar_display_name = data.calendar_display_name cfg.verify_ssl = data.verify_ssl if data.password: cfg.password_encrypted = encrypt_password(data.password) elif not cfg.password_encrypted: raise HTTPException(status_code=400, detail="Passwort wird beim ersten Speichern benötigt.") await db.commit() return CaldavCompanyConfigOut.model_validate(cfg) @router.post("/company/test") async def test_company_config( current_user: User = require_role(*_admin_roles), db: AsyncSession = Depends(get_db), ): cfg = await caldav_service.get_company_config(current_user.company_id, db) if not cfg: raise HTTPException(status_code=404, detail="Keine Firmen-CalDAV-Konfiguration vorhanden.") result = await caldav_service.test_config(cfg) if not result["ok"]: raise HTTPException(status_code=502, detail=result["error"]) return {"message": "Verbindung erfolgreich.", "http_status": result.get("status")} @router.post("/company/resync", response_model=ResyncResult) async def resync_all( current_user: User = require_role(*_admin_roles), db: AsyncSession = Depends(get_db), ): """Alle genehmigten Abwesenheiten neu in den Firmenkalender synchronisieren.""" result = await caldav_service.resync_all_approved(current_user.company_id, db) await db.commit() return ResyncResult(**result) # ── Persönlicher Kalender ────────────────────────────────────────────────────── @router.get("/user/config", response_model=CaldavUserConfigOut | None) async def get_user_config( current_user: CurrentUser, db: AsyncSession = Depends(get_db), ): cfg = await caldav_service.get_user_config(current_user.id, db) return CaldavUserConfigOut.model_validate(cfg) if cfg else None @router.post("/user/config", response_model=CaldavUserConfigOut) async def save_user_config( data: CaldavUserConfigSave, current_user: CurrentUser, db: AsyncSession = Depends(get_db), ): cfg = await caldav_service.get_user_config(current_user.id, db) if cfg is None: cfg = CaldavUserConfig(user_id=current_user.id, id=uuid.uuid4()) db.add(cfg) cfg.enabled = data.enabled cfg.principal_url = data.principal_url cfg.calendar_url = data.calendar_url cfg.username = data.username cfg.calendar_display_name = data.calendar_display_name cfg.verify_ssl = data.verify_ssl if data.password: cfg.password_encrypted = encrypt_password(data.password) elif not cfg.password_encrypted: raise HTTPException(status_code=400, detail="Passwort wird beim ersten Speichern benötigt.") await db.commit() return CaldavUserConfigOut.model_validate(cfg) @router.post("/user/test") async def test_user_config( current_user: CurrentUser, db: AsyncSession = Depends(get_db), ): cfg = await caldav_service.get_user_config(current_user.id, db) if not cfg: raise HTTPException(status_code=404, detail="Keine persönliche CalDAV-Konfiguration vorhanden.") result = await caldav_service.test_config(cfg) if not result["ok"]: raise HTTPException(status_code=502, detail=result["error"]) return {"message": "Verbindung erfolgreich.", "http_status": result.get("status")}