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, [], [])