myrmidon / python /src /server /auth /permissions.py
tek Atrust
chore(deploy): build monolithic server for Hugging Face
d5ef46f
Raw
History Blame Contribute Delete
4.53 kB
# python/src/server/auth/permissions.py
# --- Permission Scopes ---
# Task Management
TASK_CREATE = "task:create"
TASK_READ_OWN = "task:read:own"
TASK_READ_TEAM = "task:read:team"
TASK_READ_ALL = "task:read:all"
TASK_UPDATE_OWN = "task:update:own"
TASK_UPDATE_ALL = "task:update:all" # Admin override
# Agent Collaboration
AGENT_TRIGGER_DEV = "agent:trigger:dev" # DevBot
AGENT_TRIGGER_MKT = "agent:trigger:mkt" # MarketBot
AGENT_TRIGGER_KNOW = "agent:trigger:know" # Knowledge Agent
# Code/Content Approval
CODE_APPROVE = "code:approve"
CONTENT_PUBLISH = "content:publish"
# Business Intelligence
STATS_VIEW_OWN = "stats:view:own"
STATS_VIEW_TEAM = "stats:view:team"
STATS_VIEW_ALL = "stats:view:all"
LEADS_VIEW_ALL = "leads:view:all"
# Content Loop (Phase 4.6)
CONTENT_REJECT = "content:reject"
INFO_REQUEST = "info:request"
# System Management
USER_MANAGE = "user:manage" # Create user, change role
USER_MANAGE_TEAM = "user:manage:team" # Manage users in same department
MCP_MANAGE = "mcp:manage" # Configure tools
BRAND_ASSET_MANAGE = "brand:manage" # Manage logos, colors, assets
# --- Role Definition ---
ROLE_PERMISSIONS: dict[str, set[str]] = {
"system_admin": {
TASK_CREATE,
TASK_READ_OWN,
TASK_READ_TEAM,
TASK_READ_ALL,
TASK_UPDATE_OWN,
TASK_UPDATE_ALL,
AGENT_TRIGGER_DEV,
AGENT_TRIGGER_MKT,
AGENT_TRIGGER_KNOW,
CODE_APPROVE,
CONTENT_PUBLISH,
CONTENT_REJECT,
INFO_REQUEST,
STATS_VIEW_OWN,
STATS_VIEW_TEAM,
STATS_VIEW_ALL,
LEADS_VIEW_ALL,
USER_MANAGE,
MCP_MANAGE,
BRAND_ASSET_MANAGE,
USER_MANAGE_TEAM,
},
"admin": { # Alias for system_admin for backward compatibility
TASK_CREATE,
TASK_READ_OWN,
TASK_READ_TEAM,
TASK_READ_ALL,
TASK_UPDATE_OWN,
TASK_UPDATE_ALL,
AGENT_TRIGGER_DEV,
AGENT_TRIGGER_MKT,
AGENT_TRIGGER_KNOW,
CODE_APPROVE,
CONTENT_PUBLISH,
CONTENT_REJECT,
INFO_REQUEST,
STATS_VIEW_OWN,
STATS_VIEW_TEAM,
STATS_VIEW_ALL,
LEADS_VIEW_ALL,
USER_MANAGE,
MCP_MANAGE,
BRAND_ASSET_MANAGE,
USER_MANAGE_TEAM,
},
"manager": {
TASK_CREATE,
TASK_READ_TEAM,
TASK_UPDATE_OWN,
AGENT_TRIGGER_DEV,
AGENT_TRIGGER_MKT,
AGENT_TRIGGER_KNOW,
CODE_APPROVE,
CONTENT_PUBLISH,
CONTENT_REJECT,
INFO_REQUEST,
STATS_VIEW_TEAM,
LEADS_VIEW_ALL,
USER_MANAGE_TEAM,
MCP_MANAGE,
BRAND_ASSET_MANAGE,
},
"employee": { # Generic Employee
TASK_CREATE,
TASK_READ_OWN,
TASK_UPDATE_OWN,
AGENT_TRIGGER_KNOW,
STATS_VIEW_OWN,
},
"sales": {TASK_CREATE, TASK_READ_OWN, TASK_READ_TEAM, TASK_UPDATE_OWN, AGENT_TRIGGER_MKT, LEADS_VIEW_ALL},
"marketing": { # Bob
TASK_CREATE,
TASK_READ_OWN,
TASK_READ_TEAM,
TASK_UPDATE_OWN,
AGENT_TRIGGER_MKT,
AGENT_TRIGGER_KNOW,
STATS_VIEW_OWN,
LEADS_VIEW_ALL,
BRAND_ASSET_MANAGE,
INFO_REQUEST,
},
}
# --- All Permissions List (for UI Matrix) ---
ALL_PERMISSIONS = [
TASK_CREATE,
TASK_READ_TEAM,
TASK_READ_ALL,
TASK_UPDATE_ALL,
AGENT_TRIGGER_DEV,
AGENT_TRIGGER_MKT,
AGENT_TRIGGER_KNOW,
CODE_APPROVE,
CONTENT_PUBLISH,
CONTENT_REJECT,
INFO_REQUEST,
STATS_VIEW_TEAM,
STATS_VIEW_ALL,
LEADS_VIEW_ALL,
USER_MANAGE,
USER_MANAGE_TEAM,
MCP_MANAGE,
BRAND_ASSET_MANAGE,
]
def get_role_permissions(role: str) -> set[str]:
"""Returns the set of permissions for a given role (case-insensitive)."""
return ROLE_PERMISSIONS.get(role.lower(), set())
def has_permission(user: dict, permission: str) -> bool:
"""
Checks if a user has a specific permission.
Args:
user: User dictionary (usually from profiles table)
permission: The permission scope to check (e.g. TASK_CREATE)
"""
if not user:
return False
# 1. Check per-user overrides first (High priority)
overrides = user.get("permission_overrides") or {}
if permission in overrides:
return bool(overrides[permission])
# 2. Fallback to role-based permissions
user_role = user.get("role", "viewer").lower()
role_perms = get_role_permissions(user_role)
return permission in role_perms