Don't expose config or diagnostic entities to cloud (#57771)
parent
8b33aa3702
commit
0f2b5ea28e
|
@ -15,9 +15,14 @@ from homeassistant.components.alexa import (
|
|||
errors as alexa_errors,
|
||||
state_report as alexa_state_report,
|
||||
)
|
||||
from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES, HTTP_BAD_REQUEST
|
||||
from homeassistant.const import (
|
||||
CLOUD_NEVER_EXPOSED_ENTITIES,
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
HTTP_BAD_REQUEST,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback, split_entity_id
|
||||
from homeassistant.helpers import entity_registry, start
|
||||
from homeassistant.helpers import entity_registry as er, start
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
@ -110,7 +115,7 @@ class AlexaConfig(alexa_config.AbstractConfig):
|
|||
|
||||
self._prefs.async_listen_updates(self._async_prefs_updated)
|
||||
self.hass.bus.async_listen(
|
||||
entity_registry.EVENT_ENTITY_REGISTRY_UPDATED,
|
||||
er.EVENT_ENTITY_REGISTRY_UPDATED,
|
||||
self._handle_entity_registry_updated,
|
||||
)
|
||||
|
||||
|
@ -128,13 +133,23 @@ class AlexaConfig(alexa_config.AbstractConfig):
|
|||
if entity_expose is not None:
|
||||
return entity_expose
|
||||
|
||||
entity_registry = er.async_get(self.hass)
|
||||
registry_entry = entity_registry.async_get(entity_id)
|
||||
if registry_entry:
|
||||
auxiliary_entity = registry_entry.entity_category in (
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
)
|
||||
else:
|
||||
auxiliary_entity = False
|
||||
|
||||
default_expose = self._prefs.alexa_default_expose
|
||||
|
||||
# Backwards compat
|
||||
if default_expose is None:
|
||||
return True
|
||||
return not auxiliary_entity
|
||||
|
||||
return split_entity_id(entity_id)[0] in default_expose
|
||||
return not auxiliary_entity and split_entity_id(entity_id)[0] in default_expose
|
||||
|
||||
@callback
|
||||
def async_invalidate_access_token(self):
|
||||
|
@ -340,7 +355,7 @@ class AlexaConfig(alexa_config.AbstractConfig):
|
|||
elif action == "remove":
|
||||
to_remove.append(entity_id)
|
||||
elif action == "update" and bool(
|
||||
set(event.data["changes"]) & entity_registry.ENTITY_DESCRIBING_ATTRIBUTES
|
||||
set(event.data["changes"]) & er.ENTITY_DESCRIBING_ATTRIBUTES
|
||||
):
|
||||
to_update.append(entity_id)
|
||||
if "old_entity_id" in event.data:
|
||||
|
|
|
@ -7,9 +7,14 @@ from hass_nabucasa.google_report_state import ErrorResponse
|
|||
|
||||
from homeassistant.components.google_assistant.const import DOMAIN as GOOGLE_DOMAIN
|
||||
from homeassistant.components.google_assistant.helpers import AbstractConfig
|
||||
from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES, HTTP_OK
|
||||
from homeassistant.const import (
|
||||
CLOUD_NEVER_EXPOSED_ENTITIES,
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
HTTP_OK,
|
||||
)
|
||||
from homeassistant.core import CoreState, split_entity_id
|
||||
from homeassistant.helpers import entity_registry, start
|
||||
from homeassistant.helpers import entity_registry as er, start
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .const import (
|
||||
|
@ -104,7 +109,7 @@ class CloudGoogleConfig(AbstractConfig):
|
|||
self._prefs.async_listen_updates(self._async_prefs_updated)
|
||||
|
||||
self.hass.bus.async_listen(
|
||||
entity_registry.EVENT_ENTITY_REGISTRY_UPDATED,
|
||||
er.EVENT_ENTITY_REGISTRY_UPDATED,
|
||||
self._handle_entity_registry_updated,
|
||||
)
|
||||
|
||||
|
@ -126,13 +131,23 @@ class CloudGoogleConfig(AbstractConfig):
|
|||
if entity_expose is not None:
|
||||
return entity_expose
|
||||
|
||||
entity_registry = er.async_get(self.hass)
|
||||
registry_entry = entity_registry.async_get(entity_id)
|
||||
if registry_entry:
|
||||
auxiliary_entity = registry_entry.entity_category in (
|
||||
ENTITY_CATEGORY_CONFIG,
|
||||
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
)
|
||||
else:
|
||||
auxiliary_entity = False
|
||||
|
||||
default_expose = self._prefs.google_default_expose
|
||||
|
||||
# Backwards compat
|
||||
if default_expose is None:
|
||||
return True
|
||||
return not auxiliary_entity
|
||||
|
||||
return split_entity_id(entity_id)[0] in default_expose
|
||||
return not auxiliary_entity and split_entity_id(entity_id)[0] in default_expose
|
||||
|
||||
@property
|
||||
def agent_user_id(self):
|
||||
|
@ -215,7 +230,7 @@ class CloudGoogleConfig(AbstractConfig):
|
|||
|
||||
# Only consider entity registry updates if info relevant for Google has changed
|
||||
if event.data["action"] == "update" and not bool(
|
||||
set(event.data["changes"]) & entity_registry.ENTITY_DESCRIBING_ATTRIBUTES
|
||||
set(event.data["changes"]) & er.ENTITY_DESCRIBING_ATTRIBUTES
|
||||
):
|
||||
return
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ from homeassistant.components.cloud import ALEXA_SCHEMA, alexa_config
|
|||
from homeassistant.helpers.entity_registry import EVENT_ENTITY_REGISTRY_UPDATED
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
from tests.common import async_fire_time_changed, mock_registry
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
@ -19,6 +19,23 @@ def cloud_stub():
|
|||
|
||||
async def test_alexa_config_expose_entity_prefs(hass, cloud_prefs, cloud_stub):
|
||||
"""Test Alexa config should expose using prefs."""
|
||||
entity_registry = mock_registry(hass)
|
||||
|
||||
entity_entry1 = entity_registry.async_get_or_create(
|
||||
"switch",
|
||||
"test",
|
||||
"switch_config_id",
|
||||
suggested_object_id="config_switch",
|
||||
entity_category="config",
|
||||
)
|
||||
entity_entry2 = entity_registry.async_get_or_create(
|
||||
"switch",
|
||||
"test",
|
||||
"switch_diagnostic_id",
|
||||
suggested_object_id="diagnostic_switch",
|
||||
entity_category="diagnostic",
|
||||
)
|
||||
|
||||
entity_conf = {"should_expose": False}
|
||||
await cloud_prefs.async_update(
|
||||
alexa_entity_configs={"light.kitchen": entity_conf},
|
||||
|
@ -31,11 +48,20 @@ async def test_alexa_config_expose_entity_prefs(hass, cloud_prefs, cloud_stub):
|
|||
await conf.async_initialize()
|
||||
|
||||
assert not conf.should_expose("light.kitchen")
|
||||
assert not conf.should_expose(entity_entry1.entity_id)
|
||||
assert not conf.should_expose(entity_entry2.entity_id)
|
||||
|
||||
entity_conf["should_expose"] = True
|
||||
assert conf.should_expose("light.kitchen")
|
||||
# config and diagnostic entities should not be exposed
|
||||
assert not conf.should_expose(entity_entry1.entity_id)
|
||||
assert not conf.should_expose(entity_entry2.entity_id)
|
||||
|
||||
entity_conf["should_expose"] = None
|
||||
assert conf.should_expose("light.kitchen")
|
||||
# config and diagnostic entities should not be exposed
|
||||
assert not conf.should_expose(entity_entry1.entity_id)
|
||||
assert not conf.should_expose(entity_entry2.entity_id)
|
||||
|
||||
assert "alexa" not in hass.config.components
|
||||
await cloud_prefs.async_update(
|
||||
|
|
|
@ -11,7 +11,7 @@ from homeassistant.core import CoreState, State
|
|||
from homeassistant.helpers.entity_registry import EVENT_ENTITY_REGISTRY_UPDATED
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
from tests.common import async_fire_time_changed, mock_registry
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -215,8 +215,25 @@ async def test_sync_google_on_home_assistant_start(hass, mock_cloud_login, cloud
|
|||
assert len(mock_sync.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_google_config_expose_entity_prefs(mock_conf, cloud_prefs):
|
||||
async def test_google_config_expose_entity_prefs(hass, mock_conf, cloud_prefs):
|
||||
"""Test Google config should expose using prefs."""
|
||||
entity_registry = mock_registry(hass)
|
||||
|
||||
entity_entry1 = entity_registry.async_get_or_create(
|
||||
"switch",
|
||||
"test",
|
||||
"switch_config_id",
|
||||
suggested_object_id="config_switch",
|
||||
entity_category="config",
|
||||
)
|
||||
entity_entry2 = entity_registry.async_get_or_create(
|
||||
"switch",
|
||||
"test",
|
||||
"switch_diagnostic_id",
|
||||
suggested_object_id="diagnostic_switch",
|
||||
entity_category="diagnostic",
|
||||
)
|
||||
|
||||
entity_conf = {"should_expose": False}
|
||||
await cloud_prefs.async_update(
|
||||
google_entity_configs={"light.kitchen": entity_conf},
|
||||
|
@ -224,13 +241,24 @@ async def test_google_config_expose_entity_prefs(mock_conf, cloud_prefs):
|
|||
)
|
||||
|
||||
state = State("light.kitchen", "on")
|
||||
state_config = State(entity_entry1.entity_id, "on")
|
||||
state_diagnostic = State(entity_entry2.entity_id, "on")
|
||||
|
||||
assert not mock_conf.should_expose(state)
|
||||
assert not mock_conf.should_expose(state_config)
|
||||
assert not mock_conf.should_expose(state_diagnostic)
|
||||
|
||||
entity_conf["should_expose"] = True
|
||||
assert mock_conf.should_expose(state)
|
||||
# config and diagnostic entities should not be exposed
|
||||
assert not mock_conf.should_expose(state_config)
|
||||
assert not mock_conf.should_expose(state_diagnostic)
|
||||
|
||||
entity_conf["should_expose"] = None
|
||||
assert mock_conf.should_expose(state)
|
||||
# config and diagnostic entities should not be exposed
|
||||
assert not mock_conf.should_expose(state_config)
|
||||
assert not mock_conf.should_expose(state_diagnostic)
|
||||
|
||||
await cloud_prefs.async_update(
|
||||
google_default_expose=["sensor"],
|
||||
|
|
Loading…
Reference in New Issue