diff --git a/homeassistant/components/enphase_envoy/config_flow.py b/homeassistant/components/enphase_envoy/config_flow.py index 1a2186d305e..031d1883d1f 100644 --- a/homeassistant/components/enphase_envoy/config_flow.py +++ b/homeassistant/components/enphase_envoy/config_flow.py @@ -13,7 +13,6 @@ import voluptuous as vol from homeassistant.components import zeroconf from homeassistant.config_entries import ( SOURCE_REAUTH, - ConfigEntry, ConfigFlow, ConfigFlowResult, OptionsFlow, @@ -43,12 +42,28 @@ INSTALLER_AUTH_USERNAME = "installer" async def validate_input( - hass: HomeAssistant, host: str, username: str, password: str + hass: HomeAssistant, + host: str, + username: str, + password: str, + errors: dict[str, str], + description_placeholders: dict[str, str], ) -> Envoy: """Validate the user input allows us to connect.""" envoy = Envoy(host, get_async_client(hass, verify_ssl=False)) - await envoy.setup() - await envoy.authenticate(username=username, password=password) + try: + await envoy.setup() + await envoy.authenticate(username=username, password=password) + except INVALID_AUTH_ERRORS as e: + errors["base"] = "invalid_auth" + description_placeholders["reason"] = str(e) + except EnvoyError as e: + errors["base"] = "cannot_connect" + description_placeholders["reason"] = str(e) + except Exception: + _LOGGER.exception("Unexpected exception") + errors["base"] = "unknown" + return envoy @@ -57,8 +72,6 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN): VERSION = 1 - _reauth_entry: ConfigEntry - def __init__(self) -> None: """Initialize an envoy flow.""" self.ip_address: str | None = None @@ -159,10 +172,43 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN): self, entry_data: Mapping[str, Any] ) -> ConfigFlowResult: """Handle configuration by re-auth.""" - self._reauth_entry = self._get_reauth_entry() - if unique_id := self._reauth_entry.unique_id: - await self.async_set_unique_id(unique_id, raise_on_progress=False) - return await self.async_step_user() + return await self.async_step_reauth_confirm() + + async def async_step_reauth_confirm( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """Dialog that informs the user that reauth is required.""" + reauth_entry = self._get_reauth_entry() + errors: dict[str, str] = {} + description_placeholders: dict[str, str] = {} + + if user_input is not None: + await validate_input( + self.hass, + reauth_entry.data[CONF_HOST], + user_input[CONF_USERNAME], + user_input[CONF_PASSWORD], + errors, + description_placeholders, + ) + if not errors: + return self.async_update_reload_and_abort( + reauth_entry, + data_updates=user_input, + ) + + serial = reauth_entry.unique_id or "-" + self.context["title_placeholders"] = { + CONF_SERIAL: serial, + CONF_HOST: reauth_entry.data[CONF_HOST], + } + description_placeholders["serial"] = serial + return self.async_show_form( + step_id="reauth_confirm", + data_schema=self._async_generate_schema(), + description_placeholders=description_placeholders, + errors=errors, + ) def _async_envoy_name(self) -> str: """Return the name of the envoy.""" @@ -174,38 +220,20 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN): """Handle the initial step.""" errors: dict[str, str] = {} description_placeholders: dict[str, str] = {} - - if self.source == SOURCE_REAUTH: - host = self._reauth_entry.data[CONF_HOST] - else: - host = (user_input or {}).get(CONF_HOST) or self.ip_address or "" + host = (user_input or {}).get(CONF_HOST) or self.ip_address or "" if user_input is not None: - try: - envoy = await validate_input( - self.hass, - host, - user_input[CONF_USERNAME], - user_input[CONF_PASSWORD], - ) - except INVALID_AUTH_ERRORS as e: - errors["base"] = "invalid_auth" - description_placeholders = {"reason": str(e)} - except EnvoyError as e: - errors["base"] = "cannot_connect" - description_placeholders = {"reason": str(e)} - except Exception: - _LOGGER.exception("Unexpected exception") - errors["base"] = "unknown" - else: + envoy = await validate_input( + self.hass, + host, + user_input[CONF_USERNAME], + user_input[CONF_PASSWORD], + errors, + description_placeholders, + ) + if not errors: name = self._async_envoy_name() - if self.source == SOURCE_REAUTH: - return self.async_update_reload_and_abort( - self._reauth_entry, - data=self._reauth_entry.data | user_input, - ) - if not self.unique_id: await self.async_set_unique_id(envoy.serial_number) name = self._async_envoy_name() @@ -251,23 +279,15 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN): host: str = user_input[CONF_HOST] username: str = user_input[CONF_USERNAME] password: str = user_input[CONF_PASSWORD] - try: - envoy = await validate_input( - self.hass, - host, - username, - password, - ) - except INVALID_AUTH_ERRORS as e: - errors["base"] = "invalid_auth" - description_placeholders = {"reason": str(e)} - except EnvoyError as e: - errors["base"] = "cannot_connect" - description_placeholders = {"reason": str(e)} - except Exception: # pylint: disable=broad-except - _LOGGER.exception("Unexpected exception") - errors["base"] = "unknown" - else: + envoy = await validate_input( + self.hass, + host, + username, + password, + errors, + description_placeholders, + ) + if not errors: await self.async_set_unique_id(envoy.serial_number) self._abort_if_unique_id_mismatch() return self.async_update_reload_and_abort( @@ -279,10 +299,12 @@ class EnphaseConfigFlow(ConfigFlow, domain=DOMAIN): }, ) + serial = reconfigure_entry.unique_id or "-" self.context["title_placeholders"] = { - CONF_SERIAL: reconfigure_entry.unique_id or "-", + CONF_SERIAL: serial, CONF_HOST: reconfigure_entry.data[CONF_HOST], } + description_placeholders["serial"] = serial suggested_values: Mapping[str, Any] = user_input or reconfigure_entry.data return self.async_show_form( diff --git a/homeassistant/components/enphase_envoy/quality_scale.yaml b/homeassistant/components/enphase_envoy/quality_scale.yaml index 4708a3cc11a..9e5b3a5921e 100644 --- a/homeassistant/components/enphase_envoy/quality_scale.yaml +++ b/homeassistant/components/enphase_envoy/quality_scale.yaml @@ -11,8 +11,7 @@ rules: config-flow-test-coverage: done config-flow: status: todo - comment: | - - async_step_reaut L160: I believe that the unique is already set when starting a reauth flow + comment: Even though redundant as explained in PR133726, add data-description fields for config-flow steps dependency-transparency: done docs-actions: status: done diff --git a/homeassistant/components/enphase_envoy/strings.json b/homeassistant/components/enphase_envoy/strings.json index a78d0bc032a..9747fa35a82 100644 --- a/homeassistant/components/enphase_envoy/strings.json +++ b/homeassistant/components/enphase_envoy/strings.json @@ -23,6 +23,13 @@ "data_description": { "host": "[%key:component::enphase_envoy::config::step::user::data_description::host%]" } + }, + "reauth_confirm": { + "description": "[%key:component::enphase_envoy::config::step::user::description%]", + "data": { + "username": "[%key:common::config_flow::data::username%]", + "password": "[%key:common::config_flow::data::password%]" + } } }, "error": {