Sync app/permissions.py with Spec 027 RBAC for vm123 and agentic routes.
Fixes ImportError on staging API build (can_access_foss_admin missing). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
62463aa76f
commit
bf367a75eb
1 changed files with 190 additions and 17 deletions
|
|
@ -1,19 +1,71 @@
|
|||
"""RBAC helpers for Ligbox Ops Desk."""
|
||||
"""RBAC helpers for Ligbox Ops Desk — Spec 003 + 027."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
ROLES = frozenset({"super_admin", "ops_lead", "technician", "noc"})
|
||||
# Ops (Spec 003)
|
||||
OPS_ROLES = frozenset({"super_admin", "ops_lead", "technician", "noc"})
|
||||
|
||||
ROLE_LABELS = {
|
||||
# Comercial (Spec 027)
|
||||
SALES_ROLES = frozenset({"sales_admin", "sales_support"})
|
||||
|
||||
# Negócio / plataforma (Spec 027)
|
||||
BUSINESS_ROLES = frozenset(
|
||||
{
|
||||
"finance",
|
||||
"marketing",
|
||||
"seo",
|
||||
"developer",
|
||||
"devops",
|
||||
"security_analyst",
|
||||
"content_editor",
|
||||
"agentic_operator",
|
||||
}
|
||||
)
|
||||
|
||||
# Sistema (não humanos)
|
||||
SYSTEM_ROLES = frozenset({"api_service", "agent_system"})
|
||||
|
||||
ALL_ROLES = OPS_ROLES | SALES_ROLES | BUSINESS_ROLES | SYSTEM_ROLES
|
||||
|
||||
# Funções humanas (login Desk)
|
||||
HUMAN_ROLES = OPS_ROLES | SALES_ROLES | BUSINESS_ROLES
|
||||
|
||||
# Atribuíveis no cadastro Spec 004 (exceto super_admin)
|
||||
ASSIGNABLE_ROLES = HUMAN_ROLES - {"super_admin"}
|
||||
|
||||
# Compatibilidade com código existente
|
||||
ROLES = HUMAN_ROLES
|
||||
|
||||
ROLE_LABELS: dict[str, str] = {
|
||||
"super_admin": "Super Admin",
|
||||
"ops_lead": "Chefe Ops",
|
||||
"technician": "Suporte",
|
||||
"noc": "NOC",
|
||||
"sales_admin": "Sales Admin",
|
||||
"sales_support": "Sales Support",
|
||||
"finance": "Financeiro",
|
||||
"marketing": "Marketing",
|
||||
"seo": "SEO",
|
||||
"developer": "Developer",
|
||||
"devops": "DevOps",
|
||||
"security_analyst": "Segurança / SOC",
|
||||
"content_editor": "Conteúdo / CMS",
|
||||
"agentic_operator": "Operador Agentes IA",
|
||||
"api_service": "API Service",
|
||||
"agent_system": "Agent System",
|
||||
}
|
||||
|
||||
|
||||
def is_valid_role(role: str) -> bool:
|
||||
return role in ALL_ROLES
|
||||
|
||||
|
||||
def is_assignable_role(role: str) -> bool:
|
||||
return role in ASSIGNABLE_ROLES
|
||||
|
||||
|
||||
def can_read_tickets(role: str) -> bool:
|
||||
return role in ROLES
|
||||
return role in HUMAN_ROLES
|
||||
|
||||
|
||||
def can_patch_ticket(role: str, ticket: dict, username: str) -> bool:
|
||||
|
|
@ -38,37 +90,99 @@ def can_run_audit(role: str) -> bool:
|
|||
|
||||
|
||||
def can_read_audit_overview(role: str) -> bool:
|
||||
return role in ("super_admin", "ops_lead", "noc")
|
||||
return role in (
|
||||
"super_admin",
|
||||
"ops_lead",
|
||||
"noc",
|
||||
"developer",
|
||||
"devops",
|
||||
"security_analyst",
|
||||
"agentic_operator",
|
||||
)
|
||||
|
||||
|
||||
def can_read_audit_scorecard(role: str) -> bool:
|
||||
return role in ("super_admin", "ops_lead", "noc")
|
||||
return role in (
|
||||
"super_admin",
|
||||
"ops_lead",
|
||||
"noc",
|
||||
"developer",
|
||||
"security_analyst",
|
||||
"agentic_operator",
|
||||
)
|
||||
|
||||
|
||||
def can_read_cloudflare_dns(role: str) -> bool:
|
||||
return role in ("super_admin", "ops_lead", "technician", "noc")
|
||||
return role in (
|
||||
"super_admin",
|
||||
"ops_lead",
|
||||
"technician",
|
||||
"noc",
|
||||
"seo",
|
||||
"devops",
|
||||
"developer",
|
||||
)
|
||||
|
||||
|
||||
def can_read_funnel(role: str) -> bool:
|
||||
return role in ROLES
|
||||
return role in (
|
||||
"super_admin",
|
||||
"ops_lead",
|
||||
"technician",
|
||||
"noc",
|
||||
"sales_admin",
|
||||
"sales_support",
|
||||
"finance",
|
||||
"marketing",
|
||||
"seo",
|
||||
"developer",
|
||||
"devops",
|
||||
"agentic_operator",
|
||||
)
|
||||
|
||||
|
||||
def can_read_session_timeline(role: str) -> bool:
|
||||
return role in ("super_admin", "ops_lead", "technician")
|
||||
return role in (
|
||||
"super_admin",
|
||||
"ops_lead",
|
||||
"technician",
|
||||
"sales_admin",
|
||||
"sales_support",
|
||||
"finance",
|
||||
"marketing",
|
||||
"seo",
|
||||
"developer",
|
||||
"devops",
|
||||
"agentic_operator",
|
||||
)
|
||||
|
||||
|
||||
def can_list_webhook_events(role: str, source: str | None = None) -> bool:
|
||||
if role == "noc":
|
||||
return source in (None, "wazuh", "vm112-security")
|
||||
return role in ROLES
|
||||
if role == "security_analyst":
|
||||
return source in (None, "wazuh", "vm112-security", "vm112")
|
||||
if role == "finance":
|
||||
return source in (None, "billing", "vm112")
|
||||
if role == "developer":
|
||||
return source in (None, "vm112", "wazuh")
|
||||
return role in HUMAN_ROLES
|
||||
|
||||
|
||||
def can_read_crm_leads(role: str) -> bool:
|
||||
return role in ("super_admin", "ops_lead", "technician")
|
||||
return role in (
|
||||
"super_admin",
|
||||
"ops_lead",
|
||||
"technician",
|
||||
"sales_admin",
|
||||
"sales_support",
|
||||
"marketing",
|
||||
"seo",
|
||||
)
|
||||
|
||||
|
||||
def can_read_assist(role: str) -> bool:
|
||||
return role in ROLES
|
||||
return role in ("super_admin", "ops_lead", "technician", "sales_admin", "sales_support")
|
||||
|
||||
|
||||
def can_assist_takeover(role: str) -> bool:
|
||||
|
|
@ -85,15 +199,15 @@ def can_manage_users(role: str) -> bool:
|
|||
|
||||
def can_manage_vm112_domains(role: str) -> bool:
|
||||
"""Admin Desk — domínios orquestrados VM112 (Spec 017)."""
|
||||
return role in ("super_admin", "ops_lead")
|
||||
return role in ("super_admin", "ops_lead", "devops")
|
||||
|
||||
|
||||
def should_mask_sensitive(role: str) -> bool:
|
||||
return role == "noc"
|
||||
return role in ("noc", "sales_support")
|
||||
|
||||
|
||||
def can_read_migration(role: str) -> bool:
|
||||
return role in ("super_admin", "ops_lead", "technician", "noc")
|
||||
return role in ("super_admin", "ops_lead", "technician", "noc", "devops")
|
||||
|
||||
|
||||
def can_manage_migration(role: str) -> bool:
|
||||
|
|
@ -101,8 +215,67 @@ def can_manage_migration(role: str) -> bool:
|
|||
|
||||
|
||||
def can_read_billing(role: str) -> bool:
|
||||
return role in ROLES
|
||||
return role in (
|
||||
"super_admin",
|
||||
"ops_lead",
|
||||
"noc",
|
||||
"finance",
|
||||
"sales_admin",
|
||||
"sales_support",
|
||||
)
|
||||
|
||||
|
||||
def can_validate_billing(role: str) -> bool:
|
||||
"""Transicionar billing_state — Spec 023 / FR-027-005 / FR-027-009."""
|
||||
return role in ("super_admin", "ops_lead", "finance", "sales_admin")
|
||||
|
||||
|
||||
def can_manage_billing(role: str) -> bool:
|
||||
return role in ("super_admin", "ops_lead")
|
||||
return can_validate_billing(role)
|
||||
|
||||
|
||||
def can_create_foss_order(role: str) -> bool:
|
||||
return role in (
|
||||
"super_admin",
|
||||
"ops_lead",
|
||||
"finance",
|
||||
"sales_admin",
|
||||
"sales_support",
|
||||
)
|
||||
|
||||
|
||||
def can_access_foss_admin(role: str) -> bool:
|
||||
return role in ("super_admin", "finance", "sales_admin")
|
||||
|
||||
|
||||
def can_access_openadmin(role: str) -> bool:
|
||||
return role in ("super_admin", "devops", "sales_admin")
|
||||
|
||||
|
||||
def can_openpanel_autologin(role: str) -> bool:
|
||||
return role in (
|
||||
"super_admin",
|
||||
"sales_admin",
|
||||
"sales_support",
|
||||
"marketing",
|
||||
"seo",
|
||||
"content_editor",
|
||||
"technician",
|
||||
)
|
||||
|
||||
|
||||
def can_openpanel_provision(role: str) -> bool:
|
||||
return role in ("super_admin", "devops", "sales_admin", "sales_support")
|
||||
|
||||
|
||||
def can_openpanel_delete(role: str) -> bool:
|
||||
return role in ("super_admin", "devops")
|
||||
|
||||
|
||||
def roles_meta() -> dict:
|
||||
"""Metadados para UI — labels e funções atribuíveis no cadastro."""
|
||||
return {
|
||||
"labels": ROLE_LABELS,
|
||||
"assignable": sorted(ASSIGNABLE_ROLES),
|
||||
"human": sorted(HUMAN_ROLES),
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue