mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Google assistant: disconnect user agent when not found in google (#48233)
This commit is contained in:
parent
9f8b697e64
commit
b1d0b37d2c
@ -6,11 +6,7 @@ from hass_nabucasa import Cloud, cloud_api
|
|||||||
from hass_nabucasa.google_report_state import ErrorResponse
|
from hass_nabucasa.google_report_state import ErrorResponse
|
||||||
|
|
||||||
from homeassistant.components.google_assistant.helpers import AbstractConfig
|
from homeassistant.components.google_assistant.helpers import AbstractConfig
|
||||||
from homeassistant.const import (
|
from homeassistant.const import CLOUD_NEVER_EXPOSED_ENTITIES, HTTP_OK
|
||||||
CLOUD_NEVER_EXPOSED_ENTITIES,
|
|
||||||
EVENT_HOMEASSISTANT_STARTED,
|
|
||||||
HTTP_OK,
|
|
||||||
)
|
|
||||||
from homeassistant.core import CoreState, split_entity_id
|
from homeassistant.core import CoreState, split_entity_id
|
||||||
from homeassistant.helpers import entity_registry
|
from homeassistant.helpers import entity_registry
|
||||||
|
|
||||||
@ -87,8 +83,15 @@ class CloudGoogleConfig(AbstractConfig):
|
|||||||
async def async_initialize(self):
|
async def async_initialize(self):
|
||||||
"""Perform async initialization of config."""
|
"""Perform async initialization of config."""
|
||||||
await super().async_initialize()
|
await super().async_initialize()
|
||||||
# Remove bad data that was there until 0.103.6 - Jan 6, 2020
|
|
||||||
self._store.pop_agent_user_id(self._user)
|
# Remove old/wrong user agent ids
|
||||||
|
remove_agent_user_ids = []
|
||||||
|
for agent_user_id in self._store.agent_user_ids:
|
||||||
|
if agent_user_id != self.agent_user_id:
|
||||||
|
remove_agent_user_ids.append(agent_user_id)
|
||||||
|
|
||||||
|
for agent_user_id in remove_agent_user_ids:
|
||||||
|
await self.async_disconnect_agent_user(agent_user_id)
|
||||||
|
|
||||||
self._prefs.async_listen_updates(self._async_prefs_updated)
|
self._prefs.async_listen_updates(self._async_prefs_updated)
|
||||||
|
|
||||||
@ -198,17 +201,7 @@ class CloudGoogleConfig(AbstractConfig):
|
|||||||
if not self._should_expose_entity_id(entity_id):
|
if not self._should_expose_entity_id(entity_id):
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.hass.state == CoreState.running:
|
if self.hass.state != CoreState.running:
|
||||||
self.async_schedule_google_sync_all()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._sync_on_started:
|
self.async_schedule_google_sync_all()
|
||||||
return
|
|
||||||
|
|
||||||
self._sync_on_started = True
|
|
||||||
|
|
||||||
async def sync_google(_):
|
|
||||||
"""Sync entities to Google."""
|
|
||||||
await self.async_sync_entities_all()
|
|
||||||
|
|
||||||
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, sync_google)
|
|
||||||
|
@ -15,9 +15,10 @@ from homeassistant.const import (
|
|||||||
ATTR_SUPPORTED_FEATURES,
|
ATTR_SUPPORTED_FEATURES,
|
||||||
CLOUD_NEVER_EXPOSED_ENTITIES,
|
CLOUD_NEVER_EXPOSED_ENTITIES,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
|
EVENT_HOMEASSISTANT_STARTED,
|
||||||
STATE_UNAVAILABLE,
|
STATE_UNAVAILABLE,
|
||||||
)
|
)
|
||||||
from homeassistant.core import Context, HomeAssistant, State, callback
|
from homeassistant.core import Context, CoreState, HomeAssistant, State, callback
|
||||||
from homeassistant.helpers.area_registry import AreaEntry
|
from homeassistant.helpers.area_registry import AreaEntry
|
||||||
from homeassistant.helpers.device_registry import DeviceEntry
|
from homeassistant.helpers.device_registry import DeviceEntry
|
||||||
from homeassistant.helpers.entity_registry import RegistryEntry
|
from homeassistant.helpers.entity_registry import RegistryEntry
|
||||||
@ -104,6 +105,16 @@ class AbstractConfig(ABC):
|
|||||||
self._store = GoogleConfigStore(self.hass)
|
self._store = GoogleConfigStore(self.hass)
|
||||||
await self._store.async_load()
|
await self._store.async_load()
|
||||||
|
|
||||||
|
if self.hass.state == CoreState.running:
|
||||||
|
await self.async_sync_entities_all()
|
||||||
|
return
|
||||||
|
|
||||||
|
async def sync_google(_):
|
||||||
|
"""Sync entities to Google."""
|
||||||
|
await self.async_sync_entities_all()
|
||||||
|
|
||||||
|
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, sync_google)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def enabled(self):
|
def enabled(self):
|
||||||
"""Return if Google is enabled."""
|
"""Return if Google is enabled."""
|
||||||
@ -193,7 +204,10 @@ class AbstractConfig(ABC):
|
|||||||
"""Sync all entities to Google."""
|
"""Sync all entities to Google."""
|
||||||
# Remove any pending sync
|
# Remove any pending sync
|
||||||
self._google_sync_unsub.pop(agent_user_id, lambda: None)()
|
self._google_sync_unsub.pop(agent_user_id, lambda: None)()
|
||||||
return await self._async_request_sync_devices(agent_user_id)
|
status = await self._async_request_sync_devices(agent_user_id)
|
||||||
|
if status == 404:
|
||||||
|
await self.async_disconnect_agent_user(agent_user_id)
|
||||||
|
return status
|
||||||
|
|
||||||
async def async_sync_entities_all(self):
|
async def async_sync_entities_all(self):
|
||||||
"""Sync all entities to Google for all registered agents."""
|
"""Sync all entities to Google for all registered agents."""
|
||||||
|
@ -135,11 +135,12 @@ class GoogleConfig(AbstractConfig):
|
|||||||
|
|
||||||
async def _async_request_sync_devices(self, agent_user_id: str):
|
async def _async_request_sync_devices(self, agent_user_id: str):
|
||||||
if CONF_SERVICE_ACCOUNT in self._config:
|
if CONF_SERVICE_ACCOUNT in self._config:
|
||||||
await self.async_call_homegraph_api(
|
return await self.async_call_homegraph_api(
|
||||||
REQUEST_SYNC_BASE_URL, {"agentUserId": agent_user_id}
|
REQUEST_SYNC_BASE_URL, {"agentUserId": agent_user_id}
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
_LOGGER.error("No configuration for request_sync available")
|
_LOGGER.error("No configuration for request_sync available")
|
||||||
|
return HTTP_INTERNAL_SERVER_ERROR
|
||||||
|
|
||||||
async def _async_update_token(self, force=False):
|
async def _async_update_token(self, force=False):
|
||||||
if CONF_SERVICE_ACCOUNT not in self._config:
|
if CONF_SERVICE_ACCOUNT not in self._config:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""Test the Cloud Google Config."""
|
"""Test the Cloud Google Config."""
|
||||||
from unittest.mock import AsyncMock, Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -41,21 +41,19 @@ async def test_google_update_report_state(mock_conf, hass, cloud_prefs):
|
|||||||
assert len(mock_report_state.mock_calls) == 1
|
assert len(mock_report_state.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_sync_entities(aioclient_mock, hass, cloud_prefs):
|
async def test_sync_entities(mock_conf, hass, cloud_prefs):
|
||||||
"""Test sync devices."""
|
"""Test sync devices."""
|
||||||
config = CloudGoogleConfig(
|
await mock_conf.async_initialize()
|
||||||
hass,
|
await mock_conf.async_connect_agent_user("mock-user-id")
|
||||||
GACTIONS_SCHEMA({}),
|
|
||||||
"mock-user-id",
|
assert len(mock_conf._store.agent_user_ids) == 1
|
||||||
cloud_prefs,
|
|
||||||
Mock(auth=Mock(async_check_token=AsyncMock())),
|
|
||||||
)
|
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"hass_nabucasa.cloud_api.async_google_actions_request_sync",
|
"hass_nabucasa.cloud_api.async_google_actions_request_sync",
|
||||||
return_value=Mock(status=HTTP_NOT_FOUND),
|
return_value=Mock(status=HTTP_NOT_FOUND),
|
||||||
) as mock_request_sync:
|
) as mock_request_sync:
|
||||||
assert await config.async_sync_entities("user") == HTTP_NOT_FOUND
|
assert await mock_conf.async_sync_entities("mock-user-id") == HTTP_NOT_FOUND
|
||||||
|
assert len(mock_conf._store.agent_user_ids) == 0
|
||||||
assert len(mock_request_sync.mock_calls) == 1
|
assert len(mock_request_sync.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
@ -165,7 +163,29 @@ async def test_google_entity_registry_sync(hass, mock_cloud_login, cloud_prefs):
|
|||||||
|
|
||||||
assert len(mock_sync.mock_calls) == 3
|
assert len(mock_sync.mock_calls) == 3
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sync_google_when_started(hass, mock_cloud_login, cloud_prefs):
|
||||||
|
"""Test Google config syncs on init."""
|
||||||
|
config = CloudGoogleConfig(
|
||||||
|
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||||
|
)
|
||||||
with patch.object(config, "async_sync_entities_all") as mock_sync:
|
with patch.object(config, "async_sync_entities_all") as mock_sync:
|
||||||
|
await config.async_initialize()
|
||||||
|
await config.async_connect_agent_user("mock-user-id")
|
||||||
|
assert len(mock_sync.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sync_google_on_home_assistant_start(hass, mock_cloud_login, cloud_prefs):
|
||||||
|
"""Test Google config syncs when home assistant started."""
|
||||||
|
config = CloudGoogleConfig(
|
||||||
|
hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"]
|
||||||
|
)
|
||||||
|
hass.state = CoreState.starting
|
||||||
|
with patch.object(config, "async_sync_entities_all") as mock_sync:
|
||||||
|
await config.async_initialize()
|
||||||
|
await config.async_connect_agent_user("mock-user-id")
|
||||||
|
assert len(mock_sync.mock_calls) == 0
|
||||||
|
|
||||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(mock_sync.mock_calls) == 1
|
assert len(mock_sync.mock_calls) == 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user