Hue config flow to guard ipv6 (#70703)

* Hue config flow to guard ipv6

* Use helper
This commit is contained in:
Paulus Schoutsen 2022-04-25 10:52:57 -07:00 committed by GitHub
parent 5317bf02e6
commit 87dceaf238
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 4 deletions

View File

@ -21,6 +21,7 @@ from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers import aiohttp_client, device_registry
import homeassistant.helpers.config_validation as cv
from homeassistant.util.network import is_ipv6_address
from .const import (
CONF_ALLOW_HUE_GROUPS,
@ -230,6 +231,10 @@ class HueFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
if not url.hostname:
return self.async_abort(reason="not_hue_bridge")
# Ignore if host is IPv6
if is_ipv6_address(url.hostname):
return self.async_abort(reason="invalid_host")
# abort if we already have exactly this bridge id/host
# reload the integration if the host got updated
bridge_id = normalize_bridge_id(discovery_info.upnp[ssdp.ATTR_UPNP_SERIAL])
@ -251,6 +256,10 @@ class HueFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
This flow is triggered by the Zeroconf component. It will check if the
host is already configured and delegate to the import step if not.
"""
# Ignore if host is IPv6
if is_ipv6_address(discovery_info.host):
return self.async_abort(reason="invalid_host")
# abort if we already have exactly this bridge id/host
# reload the integration if the host got updated
bridge_id = normalize_bridge_id(discovery_info.properties["bridgeid"])

View File

@ -30,7 +30,8 @@
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
"not_hue_bridge": "Not a Hue bridge"
"not_hue_bridge": "Not a Hue bridge",
"invalid_host": "Invalid host"
}
},
"device_automation": {

View File

@ -424,7 +424,14 @@ async def test_bridge_ssdp_missing_serial(hass):
assert result["reason"] == "not_hue_bridge"
async def test_bridge_ssdp_invalid_location(hass):
@pytest.mark.parametrize(
"location,reason",
(
("http:///", "not_hue_bridge"),
("http://[fd00::eeb5:faff:fe84:b17d]/description.xml", "invalid_host"),
),
)
async def test_bridge_ssdp_invalid_location(hass, location, reason):
"""Test if discovery info is a serial attribute."""
result = await hass.config_entries.flow.async_init(
const.DOMAIN,
@ -432,7 +439,7 @@ async def test_bridge_ssdp_invalid_location(hass):
data=ssdp.SsdpServiceInfo(
ssdp_usn="mock_usn",
ssdp_st="mock_st",
ssdp_location="http:///",
ssdp_location=location,
upnp={
ssdp.ATTR_UPNP_MANUFACTURER_URL: config_flow.HUE_MANUFACTURERURL[0],
ssdp.ATTR_UPNP_SERIAL: "1234",
@ -441,7 +448,7 @@ async def test_bridge_ssdp_invalid_location(hass):
)
assert result["type"] == "abort"
assert result["reason"] == "not_hue_bridge"
assert result["reason"] == reason
async def test_bridge_ssdp_espalexa(hass):
@ -791,3 +798,27 @@ async def test_bridge_zeroconf_already_exists(hass, aioclient_mock):
assert result["type"] == "abort"
assert result["reason"] == "already_configured"
assert entry.data["host"] == "192.168.1.217"
async def test_bridge_zeroconf_ipv6(hass):
"""Test a bridge being discovered by zeroconf and ipv6 address."""
result = await hass.config_entries.flow.async_init(
const.DOMAIN,
context={"source": config_entries.SOURCE_ZEROCONF},
data=zeroconf.ZeroconfServiceInfo(
host="fd00::eeb5:faff:fe84:b17d",
addresses=["fd00::eeb5:faff:fe84:b17d"],
port=443,
hostname="Philips-hue.local",
type="_hue._tcp.local.",
name="Philips Hue - ABCABC._hue._tcp.local.",
properties={
"_raw": {"bridgeid": b"ecb5faabcabc", "modelid": b"BSB002"},
"bridgeid": "ecb5faabcabc",
"modelid": "BSB002",
},
),
)
assert result["type"] == "abort"
assert result["reason"] == "invalid_host"