diff options
-rw-r--r-- | synapse/handlers/user_directory.py | 10 | ||||
-rw-r--r-- | tests/handlers/test_user_directory.py | 29 |
2 files changed, 35 insertions, 4 deletions
diff --git a/synapse/handlers/user_directory.py b/synapse/handlers/user_directory.py index 22905eda12..de7ecd42b8 100644 --- a/synapse/handlers/user_directory.py +++ b/synapse/handlers/user_directory.py @@ -413,11 +413,13 @@ class UserDirectoryHandler(StateDeltasHandler): # Remove user from sharing tables await self.store.remove_user_who_share_room(user_id, room_id) - # Are they still in any rooms? If not, remove them entirely. - rooms_user_is_in = await self.store.get_user_dir_rooms_user_is_in(user_id) + # If they're a remote user and not in any rooms we can see, + # remove their user_directory entry. + if not self.is_mine_id(user_id): + rooms_user_is_in = await self.store.get_user_dir_rooms_user_is_in(user_id) - if len(rooms_user_is_in) == 0: - await self.store.remove_from_user_dir(user_id) + if len(rooms_user_is_in) == 0: + await self.store.remove_from_user_dir(user_id) async def _handle_possible_remote_profile_change( self, diff --git a/tests/handlers/test_user_directory.py b/tests/handlers/test_user_directory.py index db65253773..07d9df47d0 100644 --- a/tests/handlers/test_user_directory.py +++ b/tests/handlers/test_user_directory.py @@ -503,6 +503,35 @@ class UserDirectoryTestCase(unittest.HomeserverTestCase): 0, ) + def test_local_user_remains_in_directory_after_leaving_all_rooms(self) -> None: + """We should preserve the invariant that local, non-excluded users are + always in the user_directory table. + + This is a choice to simplify the implementation, and also ensure that + the config option to search for all users works in this case.""" + alice = self.register_user("alice", "pass") + alice_token = self.login(alice, "pass") + + # Alice should have a user directory entry created at registration. + users = self.get_success(self.user_dir_helper.get_profiles_in_user_directory()) + self.assertEqual( + users, {alice: ProfileInfo(display_name="alice", avatar_url=None)} + ) + + # Alice makes a room for herself. + room = self.helper.create_room_as(alice, tok=alice_token) + + # Alice leaves that room. + self.helper.leave(room, alice, tok=alice_token) + + # Wait for background updates to ensure that the user directory handler + # handler has processed all events. Alice should remain in the directory. + self.wait_for_background_updates() + users = self.get_success(self.user_dir_helper.get_profiles_in_user_directory()) + self.assertEqual( + users, {alice: ProfileInfo(display_name="alice", avatar_url=None)} + ) + def test_private_room(self) -> None: """ A user can be searched for only by people that are either in a public |