Home Assistant Unofficial Reference 2024.12.1
entities.py
Go to the documentation of this file.
1 """Entity permissions."""
2 
3 from __future__ import annotations
4 
5 from collections import OrderedDict
6 from collections.abc import Callable
7 
8 import voluptuous as vol
9 
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
14 
15 SINGLE_ENTITY_SCHEMA = vol.Any(
16  True,
17  vol.Schema(
18  {
19  vol.Optional(POLICY_READ): True,
20  vol.Optional(POLICY_CONTROL): True,
21  vol.Optional(POLICY_EDIT): True,
22  }
23  ),
24 )
25 
26 ENTITY_DOMAINS = "domains"
27 ENTITY_AREAS = "area_ids"
28 ENTITY_DEVICE_IDS = "device_ids"
29 ENTITY_ENTITY_IDS = "entity_ids"
30 
31 ENTITY_VALUES_SCHEMA = vol.Any(True, vol.Schema({str: SINGLE_ENTITY_SCHEMA}))
32 
33 ENTITY_POLICY_SCHEMA = vol.Any(
34  True,
35  vol.Schema(
36  {
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,
42  }
43  ),
44 )
45 
46 
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])
52 
53 
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)
59 
60  if entity_entry is None or entity_entry.device_id is None:
61  return None
62 
63  device_entry = perm_lookup.device_registry.async_get(entity_entry.device_id)
64 
65  if device_entry is None or device_entry.area_id is None:
66  return None
67 
68  return area_dict.get(device_entry.area_id)
69 
70 
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)
76 
77  if entity_entry is None or entity_entry.device_id is None:
78  return None
79 
80  return devices_dict.get(entity_entry.device_id)
81 
82 
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)
88 
89 
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
100 
101  return compile_policy(policy, subcategories, perm_lookup)
ValueType|None _lookup_domain(PermissionLookup perm_lookup, SubCategoryDict domains_dict, str entity_id)
Definition: entities.py:49
ValueType|None _lookup_entity_id(PermissionLookup perm_lookup, SubCategoryDict entities_dict, str entity_id)
Definition: entities.py:85
ValueType|None _lookup_area(PermissionLookup perm_lookup, SubCategoryDict area_dict, str entity_id)
Definition: entities.py:56
Callable[[str, str], bool] compile_entities(CategoryType policy, PermissionLookup perm_lookup)
Definition: entities.py:92
ValueType|None _lookup_device(PermissionLookup perm_lookup, SubCategoryDict devices_dict, str entity_id)
Definition: entities.py:73
Callable[[str, str], bool] compile_policy(CategoryType policy, SubCatLookupType subcategories, PermissionLookup perm_lookup)
Definition: util.py:27