Fix reconfigure by SSDP or Zeroconf discovery in Synology DSM (#92088)

This commit is contained in:
Michael 2023-04-27 00:52:17 +02:00 committed by GitHub
parent 29ca43acf6
commit 4e7f39e3d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 21 deletions

View file

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Mapping from collections.abc import Mapping
from ipaddress import ip_address from ipaddress import ip_address as ip
import logging import logging
from typing import Any, cast from typing import Any, cast
from urllib.parse import urlparse from urllib.parse import urlparse
@ -38,6 +38,7 @@ from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import DiscoveryInfoType from homeassistant.helpers.typing import DiscoveryInfoType
from homeassistant.util.network import is_ip_address as is_ip
from .const import ( from .const import (
CONF_DEVICE_TOKEN, CONF_DEVICE_TOKEN,
@ -99,14 +100,6 @@ def _ordered_shared_schema(
} }
def _is_valid_ip(text: str) -> bool:
try:
ip_address(text)
except ValueError:
return False
return True
def format_synology_mac(mac: str) -> str: def format_synology_mac(mac: str) -> str:
"""Format a mac address to the format used by Synology DSM.""" """Format a mac address to the format used by Synology DSM."""
return mac.replace(":", "").replace("-", "").upper() return mac.replace(":", "").replace("-", "").upper()
@ -284,16 +277,12 @@ class SynologyDSMFlowHandler(ConfigFlow, domain=DOMAIN):
break break
self._abort_if_unique_id_configured() self._abort_if_unique_id_configured()
fqdn_with_ssl_verification = (
existing_entry
and not _is_valid_ip(existing_entry.data[CONF_HOST])
and existing_entry.data[CONF_VERIFY_SSL]
)
if ( if (
existing_entry existing_entry
and is_ip(existing_entry.data[CONF_HOST])
and is_ip(host)
and existing_entry.data[CONF_HOST] != host and existing_entry.data[CONF_HOST] != host
and not fqdn_with_ssl_verification and ip(existing_entry.data[CONF_HOST]).version == ip(host).version
): ):
_LOGGER.info( _LOGGER.info(
"Update host from '%s' to '%s' for NAS '%s' via discovery", "Update host from '%s' to '%s' for NAS '%s' via discovery",

View file

@ -512,7 +512,7 @@ async def test_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> None:
MockConfigEntry( MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
data={ data={
CONF_HOST: "wrong_host", CONF_HOST: "192.168.1.3",
CONF_VERIFY_SSL: VERIFY_SSL, CONF_VERIFY_SSL: VERIFY_SSL,
CONF_USERNAME: USERNAME, CONF_USERNAME: USERNAME,
CONF_PASSWORD: PASSWORD, CONF_PASSWORD: PASSWORD,
@ -539,14 +539,24 @@ async def test_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> None:
@pytest.mark.usefixtures("mock_setup_entry") @pytest.mark.usefixtures("mock_setup_entry")
async def test_skip_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> None: @pytest.mark.parametrize(
("current_host", "new_host"),
[
("some.fqdn", "192.168.1.5"),
("192.168.1.5", "abcd:1234::"),
("abcd:1234::", "192.168.1.5"),
],
)
async def test_skip_reconfig_ssdp(
hass: HomeAssistant, current_host: str, new_host: str, service: MagicMock
) -> None:
"""Test re-configuration of already existing entry by ssdp.""" """Test re-configuration of already existing entry by ssdp."""
MockConfigEntry( MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
data={ data={
CONF_HOST: "wrong_host", CONF_HOST: current_host,
CONF_VERIFY_SSL: True, CONF_VERIFY_SSL: VERIFY_SSL,
CONF_USERNAME: USERNAME, CONF_USERNAME: USERNAME,
CONF_PASSWORD: PASSWORD, CONF_PASSWORD: PASSWORD,
CONF_MAC: MACS, CONF_MAC: MACS,
@ -560,7 +570,7 @@ async def test_skip_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> No
data=ssdp.SsdpServiceInfo( data=ssdp.SsdpServiceInfo(
ssdp_usn="mock_usn", ssdp_usn="mock_usn",
ssdp_st="mock_st", ssdp_st="mock_st",
ssdp_location="http://192.168.1.5:5000", ssdp_location=f"http://{new_host}:5000",
upnp={ upnp={
ssdp.ATTR_UPNP_FRIENDLY_NAME: "mydsm", ssdp.ATTR_UPNP_FRIENDLY_NAME: "mydsm",
ssdp.ATTR_UPNP_SERIAL: "001132XXXX59", # Existing in MACS[0], but SSDP does not have `-` ssdp.ATTR_UPNP_SERIAL: "001132XXXX59", # Existing in MACS[0], but SSDP does not have `-`