You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
10 KiB
Python
309 lines
10 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
|
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,
|
|
AdminSystemBotGovernedConfigurationResponse,
|
|
AdminSystemConfigurationResponse,
|
|
AdminSystemFunctionalConfigurationCatalogResponse,
|
|
AdminSystemFunctionalConfigurationDetailResponse,
|
|
AdminSystemInfoResponse,
|
|
AdminSystemModelRuntimeSeparationResponse,
|
|
AdminSystemRuntimeConfigurationResponse,
|
|
AdminSystemSecurityConfigurationResponse,
|
|
AdminSystemWriteGovernanceResponse,
|
|
)
|
|
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
|
|
|
|
# governança e configuração do sistema.
|
|
|
|
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(),
|
|
model_runtimes=service.build_model_runtime_separation_payload(),
|
|
write_governance=service.build_write_governance_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(),
|
|
)
|
|
|
|
|
|
@router.get(
|
|
"/system/configuration/model-runtimes",
|
|
response_model=AdminSystemModelRuntimeSeparationResponse,
|
|
)
|
|
def system_model_runtime_separation(
|
|
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 AdminSystemModelRuntimeSeparationResponse(
|
|
service="orquestrador-admin",
|
|
model_runtimes=service.build_model_runtime_separation_payload(),
|
|
)
|
|
|
|
|
|
@router.get(
|
|
"/system/configuration/write-governance",
|
|
response_model=AdminSystemWriteGovernanceResponse,
|
|
)
|
|
def system_write_governance_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 AdminSystemWriteGovernanceResponse(
|
|
service="orquestrador-admin",
|
|
write_governance=service.build_write_governance_payload(),
|
|
)
|
|
|
|
|
|
@router.get(
|
|
"/system/configuration/functional",
|
|
response_model=AdminSystemFunctionalConfigurationCatalogResponse,
|
|
)
|
|
def system_functional_configuration_catalog(
|
|
settings: AdminSettings = Depends(get_settings),
|
|
security_service: AdminSecurityService = Depends(get_security_service),
|
|
_: AuthenticatedStaffPrincipal = Depends(
|
|
require_admin_permission(AdminPermission.VIEW_SYSTEM)
|
|
),
|
|
):
|
|
service = _build_service(settings, security_service)
|
|
payload = service.build_functional_configuration_catalog_payload()
|
|
return AdminSystemFunctionalConfigurationCatalogResponse(
|
|
service="orquestrador-admin",
|
|
mode=payload["mode"],
|
|
configurations=payload["configurations"],
|
|
bot_governed_parent_config_keys=payload["bot_governed_parent_config_keys"],
|
|
next_steps=payload["next_steps"],
|
|
)
|
|
|
|
|
|
@router.get(
|
|
"/system/configuration/functional/bot-governance",
|
|
response_model=AdminSystemBotGovernedConfigurationResponse,
|
|
)
|
|
def system_bot_governed_configuration(
|
|
settings: AdminSettings = Depends(get_settings),
|
|
security_service: AdminSecurityService = Depends(get_security_service),
|
|
_: AuthenticatedStaffPrincipal = Depends(
|
|
require_admin_permission(AdminPermission.VIEW_SYSTEM)
|
|
),
|
|
):
|
|
service = _build_service(settings, security_service)
|
|
payload = service.build_bot_governed_configuration_payload()
|
|
return AdminSystemBotGovernedConfigurationResponse(
|
|
service="orquestrador-admin",
|
|
parent_config_keys=payload["parent_config_keys"],
|
|
settings=payload["settings"],
|
|
)
|
|
|
|
|
|
@router.get(
|
|
"/system/configuration/functional/{config_key}",
|
|
response_model=AdminSystemFunctionalConfigurationDetailResponse,
|
|
)
|
|
def system_functional_configuration_detail(
|
|
config_key: str,
|
|
settings: AdminSettings = Depends(get_settings),
|
|
security_service: AdminSecurityService = Depends(get_security_service),
|
|
_: AuthenticatedStaffPrincipal = Depends(
|
|
require_admin_permission(AdminPermission.VIEW_SYSTEM)
|
|
),
|
|
):
|
|
service = _build_service(settings, security_service)
|
|
payload = service.get_functional_configuration_payload(config_key)
|
|
if payload is None:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Configuracao funcional do sistema nao encontrada.",
|
|
)
|
|
|
|
return AdminSystemFunctionalConfigurationDetailResponse(
|
|
service="orquestrador-admin",
|
|
configuration=payload["configuration"],
|
|
linked_bot_settings=payload["linked_bot_settings"],
|
|
related_runtime_profile=payload["related_runtime_profile"],
|
|
managed_by_bot_governance=payload["managed_by_bot_governance"],
|
|
)
|
|
|
|
|
|
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}"
|