1 """Entity permissions."""
3 from __future__
import annotations
5 from collections
import OrderedDict
6 from collections.abc
import Callable
8 import voluptuous
as vol
10 from .const
import POLICY_CONTROL, POLICY_EDIT, POLICY_READ, SUBCAT_ALL
11 from .models
import PermissionLookup
12 from .types
import CategoryType, SubCategoryDict, ValueType
13 from .util
import SubCatLookupType, compile_policy, lookup_all
15 SINGLE_ENTITY_SCHEMA = vol.Any(
19 vol.Optional(POLICY_READ):
True,
20 vol.Optional(POLICY_CONTROL):
True,
21 vol.Optional(POLICY_EDIT):
True,
26 ENTITY_DOMAINS =
"domains"
27 ENTITY_AREAS =
"area_ids"
28 ENTITY_DEVICE_IDS =
"device_ids"
29 ENTITY_ENTITY_IDS =
"entity_ids"
31 ENTITY_VALUES_SCHEMA = vol.Any(
True, vol.Schema({str: SINGLE_ENTITY_SCHEMA}))
33 ENTITY_POLICY_SCHEMA = vol.Any(
37 vol.Optional(SUBCAT_ALL): SINGLE_ENTITY_SCHEMA,
38 vol.Optional(ENTITY_AREAS): ENTITY_VALUES_SCHEMA,
39 vol.Optional(ENTITY_DEVICE_IDS): ENTITY_VALUES_SCHEMA,
40 vol.Optional(ENTITY_DOMAINS): ENTITY_VALUES_SCHEMA,
41 vol.Optional(ENTITY_ENTITY_IDS): ENTITY_VALUES_SCHEMA,
48 perm_lookup: PermissionLookup, domains_dict: SubCategoryDict, entity_id: str
49 ) -> ValueType |
None:
50 """Look up entity permissions by domain."""
51 return domains_dict.get(entity_id.partition(
".")[0])
55 perm_lookup: PermissionLookup, area_dict: SubCategoryDict, entity_id: str
56 ) -> ValueType |
None:
57 """Look up entity permissions by area."""
58 entity_entry = perm_lookup.entity_registry.async_get(entity_id)
60 if entity_entry
is None or entity_entry.device_id
is None:
63 device_entry = perm_lookup.device_registry.async_get(entity_entry.device_id)
65 if device_entry
is None or device_entry.area_id
is None:
68 return area_dict.get(device_entry.area_id)
72 perm_lookup: PermissionLookup, devices_dict: SubCategoryDict, entity_id: str
73 ) -> ValueType |
None:
74 """Look up entity permissions by device."""
75 entity_entry = perm_lookup.entity_registry.async_get(entity_id)
77 if entity_entry
is None or entity_entry.device_id
is None:
80 return devices_dict.get(entity_entry.device_id)
84 perm_lookup: PermissionLookup, entities_dict: SubCategoryDict, entity_id: str
85 ) -> ValueType |
None:
86 """Look up entity permission by entity id."""
87 return entities_dict.get(entity_id)
91 policy: CategoryType, perm_lookup: PermissionLookup
92 ) -> Callable[[str, str], bool]:
93 """Compile policy into a function that tests policy."""
94 subcategories: SubCatLookupType = OrderedDict()
95 subcategories[ENTITY_ENTITY_IDS] = _lookup_entity_id
96 subcategories[ENTITY_DEVICE_IDS] = _lookup_device
97 subcategories[ENTITY_AREAS] = _lookup_area
98 subcategories[ENTITY_DOMAINS] = _lookup_domain
99 subcategories[SUBCAT_ALL] = lookup_all
ValueType|None _lookup_domain(PermissionLookup perm_lookup, SubCategoryDict domains_dict, str entity_id)
ValueType|None _lookup_entity_id(PermissionLookup perm_lookup, SubCategoryDict entities_dict, str entity_id)
ValueType|None _lookup_area(PermissionLookup perm_lookup, SubCategoryDict area_dict, str entity_id)
Callable[[str, str], bool] compile_entities(CategoryType policy, PermissionLookup perm_lookup)
ValueType|None _lookup_device(PermissionLookup perm_lookup, SubCategoryDict devices_dict, str entity_id)
Callable[[str, str], bool] compile_policy(CategoryType policy, SubCatLookupType subcategories, PermissionLookup perm_lookup)