From 4a464f601c780409e2bbf2d3cfbe026013910aa5 Mon Sep 17 00:00:00 2001 From: Robert Resch Date: Fri, 19 Dec 2025 15:50:47 +0100 Subject: [PATCH] Remove users refresh tokens when the user get's deactivated (#159443) --- homeassistant/auth/__init__.py | 2 ++ tests/auth/test_init.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/homeassistant/auth/__init__.py b/homeassistant/auth/__init__.py index afe3b2d7aa3..e16c29ceaa8 100644 --- a/homeassistant/auth/__init__.py +++ b/homeassistant/auth/__init__.py @@ -402,6 +402,8 @@ class AuthManager: if user.is_owner: raise ValueError("Unable to deactivate the owner") await self._store.async_deactivate_user(user) + for refresh_token in list(user.refresh_tokens.values()): + self.async_remove_refresh_token(refresh_token) async def async_remove_credentials(self, credentials: models.Credentials) -> None: """Remove credentials.""" diff --git a/tests/auth/test_init.py b/tests/auth/test_init.py index 4cf6b2cc5f7..7fe70117db3 100644 --- a/tests/auth/test_init.py +++ b/tests/auth/test_init.py @@ -577,6 +577,26 @@ async def test_cannot_deactive_owner(mock_hass) -> None: await manager.async_deactivate_user(owner) +async def test_deactivate_user_removes_refresh_tokens(hass: HomeAssistant) -> None: + """Test that deactivating a user removes their refresh tokens.""" + manager = await auth.auth_manager_from_config(hass, [], []) + user = MockUser().add_to_auth_manager(manager) + + refresh_token1 = await manager.async_create_refresh_token(user, CLIENT_ID) + refresh_token2 = await manager.async_create_refresh_token(user, "other-client") + assert len(user.refresh_tokens) == 2 + assert manager.async_get_refresh_token(refresh_token1.id) == refresh_token1 + assert manager.async_get_refresh_token(refresh_token2.id) == refresh_token2 + + await manager.async_deactivate_user(user) + + # Verify user is deactivated and all refresh tokens are removed + assert user.is_active is False + assert len(user.refresh_tokens) == 0 + assert manager.async_get_refresh_token(refresh_token1.id) is None + assert manager.async_get_refresh_token(refresh_token2.id) is None + + async def test_remove_refresh_token(hass: HomeAssistant) -> None: """Test that we can remove a refresh token.""" manager = await auth.auth_manager_from_config(hass, [], [])