Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from typing import Optional | |
| def find_role(roles: list[dict], name: str) -> Optional[dict]: | |
| """Look up a role by name. Returns None if not found.""" | |
| return next((role for role in roles if role["name"] == name), None) | |
| def has_direct_permission(role: dict, resource: str, action: str) -> bool: | |
| """Check if role has the permission directly without inheritance traversal.""" | |
| return any( | |
| permission["resource"] == resource and permission["action"] == action | |
| for permission in role.get("permissions", []) | |
| ) | |
| def can_access( | |
| roles: list[dict], | |
| role_name: str, | |
| resource: str, | |
| action: str, | |
| depth: int = 5, | |
| ) -> bool: | |
| """Check if a role can access a resource/action pair using bounded inheritance.""" | |
| if depth == 0: | |
| return False | |
| role = find_role(roles, role_name) | |
| if role is None: | |
| return False | |
| if has_direct_permission(role, resource, action): | |
| return True | |
| return any( | |
| can_access(roles, parent_name, resource, action, depth - 1) | |
| for parent_name in role.get("inherits", []) | |
| ) | |
| EXAMPLE_ROLES = [ | |
| { | |
| "name": "viewer", | |
| "permissions": [{"resource": "reports", "action": "read"}], | |
| "inherits": [], | |
| }, | |
| { | |
| "name": "editor", | |
| "permissions": [{"resource": "reports", "action": "write"}], | |
| "inherits": ["viewer"], | |
| }, | |
| { | |
| "name": "admin", | |
| "permissions": [{"resource": "billing", "action": "write"}], | |
| "inherits": ["editor"], | |
| }, | |
| ] | |