From 82edea60774fc1caa2d107d105ea95e65f15e4cf Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Thu, 1 Nov 2018 22:59:42 +0100 Subject: [PATCH] Removed assumptions about provided upnp data (#17604) * Removed assumptions about incomplete UPnP devices * Removed assumptions about incomplete UPnP devices --- homeassistant/components/upnp/config_flow.py | 23 ++++++++++++++++---- homeassistant/components/upnp/strings.json | 1 + tests/components/upnp/test_config_flow.py | 21 ++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/upnp/config_flow.py b/homeassistant/components/upnp/config_flow.py index c7cd55f0477..1a6526638ba 100644 --- a/homeassistant/components/upnp/config_flow.py +++ b/homeassistant/components/upnp/config_flow.py @@ -1,4 +1,5 @@ """Config flow for UPNP.""" +import logging from collections import OrderedDict import voluptuous as vol @@ -14,6 +15,9 @@ from .const import ( from .const import DOMAIN +_LOGGER = logging.getLogger(__name__) + + async def async_ensure_domain_data(hass): """Ensure hass.data is filled properly.""" hass.data[DOMAIN] = hass.data.get(DOMAIN, {}) @@ -70,14 +74,25 @@ class UpnpFlowHandler(data_entry_flow.FlowHandler): """ await async_ensure_domain_data(self.hass) + if not discovery_info.get('udn') or not discovery_info.get('host'): + # Silently ignore incomplete/broken devices to prevent constant + # errors/warnings + _LOGGER.debug('UPnP device is missing the udn. Provided info: %r', + discovery_info) + return self.async_abort(reason='incomplete_device') + # store discovered device - discovery_info['friendly_name'] = \ - '{} ({})'.format(discovery_info['host'], discovery_info['name']) + discovery_info['friendly_name'] = discovery_info.get('host', '') + + # add name if available + if discovery_info.get('name'): + discovery_info['friendly_name'] += ' ({name})'.format( + **discovery_info) + self._store_discovery_info(discovery_info) # ensure not already discovered/configured - udn = discovery_info['udn'] - if udn in self._configured_upnp_igds: + if discovery_info.get('udn') in self._configured_upnp_igds: return self.async_abort(reason='already_configured') # auto config? diff --git a/homeassistant/components/upnp/strings.json b/homeassistant/components/upnp/strings.json index 9dd4c3f5ad0..40bcb46d386 100644 --- a/homeassistant/components/upnp/strings.json +++ b/homeassistant/components/upnp/strings.json @@ -16,6 +16,7 @@ }, "abort": { "no_devices_discovered": "No UPnP/IGDs discovered", + "incomplete_device": "Ignoring incomplete UPnP device", "already_configured": "UPnP/IGD is already configured", "no_sensors_or_port_mapping": "Enable at least sensors or port mapping" } diff --git a/tests/components/upnp/test_config_flow.py b/tests/components/upnp/test_config_flow.py index 3ff1316975f..968c59955e2 100644 --- a/tests/components/upnp/test_config_flow.py +++ b/tests/components/upnp/test_config_flow.py @@ -176,6 +176,27 @@ async def test_config_entry_created(hass): assert result['title'] == 'Test device 1' +async def test_flow_discovery_no_data(hass): + """Test creation of device with auto_config.""" + flow = upnp_config_flow.UpnpFlowHandler() + flow.hass = hass + + # auto_config active + hass.data[upnp.DOMAIN] = { + 'auto_config': { + 'active': True, + 'enable_port_mapping': False, + 'enable_sensors': True, + }, + } + + # discovered device + result = await flow.async_step_discovery({}) + + assert result['type'] == 'abort' + assert result['reason'] == 'incomplete_device' + + async def test_flow_discovery_auto_config_sensors(hass): """Test creation of device with auto_config.""" flow = upnp_config_flow.UpnpFlowHandler()