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

89 lines
2.6 KiB
Python

from __future__ import annotations
from enum import Enum
class StaffRole(str, Enum):
VIEWER = "viewer"
STAFF = "staff"
ADMIN = "admin"
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"
_ROLE_HIERARCHY = {
StaffRole.VIEWER: 10,
StaffRole.STAFF: 20,
StaffRole.ADMIN: 30,
}
_ROLE_PERMISSIONS = {
StaffRole.VIEWER: frozenset(
{
AdminPermission.VIEW_SYSTEM,
AdminPermission.VIEW_REPORTS,
AdminPermission.VIEW_AUDIT_LOGS,
}
),
StaffRole.STAFF: frozenset(
{
AdminPermission.VIEW_SYSTEM,
AdminPermission.VIEW_REPORTS,
AdminPermission.VIEW_AUDIT_LOGS,
AdminPermission.MANAGE_TOOL_DRAFTS,
AdminPermission.REVIEW_TOOL_GENERATIONS,
}
),
StaffRole.ADMIN: 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
return StaffRole(str(role).strip().lower())
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)