From 0cce35b23edffd7beffe6b817fa7a357265bf0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Thu, 10 Sep 2020 14:52:49 +0200 Subject: [PATCH] Add exception for NoURLAvailableError in OAuth2FlowHandler (#39845) Co-authored-by: Martin Hjelmare Co-authored-by: Paulus Schoutsen --- homeassistant/components/almond/strings.json | 3 +- .../components/home_connect/strings.json | 3 +- homeassistant/components/netatmo/strings.json | 5 +- homeassistant/components/smappee/strings.json | 61 ++++++++++--------- homeassistant/components/somfy/strings.json | 3 +- homeassistant/components/spotify/strings.json | 1 + homeassistant/components/toon/strings.json | 3 +- .../components/withings/strings.json | 3 +- .../helpers/config_entry_oauth2_flow.py | 9 ++- homeassistant/strings.json | 3 +- .../helpers/test_config_entry_oauth2_flow.py | 17 ++++++ 11 files changed, 72 insertions(+), 39 deletions(-) diff --git a/homeassistant/components/almond/strings.json b/homeassistant/components/almond/strings.json index 008d21c463b0..e8244798e817 100644 --- a/homeassistant/components/almond/strings.json +++ b/homeassistant/components/almond/strings.json @@ -10,7 +10,8 @@ "abort": { "already_setup": "You can only configure one Almond account.", "cannot_connect": "Unable to connect to the Almond server.", - "missing_configuration": "Please check the documentation on how to set up Almond." + "missing_configuration": "Please check the documentation on how to set up Almond.", + "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]" } } } diff --git a/homeassistant/components/home_connect/strings.json b/homeassistant/components/home_connect/strings.json index 6125897c9624..798fe2930a03 100644 --- a/homeassistant/components/home_connect/strings.json +++ b/homeassistant/components/home_connect/strings.json @@ -6,7 +6,8 @@ } }, "abort": { - "missing_configuration": "The Home Connect component is not configured. Please follow the documentation." + "missing_configuration": "The Home Connect component is not configured. Please follow the documentation.", + "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]" }, "create_entry": { "default": "Successfully authenticated with Home Connect." diff --git a/homeassistant/components/netatmo/strings.json b/homeassistant/components/netatmo/strings.json index f1b761dd1876..6e88d1916103 100644 --- a/homeassistant/components/netatmo/strings.json +++ b/homeassistant/components/netatmo/strings.json @@ -8,7 +8,8 @@ "abort": { "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]", "authorize_url_timeout": "[%key:common::config_flow::abort::oauth2_authorize_url_timeout%]", - "missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]" + "missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]", + "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]" }, "create_entry": { "default": "[%key:common::config_flow::create_entry::authenticated%]" @@ -39,4 +40,4 @@ } } } -} \ No newline at end of file +} diff --git a/homeassistant/components/smappee/strings.json b/homeassistant/components/smappee/strings.json index 9d4bb618832d..1bec8fda0cc2 100644 --- a/homeassistant/components/smappee/strings.json +++ b/homeassistant/components/smappee/strings.json @@ -1,34 +1,35 @@ { - "config": { - "flow_title": "Smappee: {name}", - "step": { - "environment": { - "description": "Set up your Smappee to integrate with Home Assistant.", - "data": { - "environment": "Environment" - } - }, - "local": { - "description": "Enter the host to initiate the Smappee local integration", - "data": { - "host": "[%key:common::config_flow::data::host%]" - } - }, - "zeroconf_confirm": { - "description": "Do you want to add the Smappee device with serialnumber `{serialnumber}` to Home Assistant?", - "title": "Discovered Smappee device" - }, - "pick_implementation": { - "title": "Pick Authentication Method" - } - }, - "abort": { - "already_configured_device": "[%key:common::config_flow::abort::already_configured_device%]", - "already_configured_local_device": "Local device(s) is already configured. Please remove those first before configuring a cloud device.", - "authorize_url_timeout": "Timeout generating authorize url.", - "connection_error": "Failed to connect to Smappee device.", - "missing_configuration": "The component is not configured. Please follow the documentation.", - "invalid_mdns": "Unsupported device for the Smappee integration." + "config": { + "flow_title": "Smappee: {name}", + "step": { + "environment": { + "description": "Set up your Smappee to integrate with Home Assistant.", + "data": { + "environment": "Environment" } + }, + "local": { + "description": "Enter the host to initiate the Smappee local integration", + "data": { + "host": "[%key:common::config_flow::data::host%]" + } + }, + "zeroconf_confirm": { + "description": "Do you want to add the Smappee device with serialnumber `{serialnumber}` to Home Assistant?", + "title": "Discovered Smappee device" + }, + "pick_implementation": { + "title": "Pick Authentication Method" + } + }, + "abort": { + "already_configured_device": "[%key:common::config_flow::abort::already_configured_device%]", + "already_configured_local_device": "Local device(s) is already configured. Please remove those first before configuring a cloud device.", + "authorize_url_timeout": "Timeout generating authorize url.", + "connection_error": "Failed to connect to Smappee device.", + "missing_configuration": "The component is not configured. Please follow the documentation.", + "invalid_mdns": "Unsupported device for the Smappee integration.", + "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]" } + } } diff --git a/homeassistant/components/somfy/strings.json b/homeassistant/components/somfy/strings.json index 90ea98f7a870..d1fa921bb8ed 100644 --- a/homeassistant/components/somfy/strings.json +++ b/homeassistant/components/somfy/strings.json @@ -6,7 +6,8 @@ "abort": { "already_setup": "You can only configure one Somfy account.", "authorize_url_timeout": "Timeout generating authorize url.", - "missing_configuration": "The Somfy component is not configured. Please follow the documentation." + "missing_configuration": "The Somfy component is not configured. Please follow the documentation.", + "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]" }, "create_entry": { "default": "Successfully authenticated with Somfy." } } diff --git a/homeassistant/components/spotify/strings.json b/homeassistant/components/spotify/strings.json index 85ff9ff267b6..8e3fa6fc6790 100644 --- a/homeassistant/components/spotify/strings.json +++ b/homeassistant/components/spotify/strings.json @@ -10,6 +10,7 @@ "abort": { "already_setup": "You can only configure one Spotify account.", "authorize_url_timeout": "Timeout generating authorize url.", + "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]", "missing_configuration": "The Spotify integration is not configured. Please follow the documentation.", "reauth_account_mismatch": "The Spotify account authenticated with, does not match the account needed re-authentication." }, diff --git a/homeassistant/components/toon/strings.json b/homeassistant/components/toon/strings.json index 05eef817d288..c5ac07516b62 100644 --- a/homeassistant/components/toon/strings.json +++ b/homeassistant/components/toon/strings.json @@ -17,7 +17,8 @@ "authorize_url_fail": "Unknown error generating an authorize url.", "authorize_url_timeout": "[%key:common::config_flow::abort::oauth2_authorize_url_timeout%]", "missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]", - "no_agreements": "This account has no Toon displays." + "no_agreements": "This account has no Toon displays.", + "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]" } } } diff --git a/homeassistant/components/withings/strings.json b/homeassistant/components/withings/strings.json index e7763a1db0ce..c9d2d7ca22ce 100644 --- a/homeassistant/components/withings/strings.json +++ b/homeassistant/components/withings/strings.json @@ -19,7 +19,8 @@ "abort": { "authorize_url_timeout": "Timeout generating authorize url.", "missing_configuration": "The Withings integration is not configured. Please follow the documentation.", - "already_configured": "Configuration updated for profile." + "already_configured": "Configuration updated for profile.", + "no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]" }, "create_entry": { "default": "Successfully authenticated with Withings." } } diff --git a/homeassistant/helpers/config_entry_oauth2_flow.py b/homeassistant/helpers/config_entry_oauth2_flow.py index da86c222c136..55ec3984b82c 100644 --- a/homeassistant/helpers/config_entry_oauth2_flow.py +++ b/homeassistant/helpers/config_entry_oauth2_flow.py @@ -21,7 +21,7 @@ from yarl import URL from homeassistant import config_entries from homeassistant.components.http import HomeAssistantView from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.network import get_url +from homeassistant.helpers.network import NoURLAvailableError, get_url from .aiohttp_client import async_get_clientsession @@ -251,6 +251,13 @@ class AbstractOAuth2FlowHandler(config_entries.ConfigFlow, metaclass=ABCMeta): url = await self.flow_impl.async_generate_authorize_url(self.flow_id) except asyncio.TimeoutError: return self.async_abort(reason="authorize_url_timeout") + except NoURLAvailableError: + return self.async_abort( + reason="no_url_available", + description_placeholders={ + "docs_url": "https://www.home-assistant.io/more-info/no-url-available" + }, + ) url = str(URL(url).update_query(self.extra_authorize_data)) diff --git a/homeassistant/strings.json b/homeassistant/strings.json index 63615094715f..05bc2e3c2479 100644 --- a/homeassistant/strings.json +++ b/homeassistant/strings.json @@ -53,7 +53,8 @@ "already_configured_device": "Device is already configured", "no_devices_found": "No devices found on the network", "oauth2_missing_configuration": "The component is not configured. Please follow the documentation.", - "oauth2_authorize_url_timeout": "Timeout generating authorize URL." + "oauth2_authorize_url_timeout": "Timeout generating authorize URL.", + "oauth2_no_url_available": "No URL available. For information about this error, [check the help section]({docs_url})" } } } diff --git a/tests/helpers/test_config_entry_oauth2_flow.py b/tests/helpers/test_config_entry_oauth2_flow.py index dc34b0f7876c..691b2e93d569 100644 --- a/tests/helpers/test_config_entry_oauth2_flow.py +++ b/tests/helpers/test_config_entry_oauth2_flow.py @@ -8,6 +8,7 @@ import pytest from homeassistant import config_entries, data_entry_flow, setup from homeassistant.config import async_process_ha_core_config from homeassistant.helpers import config_entry_oauth2_flow +from homeassistant.helpers.network import NoURLAvailableError from tests.async_mock import patch from tests.common import MockConfigEntry, mock_platform @@ -128,6 +129,22 @@ async def test_abort_if_authorization_timeout(hass, flow_handler, local_impl): assert result["reason"] == "authorize_url_timeout" +async def test_abort_if_no_url_available(hass, flow_handler, local_impl): + """Check no_url_available generating authorization url.""" + flow_handler.async_register_implementation(hass, local_impl) + + flow = flow_handler() + flow.hass = hass + + with patch.object( + local_impl, "async_generate_authorize_url", side_effect=NoURLAvailableError + ): + result = await flow.async_step_user() + + assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result["reason"] == "no_url_available" + + async def test_abort_if_oauth_error( hass, flow_handler, local_impl, aiohttp_client, aioclient_mock, current_request ):