1 """Helpers to deal with permissions."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from functools
import wraps
7 from typing
import cast
9 from .const
import SUBCAT_ALL
10 from .models
import PermissionLookup
11 from .types
import CategoryType, SubCategoryDict, ValueType
13 type LookupFunc = Callable[[PermissionLookup, SubCategoryDict, str], ValueType |
None]
14 type SubCatLookupType = dict[str, LookupFunc]
18 perm_lookup: PermissionLookup, lookup_dict: SubCategoryDict, object_id: str
20 """Look up permission for all."""
22 return cast(ValueType, lookup_dict)
26 policy: CategoryType, subcategories: SubCatLookupType, perm_lookup: PermissionLookup
27 ) -> Callable[[str, str], bool]:
28 """Compile policy into a function that tests policy.
30 Subcategories are mapping key -> lookup function, ordered by highest
36 def apply_policy_deny_all(entity_id: str, key: str) -> bool:
40 return apply_policy_deny_all
44 def apply_policy_allow_all(entity_id: str, key: str) -> bool:
48 return apply_policy_allow_all
50 assert isinstance(policy, dict)
52 funcs: list[Callable[[str, str], bool |
None]] = []
54 for key, lookup_func
in subcategories.items():
55 lookup_value = policy.get(key)
58 if isinstance(lookup_value, bool):
59 return lambda object_id, key:
True
61 if lookup_value
is not None:
68 def apply_policy_func(object_id: str, key: str) -> bool:
69 """Apply a single policy function."""
70 return func(object_id, key)
is True
72 return apply_policy_func
74 def apply_policy_funcs(object_id: str, key: str) -> bool:
75 """Apply several policy functions."""
77 if (result := func(object_id, key))
is not None:
81 return apply_policy_funcs
85 perm_lookup: PermissionLookup, lookup_func: LookupFunc, lookup_dict: SubCategoryDict
86 ) -> Callable[[str, str], bool |
None]:
87 """Generate a lookup function."""
89 def test_value(object_id: str, key: str) -> bool |
None:
90 """Test if permission is allowed based on the keys."""
91 schema: ValueType = lookup_func(perm_lookup, lookup_dict, object_id)
93 if schema
is None or isinstance(schema, bool):
96 assert isinstance(schema, dict)
98 return schema.get(key)
103 def test_all(policy: CategoryType, key: str) -> bool:
104 """Test if a policy has an ALL access for a specific key."""
105 if not isinstance(policy, dict):
108 all_policy = policy.get(SUBCAT_ALL)
110 if not isinstance(all_policy, dict):
111 return bool(all_policy)
113 return all_policy.get(key,
False)
Callable[[str, str], bool|None] _gen_dict_test_func(PermissionLookup perm_lookup, LookupFunc lookup_func, SubCategoryDict lookup_dict)
Callable[[str, str], bool] compile_policy(CategoryType policy, SubCatLookupType subcategories, PermissionLookup perm_lookup)
ValueType lookup_all(PermissionLookup perm_lookup, SubCategoryDict lookup_dict, str object_id)
bool test_all(CategoryType policy, str key)