From c2c26e2608b3f676424dd08f730ce4c49c8b319e Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 7 Nov 2022 21:19:57 -0600 Subject: [PATCH] Fix check for duplicate config entry reauth when context is passed or augmented (#81753) fixes https://github.com/home-assistant/core/issues/77578 --- homeassistant/config_entries.py | 29 +++++++++++++++-------------- tests/test_config_entries.py | 15 ++++++++++++++- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py index 8e618deb3d2..b7ee9a4d654 100644 --- a/homeassistant/config_entries.py +++ b/homeassistant/config_entries.py @@ -660,24 +660,25 @@ class ConfigEntry: data: dict[str, Any] | None = None, ) -> None: """Start a reauth flow.""" - flow_context = { - "source": SOURCE_REAUTH, - "entry_id": self.entry_id, - "title_placeholders": {"name": self.title}, - "unique_id": self.unique_id, - } - - if context: - flow_context.update(context) - - for flow in hass.config_entries.flow.async_progress_by_handler(self.domain): - if flow["context"] == flow_context: - return + if any( + flow + for flow in hass.config_entries.flow.async_progress() + if flow["context"].get("source") == SOURCE_REAUTH + and flow["context"].get("entry_id") == self.entry_id + ): + # Reauth flow already in progress for this entry + return hass.async_create_task( hass.config_entries.flow.async_init( self.domain, - context=flow_context, + context={ + "source": SOURCE_REAUTH, + "entry_id": self.entry_id, + "title_placeholders": {"name": self.title}, + "unique_id": self.unique_id, + } + | (context or {}), data=self.data | (data or {}), ) ) diff --git a/tests/test_config_entries.py b/tests/test_config_entries.py index 83343146d47..99e26be6d75 100644 --- a/tests/test_config_entries.py +++ b/tests/test_config_entries.py @@ -3287,6 +3287,7 @@ async def test_disallow_entry_reload_with_setup_in_progresss(hass, manager): async def test_reauth(hass): """Test the async_reauth_helper.""" entry = MockConfigEntry(title="test_title", domain="test") + entry2 = MockConfigEntry(title="test_title", domain="test") mock_setup_entry = AsyncMock(return_value=True) mock_integration(hass, MockModule("test", async_setup_entry=mock_setup_entry)) @@ -3313,7 +3314,19 @@ async def test_reauth(hass): assert mock_init.call_args.kwargs["data"]["extra_data"] == 1234 + assert entry.entry_id != entry2.entry_id + # Check we can't start duplicate flows entry.async_start_reauth(hass, {"extra_context": "some_extra_context"}) await hass.async_block_till_done() - assert len(flows) == 1 + assert len(hass.config_entries.flow.async_progress()) == 1 + + # Check we can't start duplicate when the context context is different + entry.async_start_reauth(hass, {"diff": "diff"}) + await hass.async_block_till_done() + assert len(hass.config_entries.flow.async_progress()) == 1 + + # Check we can start a reauth for a different entry + entry2.async_start_reauth(hass, {"extra_context": "some_extra_context"}) + await hass.async_block_till_done() + assert len(hass.config_entries.flow.async_progress()) == 2