Skip to content
Snippets Groups Projects
Unverified Commit 37b845da authored by David Robertson's avatar David Robertson Committed by GitHub
Browse files

Don't remove local users from dir when the leave their last room (#11103)

parent e09be0c8
No related branches found
No related tags found
No related merge requests found
Fix local users who left all their rooms being removed from the user directory, even if the "search_all_users" config option was enabled.
\ No newline at end of file
...@@ -415,16 +415,19 @@ class UserDirectoryHandler(StateDeltasHandler): ...@@ -415,16 +415,19 @@ class UserDirectoryHandler(StateDeltasHandler):
room_id: The room ID that user left or stopped being public that room_id: The room ID that user left or stopped being public that
user_id user_id
""" """
logger.debug("Removing user %r", user_id) logger.debug("Removing user %r from room %r", user_id, room_id)
# Remove user from sharing tables # Remove user from sharing tables
await self.store.remove_user_who_share_room(user_id, room_id) await self.store.remove_user_who_share_room(user_id, room_id)
# Are they still in any rooms? If not, remove them entirely. # Additionally, if they're a remote user and we're no longer joined
rooms_user_is_in = await self.store.get_user_dir_rooms_user_is_in(user_id) # to any rooms they're in, remove them from the user directory.
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: if len(rooms_user_is_in) == 0:
await self.store.remove_from_user_dir(user_id) logger.debug("Removing user %r from directory", user_id)
await self.store.remove_from_user_dir(user_id)
async def _handle_possible_remote_profile_change( async def _handle_possible_remote_profile_change(
self, self,
......
...@@ -914,6 +914,56 @@ class UserDirectoryTestCase(unittest.HomeserverTestCase): ...@@ -914,6 +914,56 @@ class UserDirectoryTestCase(unittest.HomeserverTestCase):
self.hs.get_storage().persistence.persist_event(event, context) self.hs.get_storage().persistence.persist_event(event, context)
) )
def test_local_user_leaving_room_remains_in_user_directory(self) -> None:
"""We've chosen to simplify the user directory's implementation by
always including local users. Ensure this invariant is maintained when
a local user
- leaves a room, and
- leaves the last room they're in which is visible to this server.
This is user-visible if the "search_all_users" config option is on: the
local user who left a room would no longer be searchable if this test fails!
"""
alice = self.register_user("alice", "pass")
alice_token = self.login(alice, "pass")
bob = self.register_user("bob", "pass")
bob_token = self.login(bob, "pass")
# Alice makes two public rooms, which Bob joins.
room1 = self.helper.create_room_as(alice, is_public=True, tok=alice_token)
room2 = self.helper.create_room_as(alice, is_public=True, tok=alice_token)
self.helper.join(room1, bob, tok=bob_token)
self.helper.join(room2, bob, tok=bob_token)
# The user directory tables are updated.
users, in_public, in_private = self.get_success(
self.user_dir_helper.get_tables()
)
self.assertEqual(users, {alice, bob})
self.assertEqual(
in_public, {(alice, room1), (alice, room2), (bob, room1), (bob, room2)}
)
self.assertEqual(in_private, set())
# Alice leaves one room. She should still be in the directory.
self.helper.leave(room1, alice, tok=alice_token)
users, in_public, in_private = self.get_success(
self.user_dir_helper.get_tables()
)
self.assertEqual(users, {alice, bob})
self.assertEqual(in_public, {(alice, room2), (bob, room1), (bob, room2)})
self.assertEqual(in_private, set())
# Alice leaves the other. She should still be in the directory.
self.helper.leave(room2, alice, tok=alice_token)
self.wait_for_background_updates()
users, in_public, in_private = self.get_success(
self.user_dir_helper.get_tables()
)
self.assertEqual(users, {alice, bob})
self.assertEqual(in_public, {(bob, room1), (bob, room2)})
self.assertEqual(in_private, set())
class TestUserDirSearchDisabled(unittest.HomeserverTestCase): class TestUserDirSearchDisabled(unittest.HomeserverTestCase):
servlets = [ servlets = [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment