Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from typing import Optional, Set | |
| # Role hierarchy used across MCP server and FastAPI routes | |
| VALID_ROLES = ("viewer", "editor", "admin", "owner") | |
| ROLE_ORDER = {role: idx for idx, role in enumerate(VALID_ROLES)} | |
| # Permission matrix defining which roles can perform which enterprise actions | |
| PERMISSIONS: dict[str, Set[str]] = { | |
| "manage_rules": {"owner", "admin"}, | |
| "ingest_documents": {"owner", "admin", "editor"}, | |
| "delete_documents": {"owner", "admin"}, | |
| "view_analytics": {"viewer", "editor", "admin", "owner"}, # All roles can view analytics | |
| } | |
| # Mapping of MCP tool names to enterprise actions | |
| TOOL_PERMISSION_MAP: dict[str, str] = { | |
| "admin.addRule": "manage_rules", | |
| "admin.deleteRule": "manage_rules", | |
| "rag.ingest": "ingest_documents", | |
| "rag.delete": "delete_documents", | |
| } | |
| def normalize_role(raw_value: Optional[str]) -> str: | |
| """ | |
| Normalize an inbound role string. Defaults to 'viewer' when undefined or invalid. | |
| """ | |
| if not raw_value: | |
| return "viewer" | |
| value = raw_value.strip().lower() | |
| if value not in VALID_ROLES: | |
| return "viewer" | |
| return value | |
| def allowed_roles_for(action: str) -> Set[str]: | |
| """ | |
| Return the set of roles that can execute the given action. | |
| If the action is unknown, all roles are allowed. | |
| """ | |
| return PERMISSIONS.get(action, set(VALID_ROLES)) | |
| def role_allows(role: str, action: str) -> bool: | |
| """ | |
| Check whether the supplied role has permission for the action. | |
| Unknown actions default to allow-all to avoid accidental lockouts. | |
| """ | |
| allowed = allowed_roles_for(action) | |
| return role in allowed if allowed else True | |
| def describe_allowed_roles(action: str) -> str: | |
| """ | |
| Return a human-friendly description of which roles are allowed for an action. | |
| """ | |
| allowed = sorted(allowed_roles_for(action), key=lambda r: ROLE_ORDER.get(r, 0)) | |
| return ", ".join(allowed) | |
| def get_required_action_for_tool(tool_name: str) -> Optional[str]: | |
| """ | |
| Look up the enterprise action that applies to a tool name, if any. | |
| """ | |
| return TOOL_PERMISSION_MAP.get(tool_name) | |