"""SUPER_ADMIN: TLS-Zertifikat-Status + manuelles Renewal (server-lokal). Läuft mit Root-Rechten (timemaster.service User=root), deshalb strikt auf SUPER_ADMIN begrenzt + AuditLog + Rate-Limit. Kein Cross-Server-Wissen – zeigt nur das Zertifikat DIESES Servers. """ from fastapi import APIRouter, Depends, HTTPException, Request from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.core.dependencies import get_client_ip, require_role from app.core.limiter import limiter from app.models.audit_log import AuditLog from app.models.user import User, UserRole from app.services import tls_service router = APIRouter(prefix="/admin/tls", tags=["Admin · TLS"]) _sa = (UserRole.SUPER_ADMIN,) class TlsStatusOut(BaseModel): mode: str domain: str | None valid_until: str | None renewable: bool ca_cert_path: str | None = None class TlsRenewCertbot(BaseModel): domain: str class TlsRenewInternal(BaseModel): hostname: str ip: str | None = None @router.get("/status", response_model=TlsStatusOut) async def tls_status(current_user: User = require_role(*_sa)): return tls_service.get_tls_status() @router.post("/renew/certbot", response_model=TlsStatusOut) @limiter.limit("5/hour") async def tls_renew_certbot( request: Request, data: TlsRenewCertbot, current_user: User = require_role(*_sa), db: AsyncSession = Depends(get_db), ): try: tls_service.renew_certbot(data.domain) except ValueError as e: raise HTTPException(422, str(e)) except RuntimeError as e: raise HTTPException(500, f"Zertifikat-Renewal fehlgeschlagen: {e}") db.add(AuditLog( company_id=None, user_id=current_user.id, action="tls_renewed_certbot", entity_type="server", entity_id=None, new_value={"domain": data.domain}, ip=get_client_ip(request), )) await db.commit() return tls_service.get_tls_status() @router.post("/renew/internal", response_model=TlsStatusOut) @limiter.limit("5/hour") async def tls_renew_internal( request: Request, data: TlsRenewInternal, current_user: User = require_role(*_sa), db: AsyncSession = Depends(get_db), ): try: tls_service.renew_internal(data.hostname, data.ip) except ValueError as e: raise HTTPException(422, str(e)) except RuntimeError as e: raise HTTPException(500, f"Zertifikat-Renewal fehlgeschlagen: {e}") db.add(AuditLog( company_id=None, user_id=current_user.id, action="tls_renewed_internal", entity_type="server", entity_id=None, new_value={"hostname": data.hostname, "ip": data.ip}, ip=get_client_ip(request), )) await db.commit() return tls_service.get_tls_status()