Spaces:
Sleeping
Sleeping
File size: 1,563 Bytes
16f1328 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 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"],
},
]
|