from fastapi import APIRouter, Depends, Request from fastapi.responses import RedirectResponse, Response from admin_app.api.dependencies import ( get_current_staff_permissions, get_security_service, get_settings, require_admin_permission, ) from admin_app.api.panel_session import ( PANEL_ACCESS_COOKIE_NAME, PANEL_COOKIE_SAMESITE, PANEL_REFRESH_COOKIE_NAME, build_panel_cookie_path, should_use_secure_cookies, ) from admin_app.api.schemas import ( AdminCapabilityResponse, AdminCurrentAccessResponse, AdminHealthResponse, AdminSystemConfigurationResponse, AdminSystemInfoResponse, AdminSystemRuntimeConfigurationResponse, AdminSystemSecurityConfigurationResponse, ) from admin_app.core import AdminSecurityService, AuthenticatedStaffPrincipal from admin_app.core.settings import AdminSettings from admin_app.services.system_service import SystemService from shared.contracts import AdminPermission router = APIRouter(tags=["system"]) def _build_service( settings: AdminSettings, security_service: AdminSecurityService, ) -> SystemService: return SystemService(settings=settings, security_service=security_service) @router.get("/", response_model=None) def root( request: Request, settings: AdminSettings = Depends(get_settings), ) -> Response | dict: if "text/html" in request.headers.get("accept", ""): return RedirectResponse( url=_build_prefixed_path(settings.admin_api_prefix, "/login"), status_code=302, ) return SystemService(settings=settings).build_root_payload() @router.get("/health", response_model=AdminHealthResponse) def health_check(settings: AdminSettings = Depends(get_settings)): return SystemService(settings=settings).build_health_payload() @router.get( "/system/info", response_model=AdminSystemInfoResponse, ) def system_info( settings: AdminSettings = Depends(get_settings), security_service: AdminSecurityService = Depends(get_security_service), _: AuthenticatedStaffPrincipal = Depends( require_admin_permission(AdminPermission.VIEW_SYSTEM) ), ): return _build_service(settings, security_service).build_system_info_payload() @router.get( "/system/access", response_model=AdminCurrentAccessResponse, ) def current_access( current_staff: AuthenticatedStaffPrincipal = Depends( require_admin_permission(AdminPermission.VIEW_SYSTEM) ), permissions: tuple[str, ...] = Depends(get_current_staff_permissions), ): return AdminCurrentAccessResponse( service="orquestrador-admin", staff_account={ "id": current_staff.id, "email": current_staff.email, "display_name": current_staff.display_name, "role": current_staff.role, "is_active": current_staff.is_active, }, permissions=list(permissions), ) @router.get( "/system/admin-capabilities", response_model=AdminCapabilityResponse, ) def admin_capabilities( current_staff: AuthenticatedStaffPrincipal = Depends( require_admin_permission(AdminPermission.MANAGE_SETTINGS) ), ): return AdminCapabilityResponse( service="orquestrador-admin", action="manage_settings", allowed=True, role=current_staff.role, ) @router.get( "/system/configuration", response_model=AdminSystemConfigurationResponse, ) def system_configuration( settings: AdminSettings = Depends(get_settings), security_service: AdminSecurityService = Depends(get_security_service), _: AuthenticatedStaffPrincipal = Depends( require_admin_permission(AdminPermission.MANAGE_SETTINGS) ), ): service = _build_service(settings, security_service) runtime_payload = _build_runtime_configuration_payload(service, settings) return AdminSystemConfigurationResponse( service="orquestrador-admin", runtime=runtime_payload, security=service.build_security_configuration_payload(), sources=service.build_configuration_sources_payload(), ) @router.get( "/system/configuration/runtime", response_model=AdminSystemRuntimeConfigurationResponse, ) def system_runtime_configuration( settings: AdminSettings = Depends(get_settings), security_service: AdminSecurityService = Depends(get_security_service), _: AuthenticatedStaffPrincipal = Depends( require_admin_permission(AdminPermission.MANAGE_SETTINGS) ), ): service = _build_service(settings, security_service) return AdminSystemRuntimeConfigurationResponse( service="orquestrador-admin", runtime=_build_runtime_configuration_payload(service, settings), ) @router.get( "/system/configuration/security", response_model=AdminSystemSecurityConfigurationResponse, ) def system_security_configuration( settings: AdminSettings = Depends(get_settings), security_service: AdminSecurityService = Depends(get_security_service), _: AuthenticatedStaffPrincipal = Depends( require_admin_permission(AdminPermission.MANAGE_SETTINGS) ), ): service = _build_service(settings, security_service) return AdminSystemSecurityConfigurationResponse( service="orquestrador-admin", security=service.build_security_configuration_payload(), ) def _build_runtime_configuration_payload( service: SystemService, settings: AdminSettings, ) -> dict: runtime_payload = service.build_runtime_configuration_payload() runtime_payload["panel_session"] = { "access_cookie_name": PANEL_ACCESS_COOKIE_NAME, "refresh_cookie_name": PANEL_REFRESH_COOKIE_NAME, "cookie_path": build_panel_cookie_path(settings), "same_site": PANEL_COOKIE_SAMESITE, "secure_cookies": should_use_secure_cookies(settings), } return runtime_payload def _build_prefixed_path(api_prefix: str, path: str) -> str: normalized_prefix = api_prefix.rstrip("/") normalized_path = path if path.startswith("/") else f"/{path}" if not normalized_prefix: return normalized_path if normalized_path == "/": return f"{normalized_prefix}/" return f"{normalized_prefix}{normalized_path}"