mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 22:07:10 +00:00
Ignore fake upnp/IGD devices when upnp is discovered (#73645)
This commit is contained in:
parent
2be54de448
commit
bf15df75dd
@ -63,6 +63,12 @@ async def _async_mac_address_from_discovery(
|
|||||||
return await async_get_mac_address_from_host(hass, host)
|
return await async_get_mac_address_from_host(hass, host)
|
||||||
|
|
||||||
|
|
||||||
|
def _is_igd_device(discovery_info: ssdp.SsdpServiceInfo) -> bool:
|
||||||
|
"""Test if discovery is a complete IGD device."""
|
||||||
|
root_device_info = discovery_info.upnp
|
||||||
|
return root_device_info.get(ssdp.ATTR_UPNP_DEVICE_TYPE) in {ST_IGD_V1, ST_IGD_V2}
|
||||||
|
|
||||||
|
|
||||||
class UpnpFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
class UpnpFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
"""Handle a UPnP/IGD config flow."""
|
"""Handle a UPnP/IGD config flow."""
|
||||||
|
|
||||||
@ -108,6 +114,7 @@ class UpnpFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
for discovery in discoveries
|
for discovery in discoveries
|
||||||
if (
|
if (
|
||||||
_is_complete_discovery(discovery)
|
_is_complete_discovery(discovery)
|
||||||
|
and _is_igd_device(discovery)
|
||||||
and discovery.ssdp_usn not in current_unique_ids
|
and discovery.ssdp_usn not in current_unique_ids
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -144,6 +151,12 @@ class UpnpFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
LOGGER.debug("Incomplete discovery, ignoring")
|
LOGGER.debug("Incomplete discovery, ignoring")
|
||||||
return self.async_abort(reason="incomplete_discovery")
|
return self.async_abort(reason="incomplete_discovery")
|
||||||
|
|
||||||
|
# Ensure device is usable. Ideally we would use IgdDevice.is_profile_device,
|
||||||
|
# but that requires constructing the device completely.
|
||||||
|
if not _is_igd_device(discovery_info):
|
||||||
|
LOGGER.debug("Non IGD device, ignoring")
|
||||||
|
return self.async_abort(reason="non_igd_device")
|
||||||
|
|
||||||
# Ensure not already configuring/configured.
|
# Ensure not already configuring/configured.
|
||||||
unique_id = discovery_info.ssdp_usn
|
unique_id = discovery_info.ssdp_usn
|
||||||
await self.async_set_unique_id(unique_id)
|
await self.async_set_unique_id(unique_id)
|
||||||
|
@ -14,6 +14,7 @@ from homeassistant.components.upnp.const import (
|
|||||||
CONFIG_ENTRY_ST,
|
CONFIG_ENTRY_ST,
|
||||||
CONFIG_ENTRY_UDN,
|
CONFIG_ENTRY_UDN,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
ST_IGD_V1,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
@ -75,6 +76,7 @@ async def test_flow_ssdp_incomplete_discovery(hass: HomeAssistant):
|
|||||||
ssdp_st=TEST_ST,
|
ssdp_st=TEST_ST,
|
||||||
ssdp_location=TEST_LOCATION,
|
ssdp_location=TEST_LOCATION,
|
||||||
upnp={
|
upnp={
|
||||||
|
ssdp.ATTR_UPNP_DEVICE_TYPE: ST_IGD_V1,
|
||||||
# ssdp.ATTR_UPNP_UDN: TEST_UDN, # Not provided.
|
# ssdp.ATTR_UPNP_UDN: TEST_UDN, # Not provided.
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -83,6 +85,27 @@ async def test_flow_ssdp_incomplete_discovery(hass: HomeAssistant):
|
|||||||
assert result["reason"] == "incomplete_discovery"
|
assert result["reason"] == "incomplete_discovery"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("mock_get_source_ip")
|
||||||
|
async def test_flow_ssdp_non_igd_device(hass: HomeAssistant):
|
||||||
|
"""Test config flow: incomplete discovery through ssdp."""
|
||||||
|
# Discovered via step ssdp.
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_SSDP},
|
||||||
|
data=ssdp.SsdpServiceInfo(
|
||||||
|
ssdp_usn=TEST_USN,
|
||||||
|
ssdp_st=TEST_ST,
|
||||||
|
ssdp_location=TEST_LOCATION,
|
||||||
|
upnp={
|
||||||
|
ssdp.ATTR_UPNP_DEVICE_TYPE: "urn:schemas-upnp-org:device:WFADevice:1", # Non-IGD
|
||||||
|
ssdp.ATTR_UPNP_UDN: TEST_UDN,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||||
|
assert result["reason"] == "non_igd_device"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures(
|
@pytest.mark.usefixtures(
|
||||||
"ssdp_instant_discovery",
|
"ssdp_instant_discovery",
|
||||||
"mock_setup_entry",
|
"mock_setup_entry",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user