From 9249ea0dbb7d3872afbf521a5b1cef749300a482 Mon Sep 17 00:00:00 2001 From: Manu <4445816+tr4nt0r@users.noreply.github.com> Date: Tue, 22 Apr 2025 14:11:09 +0200 Subject: [PATCH] Abort reauth flow on unique id mismatch in ista EcoTrend integration (#143430) --- .../components/ista_ecotrend/__init__.py | 1 + .../components/ista_ecotrend/config_flow.py | 15 +++++++- .../components/ista_ecotrend/strings.json | 3 +- .../ista_ecotrend/test_config_flow.py | 34 +++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/ista_ecotrend/__init__.py b/homeassistant/components/ista_ecotrend/__init__.py index 4b698139260..e39850d6c51 100644 --- a/homeassistant/components/ista_ecotrend/__init__.py +++ b/homeassistant/components/ista_ecotrend/__init__.py @@ -10,6 +10,7 @@ from homeassistant.components.recorder import get_instance from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform from homeassistant.core import HomeAssistant +from .const import DOMAIN from .coordinator import IstaConfigEntry, IstaCoordinator _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/ista_ecotrend/config_flow.py b/homeassistant/components/ista_ecotrend/config_flow.py index 1a3b2109d0c..8c08d8d5ada 100644 --- a/homeassistant/components/ista_ecotrend/config_flow.py +++ b/homeassistant/components/ista_ecotrend/config_flow.py @@ -100,8 +100,19 @@ class IstaConfigFlow(ConfigFlow, domain=DOMAIN): user_input[CONF_PASSWORD], _LOGGER, ) + + def get_consumption_units() -> set[str]: + ista.login() + consumption_units = ista.get_consumption_unit_details()[ + "consumptionUnits" + ] + return {unit["id"] for unit in consumption_units} + try: - await self.hass.async_add_executor_job(ista.login) + consumption_units = await self.hass.async_add_executor_job( + get_consumption_units + ) + except ServerError: errors["base"] = "cannot_connect" except (LoginError, KeycloakError): @@ -110,6 +121,8 @@ class IstaConfigFlow(ConfigFlow, domain=DOMAIN): _LOGGER.exception("Unexpected exception") errors["base"] = "unknown" else: + if reauth_entry.unique_id not in consumption_units: + return self.async_abort(reason="unique_id_mismatch") return self.async_update_reload_and_abort(reauth_entry, data=user_input) return self.async_show_form( diff --git a/homeassistant/components/ista_ecotrend/strings.json b/homeassistant/components/ista_ecotrend/strings.json index e7c37461b19..466969f9ba0 100644 --- a/homeassistant/components/ista_ecotrend/strings.json +++ b/homeassistant/components/ista_ecotrend/strings.json @@ -2,7 +2,8 @@ "config": { "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]", - "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" + "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]", + "unique_id_mismatch": "The login details correspond to a different account. Please re-authenticate to the previously configured account." }, "error": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", diff --git a/tests/components/ista_ecotrend/test_config_flow.py b/tests/components/ista_ecotrend/test_config_flow.py index e29c12f01f2..f5110988585 100644 --- a/tests/components/ista_ecotrend/test_config_flow.py +++ b/tests/components/ista_ecotrend/test_config_flow.py @@ -204,3 +204,37 @@ async def test_form__already_configured( assert result["type"] is FlowResultType.ABORT assert result["reason"] == "already_configured" + + +@pytest.mark.usefixtures("mock_ista") +async def test_flow_reauth_unique_id_mismatch(hass: HomeAssistant) -> None: + """Test reauth flow unique id mismatch.""" + + config_entry = MockConfigEntry( + domain=DOMAIN, + data={ + CONF_EMAIL: "test@example.com", + CONF_PASSWORD: "test-password", + }, + unique_id="42243134-21f6-40a2-a79f-e417a3a12104", + ) + + config_entry.add_to_hass(hass) + result = await config_entry.start_reauth_flow(hass) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "reauth_confirm" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + { + CONF_EMAIL: "new@example.com", + CONF_PASSWORD: "new-password", + }, + ) + + await hass.async_block_till_done() + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "unique_id_mismatch" + + assert len(hass.config_entries.async_entries()) == 1