Fix URL parsing for hyphenated hostnames in Radarr/Sonarr config flows (#171193)

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
Aldo
2026-07-26 23:08:00 +02:00
committed by GitHub
co-authored by Joost Lekkerkerker
parent 693006dc84
commit 068f6a45ee
4 changed files with 59 additions and 17 deletions
@@ -47,11 +47,13 @@ class RadarrConfigFlow(ConfigFlow, domain=DOMAIN):
errors = {}
if user_input is not None:
# aiopyarr defaults to the service port if one isn't given
# this is counter to standard practice where http = 80
# and https = 443.
# Ensure an explicit port is present in the URL so that
# aiopyarr does not fall back to its own service-port default
# (which differs from the standard HTTP/HTTPS ports).
url = URL(user_input[CONF_URL])
user_input[CONF_URL] = f"{url.scheme}://{url.host}:{url.port}{url.path}"
if url.explicit_port is None:
url = url.with_port(url.port)
user_input[CONF_URL] = url.human_repr()
try:
if result := await validate_input(self.hass, user_input):
@@ -100,12 +100,14 @@ class SonarrConfigFlow(ConfigFlow, domain=DOMAIN):
CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL
)
# aiopyarr defaults to the service port if one isn't given
# this is counter to standard practice where http = 80
# and https = 443.
# Ensure an explicit port is present in the URL so that
# aiopyarr does not fall back to its own service-port default
# (which differs from the standard HTTP/HTTPS ports).
if CONF_URL in user_input:
url = yarl.URL(user_input[CONF_URL])
user_input[CONF_URL] = f"{url.scheme}://{url.host}:{url.port}{url.path}"
if url.explicit_port is None:
url = url.with_port(url.port)
user_input[CONF_URL] = url.human_repr()
if self.source == SOURCE_REAUTH:
user_input = {**self._get_reauth_entry().data, **user_input}
+21 -4
View File
@@ -140,24 +140,41 @@ async def test_zero_conf(hass: HomeAssistant) -> None:
assert result["data"] == CONF_DATA
async def test_url_rewrite(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(
("input_url", "expected_url"),
[
pytest.param(
"https://192.168.1.100/",
"https://192.168.1.100:443/",
id="ip_without_port",
),
pytest.param(
"https://radarr-anime.example.com/",
"https://radarr-anime.example.com:443/",
id="hyphenated_hostname",
),
],
)
async def test_url_rewrite(
hass: HomeAssistant, input_url: str, expected_url: str
) -> None:
"""Test auth flow url rewrite."""
with (
patch(
"homeassistant.components.radarr.config_flow.RadarrClient.async_try_zeroconf",
return_value=("v3", API_KEY, "/test"),
return_value=("v3", API_KEY, "/"),
),
patch_async_setup_entry(),
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={CONF_SOURCE: SOURCE_USER},
data={CONF_URL: "https://192.168.1.100/test", CONF_VERIFY_SSL: False},
data={CONF_URL: input_url, CONF_VERIFY_SSL: False},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == DEFAULT_NAME
assert result["data"][CONF_URL] == "https://192.168.1.100:443/test"
assert result["data"][CONF_URL] == expected_url
@pytest.mark.freeze_time("2021-12-03 00:00:00+00:00")
+26 -5
View File
@@ -52,11 +52,32 @@ async def test_cannot_connect(
assert result["errors"] == {"base": "cannot_connect"}
@pytest.mark.parametrize(
("input_url", "expected_url", "expected_title"),
[
pytest.param(
"https://192.168.1.189",
"https://192.168.1.189:443/",
"192.168.1.189",
id="ip_without_port",
),
pytest.param(
"https://sonarr-anime.example.com/",
"https://sonarr-anime.example.com:443/",
"sonarr-anime.example.com",
id="hyphenated_hostname",
),
],
)
@pytest.mark.usefixtures("mock_setup_entry")
async def test_url_rewrite(
hass: HomeAssistant, mock_sonarr_config_flow: MagicMock
hass: HomeAssistant,
mock_sonarr_config_flow: MagicMock,
input_url: str,
expected_url: str,
expected_title: str,
) -> None:
"""Test the full manual user flow from start to finish."""
"""Test auth flow url rewrite."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={CONF_SOURCE: SOURCE_USER},
@@ -66,17 +87,17 @@ async def test_url_rewrite(
assert result["step_id"] == "user"
user_input = MOCK_USER_INPUT.copy()
user_input[CONF_URL] = "https://192.168.1.189"
user_input[CONF_URL] = input_url
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=user_input,
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "192.168.1.189"
assert result["title"] == expected_title
assert result["data"]
assert result["data"][CONF_URL] == "https://192.168.1.189:443/"
assert result["data"][CONF_URL] == expected_url
async def test_invalid_auth(