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.
orquestrador/shared/contracts/access_control.py

87 lines
2.5 KiB
Python

from __future__ import annotations
from enum import Enum
class StaffRole(str, Enum):
COLABORADOR = "colaborador"
DIRETOR = "diretor"
class AdminPermission(str, Enum):
VIEW_SYSTEM = "view_system"
VIEW_REPORTS = "view_reports"
VIEW_AUDIT_LOGS = "view_audit_logs"
MANAGE_TOOL_DRAFTS = "manage_tool_drafts"
REVIEW_TOOL_GENERATIONS = "review_tool_generations"
PUBLISH_TOOLS = "publish_tools"
MANAGE_SETTINGS = "manage_settings"
MANAGE_STAFF_ACCOUNTS = "manage_staff_accounts"
_LEGACY_ROLE_ALIASES = {
"viewer": StaffRole.COLABORADOR,
"staff": StaffRole.COLABORADOR,
"admin": StaffRole.DIRETOR,
}
_ROLE_HIERARCHY = {
StaffRole.COLABORADOR: 10,
StaffRole.DIRETOR: 20,
}
_ROLE_PERMISSIONS = {
StaffRole.COLABORADOR: frozenset(
{
AdminPermission.VIEW_SYSTEM,
AdminPermission.VIEW_REPORTS,
AdminPermission.VIEW_AUDIT_LOGS,
AdminPermission.MANAGE_TOOL_DRAFTS,
}
),
StaffRole.DIRETOR: frozenset(
{
AdminPermission.VIEW_SYSTEM,
AdminPermission.VIEW_REPORTS,
AdminPermission.VIEW_AUDIT_LOGS,
AdminPermission.MANAGE_TOOL_DRAFTS,
AdminPermission.REVIEW_TOOL_GENERATIONS,
AdminPermission.PUBLISH_TOOLS,
AdminPermission.MANAGE_SETTINGS,
AdminPermission.MANAGE_STAFF_ACCOUNTS,
}
),
}
def normalize_staff_role(role: StaffRole | str) -> StaffRole:
if isinstance(role, StaffRole):
return role
normalized = str(role).strip().lower()
if normalized in _LEGACY_ROLE_ALIASES:
return _LEGACY_ROLE_ALIASES[normalized]
return StaffRole(normalized)
def normalize_admin_permission(permission: AdminPermission | str) -> AdminPermission:
if isinstance(permission, AdminPermission):
return permission
return AdminPermission(str(permission).strip().lower())
def permissions_for_role(role: StaffRole | str) -> frozenset[AdminPermission]:
normalized_role = normalize_staff_role(role)
return _ROLE_PERMISSIONS[normalized_role]
def role_includes(role: StaffRole | str, minimum_role: StaffRole | str) -> bool:
normalized_role = normalize_staff_role(role)
normalized_minimum = normalize_staff_role(minimum_role)
return _ROLE_HIERARCHY[normalized_role] >= _ROLE_HIERARCHY[normalized_minimum]
def role_has_permission(role: StaffRole | str, permission: AdminPermission | str) -> bool:
normalized_permission = normalize_admin_permission(permission)
return normalized_permission in permissions_for_role(role)