Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 37b845d

Browse files
author
David Robertson
authored
Don't remove local users from dir when the leave their last room (#11103)
1 parent e09be0c commit 37b845d

File tree

3 files changed

+59
-5
lines changed

3 files changed

+59
-5
lines changed

changelog.d/11103.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix local users who left all their rooms being removed from the user directory, even if the "search_all_users" config option was enabled.

synapse/handlers/user_directory.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -415,16 +415,19 @@ async def _handle_remove_user(self, room_id: str, user_id: str) -> None:
415415
room_id: The room ID that user left or stopped being public that
416416
user_id
417417
"""
418-
logger.debug("Removing user %r", user_id)
418+
logger.debug("Removing user %r from room %r", user_id, room_id)
419419

420420
# Remove user from sharing tables
421421
await self.store.remove_user_who_share_room(user_id, room_id)
422422

423-
# Are they still in any rooms? If not, remove them entirely.
424-
rooms_user_is_in = await self.store.get_user_dir_rooms_user_is_in(user_id)
423+
# Additionally, if they're a remote user and we're no longer joined
424+
# to any rooms they're in, remove them from the user directory.
425+
if not self.is_mine_id(user_id):
426+
rooms_user_is_in = await self.store.get_user_dir_rooms_user_is_in(user_id)
425427

426-
if len(rooms_user_is_in) == 0:
427-
await self.store.remove_from_user_dir(user_id)
428+
if len(rooms_user_is_in) == 0:
429+
logger.debug("Removing user %r from directory", user_id)
430+
await self.store.remove_from_user_dir(user_id)
428431

429432
async def _handle_possible_remote_profile_change(
430433
self,

tests/handlers/test_user_directory.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,56 @@ def _add_user_to_room(
914914
self.hs.get_storage().persistence.persist_event(event, context)
915915
)
916916

917+
def test_local_user_leaving_room_remains_in_user_directory(self) -> None:
918+
"""We've chosen to simplify the user directory's implementation by
919+
always including local users. Ensure this invariant is maintained when
920+
a local user
921+
- leaves a room, and
922+
- leaves the last room they're in which is visible to this server.
923+
924+
This is user-visible if the "search_all_users" config option is on: the
925+
local user who left a room would no longer be searchable if this test fails!
926+
"""
927+
alice = self.register_user("alice", "pass")
928+
alice_token = self.login(alice, "pass")
929+
bob = self.register_user("bob", "pass")
930+
bob_token = self.login(bob, "pass")
931+
932+
# Alice makes two public rooms, which Bob joins.
933+
room1 = self.helper.create_room_as(alice, is_public=True, tok=alice_token)
934+
room2 = self.helper.create_room_as(alice, is_public=True, tok=alice_token)
935+
self.helper.join(room1, bob, tok=bob_token)
936+
self.helper.join(room2, bob, tok=bob_token)
937+
938+
# The user directory tables are updated.
939+
users, in_public, in_private = self.get_success(
940+
self.user_dir_helper.get_tables()
941+
)
942+
self.assertEqual(users, {alice, bob})
943+
self.assertEqual(
944+
in_public, {(alice, room1), (alice, room2), (bob, room1), (bob, room2)}
945+
)
946+
self.assertEqual(in_private, set())
947+
948+
# Alice leaves one room. She should still be in the directory.
949+
self.helper.leave(room1, alice, tok=alice_token)
950+
users, in_public, in_private = self.get_success(
951+
self.user_dir_helper.get_tables()
952+
)
953+
self.assertEqual(users, {alice, bob})
954+
self.assertEqual(in_public, {(alice, room2), (bob, room1), (bob, room2)})
955+
self.assertEqual(in_private, set())
956+
957+
# Alice leaves the other. She should still be in the directory.
958+
self.helper.leave(room2, alice, tok=alice_token)
959+
self.wait_for_background_updates()
960+
users, in_public, in_private = self.get_success(
961+
self.user_dir_helper.get_tables()
962+
)
963+
self.assertEqual(users, {alice, bob})
964+
self.assertEqual(in_public, {(bob, room1), (bob, room2)})
965+
self.assertEqual(in_private, set())
966+
917967

918968
class TestUserDirSearchDisabled(unittest.HomeserverTestCase):
919969
servlets = [

0 commit comments

Comments
 (0)