Use faster is_admin check for websocket state and event subscriptions (#107621)

This commit is contained in:
J. Nick Koston 2024-01-13 10:42:41 -10:00 committed by GitHub
parent 5e79a0e583
commit 6ada825805
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 7 deletions

View file

@ -113,9 +113,11 @@ def _forward_events_check_permissions(
# We have to lookup the permissions again because the user might have # We have to lookup the permissions again because the user might have
# changed since the subscription was created. # changed since the subscription was created.
permissions = user.permissions permissions = user.permissions
if not permissions.access_all_entities( if (
POLICY_READ not user.is_admin
) and not permissions.check_entity(event.data["entity_id"], POLICY_READ): and not permissions.access_all_entities(POLICY_READ)
and not permissions.check_entity(event.data["entity_id"], POLICY_READ)
):
return return
send_message(messages.cached_event_message(msg_id, event)) send_message(messages.cached_event_message(msg_id, event))
@ -306,7 +308,8 @@ async def handle_call_service(
def _async_get_allowed_states( def _async_get_allowed_states(
hass: HomeAssistant, connection: ActiveConnection hass: HomeAssistant, connection: ActiveConnection
) -> list[State]: ) -> list[State]:
if connection.user.permissions.access_all_entities(POLICY_READ): user = connection.user
if user.is_admin or user.permissions.access_all_entities(POLICY_READ):
return hass.states.async_all() return hass.states.async_all()
entity_perm = connection.user.permissions.check_entity entity_perm = connection.user.permissions.check_entity
return [ return [
@ -372,9 +375,11 @@ def _forward_entity_changes(
# We have to lookup the permissions again because the user might have # We have to lookup the permissions again because the user might have
# changed since the subscription was created. # changed since the subscription was created.
permissions = user.permissions permissions = user.permissions
if not permissions.access_all_entities( if (
POLICY_READ not user.is_admin
) and not permissions.check_entity(event.data["entity_id"], POLICY_READ): and not permissions.access_all_entities(POLICY_READ)
and not permissions.check_entity(event.data["entity_id"], POLICY_READ)
):
return return
send_message(messages.cached_state_diff_message(msg_id, event)) send_message(messages.cached_state_diff_message(msg_id, event))

View file

@ -804,6 +804,7 @@ async def test_states_filters_visible(
hass: HomeAssistant, hass_admin_user: MockUser, websocket_client hass: HomeAssistant, hass_admin_user: MockUser, websocket_client
) -> None: ) -> None:
"""Test we only get entities that we're allowed to see.""" """Test we only get entities that we're allowed to see."""
hass_admin_user.groups = []
hass_admin_user.mock_policy({"entities": {"entity_ids": {"test.entity": True}}}) hass_admin_user.mock_policy({"entities": {"entity_ids": {"test.entity": True}}})
hass.states.async_set("test.entity", "hello") hass.states.async_set("test.entity", "hello")
hass.states.async_set("test.not_visible_entity", "invisible") hass.states.async_set("test.not_visible_entity", "invisible")
@ -1048,6 +1049,7 @@ async def test_subscribe_unsubscribe_entities(
} }
hass_admin_user.groups = [] hass_admin_user.groups = []
hass_admin_user.mock_policy({"entities": {"entity_ids": {"light.permitted": True}}}) hass_admin_user.mock_policy({"entities": {"entity_ids": {"light.permitted": True}}})
assert not hass_admin_user.is_admin
await websocket_client.send_json({"id": 7, "type": "subscribe_entities"}) await websocket_client.send_json({"id": 7, "type": "subscribe_entities"})