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"], }, ]