diff --git a/blog/2024-10-21-reauth-reconfigure-helpers.md b/blog/2024-10-21-reauth-reconfigure-helpers.md new file mode 100644 index 00000000..a5d454c1 --- /dev/null +++ b/blog/2024-10-21-reauth-reconfigure-helpers.md @@ -0,0 +1,21 @@ +--- +author: epenet +authorURL: https://github.com/epenet +title: "New helpers and best practises for reauth and reconfigure flows" +--- + +New helper methods have been added to the ConfigFlow to facilitate management of reauth and reconfigure flows: +- `self._get_reauth_entry()` and `self._get_reconfigure_entry()` give access at any time to the corresponding config entry + - these should be used over `self.hass.config_entries.async_get_entry(self.context["entry_id"])` + - the config entry should be requested when needed (local variable, once per step) and not cached as class attributes + - if the steps are shared with discovery or user flows, `self.source` should be checked against `SOURCE_REAUTH` and `SOURCE_RECONFIGURE` before accessing the entry +- `self._abort_if_unique_id_mismatch` allows you to abort if the `unique_id` does not match the `unique_id` of the config entry to reauthenticate or reconfigure + - this should be used after a call to `self.async_set_unique_id` + - if the steps are shared with discovery or user flows, `self.source` should be checked against `SOURCE_REAUTH` and `SOURCE_RECONFIGURE` + - other sources should continue to use `self._abort_if_unique_id_configured` +- `self.async_update_reload_and_abort` has been adjusted to update the default message for reconfigure flows + - the new message `reconfigure_successful` must be present in `strings.json` +- `self.async_update_reload_and_abort` has a new argument `data_updates` to merge the data updates with the pre-existing data + - this is preferred over the `data` argument, as it reduces the risk of data loss if the schema is updated + +More details can be found in the [reconfigure](/docs/config_entries_config_flow_handler#reconfigure) and [reauthentication](/docs/config_entries_config_flow_handler#reauthentication) documentation. diff --git a/docs/config_entries_config_flow_handler.md b/docs/config_entries_config_flow_handler.md index fdeddb65..19677450 100644 --- a/docs/config_entries_config_flow_handler.md +++ b/docs/config_entries_config_flow_handler.md @@ -284,9 +284,11 @@ class ExampleConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): async def async_step_reconfigure(self, user_input: dict[str, Any] | None = None): if user_input is not None: # TODO: process user input + self.async_set_unique_id(user_id) + self._abort_if_unique_id_mismatch() return self.async_update_reload_and_abort( - self._get_reauth_entry(), - data=data, + self._get_reconfigure_entry(), + data_updates=data, ) return self.async_show_form( @@ -360,11 +362,14 @@ class OAuth2FlowHandler( async def async_oauth_create_entry(self, data: dict) -> dict: """Create an oauth config entry or update existing entry for reauth.""" + self.async_set_unique_id(user_id) if self.source == SOURCE_REAUTH: + self._abort_if_unique_id_mismatch() return self.async_update_reload_and_abort( self._get_reauth_entry(), - data=data, + data_updates=data, ) + self._abort_if_unique_id_configured() return await super().async_oauth_create_entry(data) ```