diff --git a/homeassistant/components/google_assistant/helpers.py b/homeassistant/components/google_assistant/helpers.py index 529778ce1b6..b425367f5c3 100644 --- a/homeassistant/components/google_assistant/helpers.py +++ b/homeassistant/components/google_assistant/helpers.py @@ -10,6 +10,7 @@ import logging import pprint from aiohttp.web import json_response +from awesomeversion import AwesomeVersion from homeassistant.components import webhook from homeassistant.const import ( @@ -43,6 +44,8 @@ from .error import SmartHomeError SYNC_DELAY = 15 _LOGGER = logging.getLogger(__name__) +LOCAL_SDK_VERSION_HEADER = "HA-Cloud-Version" +LOCAL_SDK_MIN_VERSION = AwesomeVersion("2.1.5") @callback @@ -86,6 +89,7 @@ class AbstractConfig(ABC): self._google_sync_unsub = {} self._local_sdk_active = False self._local_last_active: datetime | None = None + self._local_sdk_version_warn = False async def async_initialize(self): """Perform async initialization of config.""" @@ -327,6 +331,18 @@ class AbstractConfig(ABC): from . import smart_home self._local_last_active = utcnow() + + # Check version local SDK. + version = request.headers.get("HA-Cloud-Version") + if not self._local_sdk_version_warn and ( + not version or AwesomeVersion(version) < LOCAL_SDK_MIN_VERSION + ): + _LOGGER.warning( + "Local SDK version is too old (%s), check documentation on how to update to the latest version", + version, + ) + self._local_sdk_version_warn = True + payload = await request.json() if _LOGGER.isEnabledFor(logging.DEBUG): @@ -577,8 +593,9 @@ class GoogleEntity: device["customData"] = { "webhookId": self.config.get_local_webhook_id(agent_user_id), "httpPort": self.hass.http.server_port, - "httpSSL": self.hass.config.api.use_ssl, "uuid": instance_uuid, + # Below can be removed in HA 2022.9 + "httpSSL": self.hass.config.api.use_ssl, "baseUrl": get_url(self.hass, prefer_external=True), "proxyDeviceId": agent_user_id, } diff --git a/tests/components/google_assistant/test_helpers.py b/tests/components/google_assistant/test_helpers.py index 4490f0e3963..1ab573baf2a 100644 --- a/tests/components/google_assistant/test_helpers.py +++ b/tests/components/google_assistant/test_helpers.py @@ -345,3 +345,85 @@ def test_request_data(): config, "test_user", SOURCE_CLOUD, "test_request_id", None ) assert data.is_local_request is False + + +async def test_config_local_sdk_allow_min_version(hass, hass_client, caplog): + """Test the local SDK.""" + version = str(helpers.LOCAL_SDK_MIN_VERSION) + assert await async_setup_component(hass, "webhook", {}) + + config = MockConfig( + hass=hass, + agent_user_ids={ + "mock-user-id": { + STORE_GOOGLE_LOCAL_WEBHOOK_ID: "mock-webhook-id", + }, + }, + ) + + client = await hass_client() + + assert config._local_sdk_version_warn is False + config.async_enable_local_sdk() + + await client.post( + "/api/webhook/mock-webhook-id", + headers={helpers.LOCAL_SDK_VERSION_HEADER: version}, + json={ + "inputs": [ + { + "context": {"locale_country": "US", "locale_language": "en"}, + "intent": "action.devices.SYNC", + } + ], + "requestId": "mock-req-id", + }, + ) + assert config._local_sdk_version_warn is False + assert ( + f"Local SDK version is too old ({version}), check documentation on how " + "to update to the latest version" + ) not in caplog.text + + +@pytest.mark.parametrize("version", (None, "2.1.4")) +async def test_config_local_sdk_warn_version(hass, hass_client, caplog, version): + """Test the local SDK.""" + assert await async_setup_component(hass, "webhook", {}) + + config = MockConfig( + hass=hass, + agent_user_ids={ + "mock-user-id": { + STORE_GOOGLE_LOCAL_WEBHOOK_ID: "mock-webhook-id", + }, + }, + ) + + client = await hass_client() + + assert config._local_sdk_version_warn is False + config.async_enable_local_sdk() + + headers = {} + if version: + headers[helpers.LOCAL_SDK_VERSION_HEADER] = version + + await client.post( + "/api/webhook/mock-webhook-id", + headers=headers, + json={ + "inputs": [ + { + "context": {"locale_country": "US", "locale_language": "en"}, + "intent": "action.devices.SYNC", + } + ], + "requestId": "mock-req-id", + }, + ) + assert config._local_sdk_version_warn is True + assert ( + f"Local SDK version is too old ({version}), check documentation on how " + "to update to the latest version" + ) in caplog.text