From 0fe5d567a25b245c2f151f5847349b92566ece1d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 17 Jan 2019 10:33:01 -0800 Subject: [PATCH] Add command to refresh auth (#20183) --- homeassistant/components/cloud/iot.py | 11 ++++++++--- tests/components/cloud/test_iot.py | 28 +++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/cloud/iot.py b/homeassistant/components/cloud/iot.py index 8638a4233ce..ed24fe48d40 100644 --- a/homeassistant/components/cloud/iot.py +++ b/homeassistant/components/cloud/iot.py @@ -316,15 +316,20 @@ def async_handle_google_actions(hass, cloud, payload): @HANDLERS.register('cloud') -@asyncio.coroutine -def async_handle_cloud(hass, cloud, payload): +async def async_handle_cloud(hass, cloud, payload): """Handle an incoming IoT message for cloud component.""" action = payload['action'] if action == 'logout': - yield from cloud.logout() + # Log out of Home Assistant Cloud + await cloud.logout() _LOGGER.error("You have been logged out from Home Assistant cloud: %s", payload['reason']) + elif action == 'refresh_auth': + # Refresh the auth token between now and payload['seconds'] + hass.helpers.event.async_call_later( + random.randint(0, payload['seconds']), + lambda now: auth_api.check_token(cloud)) else: _LOGGER.warning("Received unknown cloud action: %s", action) diff --git a/tests/components/cloud/test_iot.py b/tests/components/cloud/test_iot.py index 2133a803aef..1a528f8cedf 100644 --- a/tests/components/cloud/test_iot.py +++ b/tests/components/cloud/test_iot.py @@ -10,8 +10,9 @@ from homeassistant.components.cloud import ( Cloud, iot, auth_api, MODE_DEV) from homeassistant.components.cloud.const import ( PREF_ENABLE_ALEXA, PREF_ENABLE_GOOGLE) +from homeassistant.util import dt as dt_util from tests.components.alexa import test_smart_home as test_alexa -from tests.common import mock_coro +from tests.common import mock_coro, async_fire_time_changed from . import mock_cloud_prefs @@ -147,17 +148,36 @@ def test_handler_forwarding(): assert payload == 'payload' -@asyncio.coroutine -def test_handling_core_messages(hass, mock_cloud): +async def test_handling_core_messages_logout(hass, mock_cloud): """Test handling core messages.""" mock_cloud.logout.return_value = mock_coro() - yield from iot.async_handle_cloud(hass, mock_cloud, { + await iot.async_handle_cloud(hass, mock_cloud, { 'action': 'logout', 'reason': 'Logged in at two places.' }) assert len(mock_cloud.logout.mock_calls) == 1 +async def test_handling_core_messages_refresh_auth(hass, mock_cloud): + """Test handling core messages.""" + mock_cloud.hass = hass + with patch('random.randint', return_value=0) as mock_rand, patch( + 'homeassistant.components.cloud.auth_api.check_token' + ) as mock_check: + await iot.async_handle_cloud(hass, mock_cloud, { + 'action': 'refresh_auth', + 'seconds': 230, + }) + async_fire_time_changed(hass, dt_util.utcnow()) + await hass.async_block_till_done() + + assert len(mock_rand.mock_calls) == 1 + assert mock_rand.mock_calls[0][1] == (0, 230) + + assert len(mock_check.mock_calls) == 1 + assert mock_check.mock_calls[0][1][0] is mock_cloud + + @asyncio.coroutine def test_cloud_getting_disconnected_by_server(mock_client, caplog, mock_cloud): """Test server disconnecting instance."""