From 4e7f39e3d08acf4bfde70c2caf20926e5cd70bec Mon Sep 17 00:00:00 2001 From: Michael <35783820+mib1185@users.noreply.github.com> Date: Thu, 27 Apr 2023 00:52:17 +0200 Subject: [PATCH] Fix reconfigure by SSDP or Zeroconf discovery in Synology DSM (#92088) --- .../components/synology_dsm/config_flow.py | 21 +++++-------------- .../synology_dsm/test_config_flow.py | 20 +++++++++++++----- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/synology_dsm/config_flow.py b/homeassistant/components/synology_dsm/config_flow.py index 9342849b2fe..36eb37b7882 100644 --- a/homeassistant/components/synology_dsm/config_flow.py +++ b/homeassistant/components/synology_dsm/config_flow.py @@ -2,7 +2,7 @@ from __future__ import annotations from collections.abc import Mapping -from ipaddress import ip_address +from ipaddress import ip_address as ip import logging from typing import Any, cast 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 import homeassistant.helpers.config_validation as cv from homeassistant.helpers.typing import DiscoveryInfoType +from homeassistant.util.network import is_ip_address as is_ip from .const import ( 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: """Format a mac address to the format used by Synology DSM.""" return mac.replace(":", "").replace("-", "").upper() @@ -284,16 +277,12 @@ class SynologyDSMFlowHandler(ConfigFlow, domain=DOMAIN): break 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 ( existing_entry + and is_ip(existing_entry.data[CONF_HOST]) + and is_ip(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( "Update host from '%s' to '%s' for NAS '%s' via discovery", diff --git a/tests/components/synology_dsm/test_config_flow.py b/tests/components/synology_dsm/test_config_flow.py index 3852712f70d..ef4dee7c597 100644 --- a/tests/components/synology_dsm/test_config_flow.py +++ b/tests/components/synology_dsm/test_config_flow.py @@ -512,7 +512,7 @@ async def test_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> None: MockConfigEntry( domain=DOMAIN, data={ - CONF_HOST: "wrong_host", + CONF_HOST: "192.168.1.3", CONF_VERIFY_SSL: VERIFY_SSL, CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD, @@ -539,14 +539,24 @@ async def test_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> None: @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.""" MockConfigEntry( domain=DOMAIN, data={ - CONF_HOST: "wrong_host", - CONF_VERIFY_SSL: True, + CONF_HOST: current_host, + CONF_VERIFY_SSL: VERIFY_SSL, CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD, CONF_MAC: MACS, @@ -560,7 +570,7 @@ async def test_skip_reconfig_ssdp(hass: HomeAssistant, service: MagicMock) -> No data=ssdp.SsdpServiceInfo( ssdp_usn="mock_usn", ssdp_st="mock_st", - ssdp_location="http://192.168.1.5:5000", + ssdp_location=f"http://{new_host}:5000", upnp={ ssdp.ATTR_UPNP_FRIENDLY_NAME: "mydsm", ssdp.ATTR_UPNP_SERIAL: "001132XXXX59", # Existing in MACS[0], but SSDP does not have `-`