From ee0bdaa2dea1031bd120a762e7e97cc97155ecd1 Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Fri, 4 Mar 2022 00:41:50 +0100 Subject: [PATCH] Check if UPnP is enabled on Fritz device (#67512) Co-authored-by: Paulus Schoutsen Co-authored-by: Paulus Schoutsen --- homeassistant/components/fritz/__init__.py | 6 ++++++ homeassistant/components/fritz/common.py | 10 ++++++++++ homeassistant/components/fritz/config_flow.py | 7 +++++++ homeassistant/components/fritz/const.py | 1 + homeassistant/components/fritz/strings.json | 1 + homeassistant/components/fritz/translations/en.json | 5 +++-- 6 files changed, 28 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/fritz/__init__.py b/homeassistant/components/fritz/__init__.py index a0e0413366b..0b334ff616a 100644 --- a/homeassistant/components/fritz/__init__.py +++ b/homeassistant/components/fritz/__init__.py @@ -33,6 +33,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except FRITZ_EXCEPTIONS as ex: raise ConfigEntryNotReady from ex + if ( + "X_AVM-DE_UPnP1" in avm_wrapper.connection.services + and not (await avm_wrapper.async_get_upnp_configuration())["NewEnable"] + ): + raise ConfigEntryAuthFailed("Missing UPnP configuration") + hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN][entry.entry_id] = avm_wrapper diff --git a/homeassistant/components/fritz/common.py b/homeassistant/components/fritz/common.py index b2a429bfa3c..2fc28433e56 100644 --- a/homeassistant/components/fritz/common.py +++ b/homeassistant/components/fritz/common.py @@ -630,6 +630,11 @@ class AvmWrapper(FritzBoxTools): ) return {} + async def async_get_upnp_configuration(self) -> dict[str, Any]: + """Call X_AVM-DE_UPnP service.""" + + return await self.hass.async_add_executor_job(self.get_upnp_configuration) + async def async_get_wan_link_properties(self) -> dict[str, Any]: """Call WANCommonInterfaceConfig service.""" @@ -698,6 +703,11 @@ class AvmWrapper(FritzBoxTools): partial(self.set_allow_wan_access, ip_address, turn_on) ) + def get_upnp_configuration(self) -> dict[str, Any]: + """Call X_AVM-DE_UPnP service.""" + + return self._service_call_action("X_AVM-DE_UPnP", "1", "GetInfo") + def get_ontel_num_deflections(self) -> dict[str, Any]: """Call GetNumberOfDeflections action from X_AVM-DE_OnTel service.""" diff --git a/homeassistant/components/fritz/config_flow.py b/homeassistant/components/fritz/config_flow.py index 0844d725522..046f00ba3a9 100644 --- a/homeassistant/components/fritz/config_flow.py +++ b/homeassistant/components/fritz/config_flow.py @@ -29,6 +29,7 @@ from .const import ( ERROR_AUTH_INVALID, ERROR_CANNOT_CONNECT, ERROR_UNKNOWN, + ERROR_UPNP_NOT_CONFIGURED, ) _LOGGER = logging.getLogger(__name__) @@ -79,6 +80,12 @@ class FritzBoxToolsFlowHandler(ConfigFlow, domain=DOMAIN): _LOGGER.exception("Unexpected exception") return ERROR_UNKNOWN + if ( + "X_AVM-DE_UPnP1" in self.avm_wrapper.connection.services + and not (await self.avm_wrapper.async_get_upnp_configuration())["NewEnable"] + ): + return ERROR_UPNP_NOT_CONFIGURED + return None async def async_check_configured_entry(self) -> ConfigEntry | None: diff --git a/homeassistant/components/fritz/const.py b/homeassistant/components/fritz/const.py index f33cf463996..f739ccf6858 100644 --- a/homeassistant/components/fritz/const.py +++ b/homeassistant/components/fritz/const.py @@ -46,6 +46,7 @@ DEFAULT_USERNAME = "" ERROR_AUTH_INVALID = "invalid_auth" ERROR_CANNOT_CONNECT = "cannot_connect" +ERROR_UPNP_NOT_CONFIGURED = "upnp_not_configured" ERROR_UNKNOWN = "unknown_error" FRITZ_SERVICES = "fritz_services" diff --git a/homeassistant/components/fritz/strings.json b/homeassistant/components/fritz/strings.json index 450566f101b..a65b2900f66 100644 --- a/homeassistant/components/fritz/strings.json +++ b/homeassistant/components/fritz/strings.json @@ -36,6 +36,7 @@ }, "error": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", + "upnp_not_configured": "Missing UPnP settings on device.", "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]" diff --git a/homeassistant/components/fritz/translations/en.json b/homeassistant/components/fritz/translations/en.json index 0a58ee686f3..c6fa4a16036 100644 --- a/homeassistant/components/fritz/translations/en.json +++ b/homeassistant/components/fritz/translations/en.json @@ -9,7 +9,8 @@ "already_configured": "Device is already configured", "already_in_progress": "Configuration flow is already in progress", "cannot_connect": "Failed to connect", - "invalid_auth": "Invalid authentication" + "invalid_auth": "Invalid authentication", + "upnp_not_configured": "Missing UPnP settings on device." }, "flow_title": "{name}", "step": { @@ -51,4 +52,4 @@ } } } -} \ No newline at end of file +}