ligbox-ops-platform/projects/ops-desk/legacy-app/permissions.py
Ligbox Spec Hub 821675ab4a Reorganize monorepo into projects/wizard, ops-desk, finance
Specs stay at repo root (cross-VM). Move deploy and code into logical
projects with README per domain, updated manifest.yaml, and symlinks at
legacy paths for VM122 backward compatibility.
2026-06-19 18:55:03 +00:00

273 lines
6.4 KiB
Python

"""RBAC helpers for Ligbox Ops Desk — Spec 003 + 027."""
from __future__ import annotations
# Ops (Spec 003)
OPS_ROLES = frozenset({"super_admin", "ops_lead", "technician", "noc"})
# 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 HUMAN_ROLES
def can_patch_ticket(role: str, ticket: dict, username: str) -> bool:
if role in ("super_admin", "ops_lead"):
return True
if role == "technician":
assignee = ticket.get("assigned_to")
return assignee is None or assignee == username
return False
def can_assign_ticket(role: str, assignee: str | None, username: str) -> bool:
if role in ("super_admin", "ops_lead"):
return True
if role == "technician":
return assignee in (None, username)
return False
def can_run_audit(role: str) -> bool:
return role in ("super_admin", "ops_lead")
def can_read_audit_overview(role: str) -> bool:
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",
"developer",
"security_analyst",
"agentic_operator",
)
def can_read_cloudflare_dns(role: str) -> bool:
return role in (
"super_admin",
"ops_lead",
"technician",
"noc",
"seo",
"devops",
"developer",
)
def can_read_funnel(role: str) -> bool:
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",
"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")
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",
"sales_admin",
"sales_support",
"marketing",
"seo",
)
def can_read_assist(role: str) -> bool:
return role in ("super_admin", "ops_lead", "technician", "sales_admin", "sales_support")
def can_assist_takeover(role: str) -> bool:
return role in ("super_admin", "ops_lead", "technician")
def can_assist_handoff(role: str, username: str) -> bool:
return role in ("super_admin", "ops_lead", "technician")
def can_manage_users(role: str) -> bool:
return role == "super_admin"
def can_manage_vm112_domains(role: str) -> bool:
"""Admin Desk — domínios orquestrados VM112 (Spec 017)."""
return role in ("super_admin", "ops_lead", "devops")
def should_mask_sensitive(role: str) -> bool:
return role in ("noc", "sales_support")
def can_read_migration(role: str) -> bool:
return role in ("super_admin", "ops_lead", "technician", "noc", "devops")
def can_manage_migration(role: str) -> bool:
return role in ("super_admin", "ops_lead", "technician")
def can_read_billing(role: str) -> bool:
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 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 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),
}