test_user_directory.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. # Copyright 2018 New Vector
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from unittest.mock import Mock
  15. from twisted.internet import defer
  16. import synapse.rest.admin
  17. from synapse.api.constants import EventTypes, RoomEncryptionAlgorithms, UserTypes
  18. from synapse.api.room_versions import RoomVersion, RoomVersions
  19. from synapse.rest.client.v1 import login, room
  20. from synapse.rest.client.v2_alpha import user_directory
  21. from synapse.storage.roommember import ProfileInfo
  22. from tests import unittest
  23. from tests.unittest import override_config
  24. class UserDirectoryTestCase(unittest.HomeserverTestCase):
  25. """
  26. Tests the UserDirectoryHandler.
  27. """
  28. servlets = [
  29. login.register_servlets,
  30. synapse.rest.admin.register_servlets_for_client_rest_resource,
  31. room.register_servlets,
  32. ]
  33. def make_homeserver(self, reactor, clock):
  34. config = self.default_config()
  35. config["update_user_directory"] = True
  36. return self.setup_test_homeserver(config=config)
  37. def prepare(self, reactor, clock, hs):
  38. self.store = hs.get_datastore()
  39. self.handler = hs.get_user_directory_handler()
  40. self.event_builder_factory = self.hs.get_event_builder_factory()
  41. self.event_creation_handler = self.hs.get_event_creation_handler()
  42. def test_handle_local_profile_change_with_support_user(self):
  43. support_user_id = "@support:test"
  44. self.get_success(
  45. self.store.register_user(
  46. user_id=support_user_id, password_hash=None, user_type=UserTypes.SUPPORT
  47. )
  48. )
  49. regular_user_id = "@regular:test"
  50. self.get_success(
  51. self.store.register_user(user_id=regular_user_id, password_hash=None)
  52. )
  53. self.get_success(
  54. self.handler.handle_local_profile_change(support_user_id, None)
  55. )
  56. profile = self.get_success(self.store.get_user_in_directory(support_user_id))
  57. self.assertTrue(profile is None)
  58. display_name = "display_name"
  59. profile_info = ProfileInfo(avatar_url="avatar_url", display_name=display_name)
  60. self.get_success(
  61. self.handler.handle_local_profile_change(regular_user_id, profile_info)
  62. )
  63. profile = self.get_success(self.store.get_user_in_directory(regular_user_id))
  64. self.assertTrue(profile["display_name"] == display_name)
  65. def test_handle_local_profile_change_with_deactivated_user(self):
  66. # create user
  67. r_user_id = "@regular:test"
  68. self.get_success(
  69. self.store.register_user(user_id=r_user_id, password_hash=None)
  70. )
  71. # update profile
  72. display_name = "Regular User"
  73. profile_info = ProfileInfo(avatar_url="avatar_url", display_name=display_name)
  74. self.get_success(
  75. self.handler.handle_local_profile_change(r_user_id, profile_info)
  76. )
  77. # profile is in directory
  78. profile = self.get_success(self.store.get_user_in_directory(r_user_id))
  79. self.assertTrue(profile["display_name"] == display_name)
  80. # deactivate user
  81. self.get_success(self.store.set_user_deactivated_status(r_user_id, True))
  82. self.get_success(self.handler.handle_user_deactivated(r_user_id))
  83. # profile is not in directory
  84. profile = self.get_success(self.store.get_user_in_directory(r_user_id))
  85. self.assertTrue(profile is None)
  86. # update profile after deactivation
  87. self.get_success(
  88. self.handler.handle_local_profile_change(r_user_id, profile_info)
  89. )
  90. # profile is furthermore not in directory
  91. profile = self.get_success(self.store.get_user_in_directory(r_user_id))
  92. self.assertTrue(profile is None)
  93. def test_handle_user_deactivated_support_user(self):
  94. s_user_id = "@support:test"
  95. self.get_success(
  96. self.store.register_user(
  97. user_id=s_user_id, password_hash=None, user_type=UserTypes.SUPPORT
  98. )
  99. )
  100. self.store.remove_from_user_dir = Mock(return_value=defer.succeed(None))
  101. self.get_success(self.handler.handle_user_deactivated(s_user_id))
  102. self.store.remove_from_user_dir.not_called()
  103. def test_handle_user_deactivated_regular_user(self):
  104. r_user_id = "@regular:test"
  105. self.get_success(
  106. self.store.register_user(user_id=r_user_id, password_hash=None)
  107. )
  108. self.store.remove_from_user_dir = Mock(return_value=defer.succeed(None))
  109. self.get_success(self.handler.handle_user_deactivated(r_user_id))
  110. self.store.remove_from_user_dir.called_once_with(r_user_id)
  111. def test_private_room(self):
  112. """
  113. A user can be searched for only by people that are either in a public
  114. room, or that share a private chat.
  115. """
  116. u1 = self.register_user("user1", "pass")
  117. u1_token = self.login(u1, "pass")
  118. u2 = self.register_user("user2", "pass")
  119. u2_token = self.login(u2, "pass")
  120. u3 = self.register_user("user3", "pass")
  121. # We do not add users to the directory until they join a room.
  122. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  123. self.assertEqual(len(s["results"]), 0)
  124. room = self.helper.create_room_as(u1, is_public=False, tok=u1_token)
  125. self.helper.invite(room, src=u1, targ=u2, tok=u1_token)
  126. self.helper.join(room, user=u2, tok=u2_token)
  127. # Check we have populated the database correctly.
  128. shares_private = self.get_users_who_share_private_rooms()
  129. public_users = self.get_users_in_public_rooms()
  130. self.assertEqual(
  131. self._compress_shared(shares_private), {(u1, u2, room), (u2, u1, room)}
  132. )
  133. self.assertEqual(public_users, [])
  134. # We get one search result when searching for user2 by user1.
  135. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  136. self.assertEqual(len(s["results"]), 1)
  137. # We get NO search results when searching for user2 by user3.
  138. s = self.get_success(self.handler.search_users(u3, "user2", 10))
  139. self.assertEqual(len(s["results"]), 0)
  140. # We get NO search results when searching for user3 by user1.
  141. s = self.get_success(self.handler.search_users(u1, "user3", 10))
  142. self.assertEqual(len(s["results"]), 0)
  143. # User 2 then leaves.
  144. self.helper.leave(room, user=u2, tok=u2_token)
  145. # Check we have removed the values.
  146. shares_private = self.get_users_who_share_private_rooms()
  147. public_users = self.get_users_in_public_rooms()
  148. self.assertEqual(self._compress_shared(shares_private), set())
  149. self.assertEqual(public_users, [])
  150. # User1 now gets no search results for any of the other users.
  151. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  152. self.assertEqual(len(s["results"]), 0)
  153. s = self.get_success(self.handler.search_users(u1, "user3", 10))
  154. self.assertEqual(len(s["results"]), 0)
  155. @override_config({"encryption_enabled_by_default_for_room_type": "all"})
  156. def test_encrypted_by_default_config_option_all(self):
  157. """Tests that invite-only and non-invite-only rooms have encryption enabled by
  158. default when the config option encryption_enabled_by_default_for_room_type is "all".
  159. """
  160. # Create a user
  161. user = self.register_user("user", "pass")
  162. user_token = self.login(user, "pass")
  163. # Create an invite-only room as that user
  164. room_id = self.helper.create_room_as(user, is_public=False, tok=user_token)
  165. # Check that the room has an encryption state event
  166. event_content = self.helper.get_state(
  167. room_id=room_id,
  168. event_type=EventTypes.RoomEncryption,
  169. tok=user_token,
  170. )
  171. self.assertEqual(event_content, {"algorithm": RoomEncryptionAlgorithms.DEFAULT})
  172. # Create a non invite-only room as that user
  173. room_id = self.helper.create_room_as(user, is_public=True, tok=user_token)
  174. # Check that the room has an encryption state event
  175. event_content = self.helper.get_state(
  176. room_id=room_id,
  177. event_type=EventTypes.RoomEncryption,
  178. tok=user_token,
  179. )
  180. self.assertEqual(event_content, {"algorithm": RoomEncryptionAlgorithms.DEFAULT})
  181. @override_config({"encryption_enabled_by_default_for_room_type": "invite"})
  182. def test_encrypted_by_default_config_option_invite(self):
  183. """Tests that only new, invite-only rooms have encryption enabled by default when
  184. the config option encryption_enabled_by_default_for_room_type is "invite".
  185. """
  186. # Create a user
  187. user = self.register_user("user", "pass")
  188. user_token = self.login(user, "pass")
  189. # Create an invite-only room as that user
  190. room_id = self.helper.create_room_as(user, is_public=False, tok=user_token)
  191. # Check that the room has an encryption state event
  192. event_content = self.helper.get_state(
  193. room_id=room_id,
  194. event_type=EventTypes.RoomEncryption,
  195. tok=user_token,
  196. )
  197. self.assertEqual(event_content, {"algorithm": RoomEncryptionAlgorithms.DEFAULT})
  198. # Create a non invite-only room as that user
  199. room_id = self.helper.create_room_as(user, is_public=True, tok=user_token)
  200. # Check that the room does not have an encryption state event
  201. self.helper.get_state(
  202. room_id=room_id,
  203. event_type=EventTypes.RoomEncryption,
  204. tok=user_token,
  205. expect_code=404,
  206. )
  207. @override_config({"encryption_enabled_by_default_for_room_type": "off"})
  208. def test_encrypted_by_default_config_option_off(self):
  209. """Tests that neither new invite-only nor non-invite-only rooms have encryption
  210. enabled by default when the config option
  211. encryption_enabled_by_default_for_room_type is "off".
  212. """
  213. # Create a user
  214. user = self.register_user("user", "pass")
  215. user_token = self.login(user, "pass")
  216. # Create an invite-only room as that user
  217. room_id = self.helper.create_room_as(user, is_public=False, tok=user_token)
  218. # Check that the room does not have an encryption state event
  219. self.helper.get_state(
  220. room_id=room_id,
  221. event_type=EventTypes.RoomEncryption,
  222. tok=user_token,
  223. expect_code=404,
  224. )
  225. # Create a non invite-only room as that user
  226. room_id = self.helper.create_room_as(user, is_public=True, tok=user_token)
  227. # Check that the room does not have an encryption state event
  228. self.helper.get_state(
  229. room_id=room_id,
  230. event_type=EventTypes.RoomEncryption,
  231. tok=user_token,
  232. expect_code=404,
  233. )
  234. def test_spam_checker(self):
  235. """
  236. A user which fails the spam checks will not appear in search results.
  237. """
  238. u1 = self.register_user("user1", "pass")
  239. u1_token = self.login(u1, "pass")
  240. u2 = self.register_user("user2", "pass")
  241. u2_token = self.login(u2, "pass")
  242. # We do not add users to the directory until they join a room.
  243. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  244. self.assertEqual(len(s["results"]), 0)
  245. room = self.helper.create_room_as(u1, is_public=False, tok=u1_token)
  246. self.helper.invite(room, src=u1, targ=u2, tok=u1_token)
  247. self.helper.join(room, user=u2, tok=u2_token)
  248. # Check we have populated the database correctly.
  249. shares_private = self.get_users_who_share_private_rooms()
  250. public_users = self.get_users_in_public_rooms()
  251. self.assertEqual(
  252. self._compress_shared(shares_private), {(u1, u2, room), (u2, u1, room)}
  253. )
  254. self.assertEqual(public_users, [])
  255. # We get one search result when searching for user2 by user1.
  256. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  257. self.assertEqual(len(s["results"]), 1)
  258. # Configure a spam checker that does not filter any users.
  259. spam_checker = self.hs.get_spam_checker()
  260. class AllowAll:
  261. async def check_username_for_spam(self, user_profile):
  262. # Allow all users.
  263. return False
  264. spam_checker.spam_checkers = [AllowAll()]
  265. # The results do not change:
  266. # We get one search result when searching for user2 by user1.
  267. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  268. self.assertEqual(len(s["results"]), 1)
  269. # Configure a spam checker that filters all users.
  270. class BlockAll:
  271. async def check_username_for_spam(self, user_profile):
  272. # All users are spammy.
  273. return True
  274. spam_checker.spam_checkers = [BlockAll()]
  275. # User1 now gets no search results for any of the other users.
  276. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  277. self.assertEqual(len(s["results"]), 0)
  278. def test_legacy_spam_checker(self):
  279. """
  280. A spam checker without the expected method should be ignored.
  281. """
  282. u1 = self.register_user("user1", "pass")
  283. u1_token = self.login(u1, "pass")
  284. u2 = self.register_user("user2", "pass")
  285. u2_token = self.login(u2, "pass")
  286. # We do not add users to the directory until they join a room.
  287. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  288. self.assertEqual(len(s["results"]), 0)
  289. room = self.helper.create_room_as(u1, is_public=False, tok=u1_token)
  290. self.helper.invite(room, src=u1, targ=u2, tok=u1_token)
  291. self.helper.join(room, user=u2, tok=u2_token)
  292. # Check we have populated the database correctly.
  293. shares_private = self.get_users_who_share_private_rooms()
  294. public_users = self.get_users_in_public_rooms()
  295. self.assertEqual(
  296. self._compress_shared(shares_private), {(u1, u2, room), (u2, u1, room)}
  297. )
  298. self.assertEqual(public_users, [])
  299. # Configure a spam checker.
  300. spam_checker = self.hs.get_spam_checker()
  301. # The spam checker doesn't need any methods, so create a bare object.
  302. spam_checker.spam_checker = object()
  303. # We get one search result when searching for user2 by user1.
  304. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  305. self.assertEqual(len(s["results"]), 1)
  306. def _compress_shared(self, shared):
  307. """
  308. Compress a list of users who share rooms dicts to a list of tuples.
  309. """
  310. r = set()
  311. for i in shared:
  312. r.add((i["user_id"], i["other_user_id"], i["room_id"]))
  313. return r
  314. def get_users_in_public_rooms(self):
  315. r = self.get_success(
  316. self.store.db_pool.simple_select_list(
  317. "users_in_public_rooms", None, ("user_id", "room_id")
  318. )
  319. )
  320. retval = []
  321. for i in r:
  322. retval.append((i["user_id"], i["room_id"]))
  323. return retval
  324. def get_users_who_share_private_rooms(self):
  325. return self.get_success(
  326. self.store.db_pool.simple_select_list(
  327. "users_who_share_private_rooms",
  328. None,
  329. ["user_id", "other_user_id", "room_id"],
  330. )
  331. )
  332. def _add_background_updates(self):
  333. """
  334. Add the background updates we need to run.
  335. """
  336. # Ugh, have to reset this flag
  337. self.store.db_pool.updates._all_done = False
  338. self.get_success(
  339. self.store.db_pool.simple_insert(
  340. "background_updates",
  341. {
  342. "update_name": "populate_user_directory_createtables",
  343. "progress_json": "{}",
  344. },
  345. )
  346. )
  347. self.get_success(
  348. self.store.db_pool.simple_insert(
  349. "background_updates",
  350. {
  351. "update_name": "populate_user_directory_process_rooms",
  352. "progress_json": "{}",
  353. "depends_on": "populate_user_directory_createtables",
  354. },
  355. )
  356. )
  357. self.get_success(
  358. self.store.db_pool.simple_insert(
  359. "background_updates",
  360. {
  361. "update_name": "populate_user_directory_process_users",
  362. "progress_json": "{}",
  363. "depends_on": "populate_user_directory_process_rooms",
  364. },
  365. )
  366. )
  367. self.get_success(
  368. self.store.db_pool.simple_insert(
  369. "background_updates",
  370. {
  371. "update_name": "populate_user_directory_cleanup",
  372. "progress_json": "{}",
  373. "depends_on": "populate_user_directory_process_users",
  374. },
  375. )
  376. )
  377. def test_initial(self):
  378. """
  379. The user directory's initial handler correctly updates the search tables.
  380. """
  381. u1 = self.register_user("user1", "pass")
  382. u1_token = self.login(u1, "pass")
  383. u2 = self.register_user("user2", "pass")
  384. u2_token = self.login(u2, "pass")
  385. u3 = self.register_user("user3", "pass")
  386. u3_token = self.login(u3, "pass")
  387. room = self.helper.create_room_as(u1, is_public=True, tok=u1_token)
  388. self.helper.invite(room, src=u1, targ=u2, tok=u1_token)
  389. self.helper.join(room, user=u2, tok=u2_token)
  390. private_room = self.helper.create_room_as(u1, is_public=False, tok=u1_token)
  391. self.helper.invite(private_room, src=u1, targ=u3, tok=u1_token)
  392. self.helper.join(private_room, user=u3, tok=u3_token)
  393. self.get_success(self.store.update_user_directory_stream_pos(None))
  394. self.get_success(self.store.delete_all_from_user_dir())
  395. shares_private = self.get_users_who_share_private_rooms()
  396. public_users = self.get_users_in_public_rooms()
  397. # Nothing updated yet
  398. self.assertEqual(shares_private, [])
  399. self.assertEqual(public_users, [])
  400. # Do the initial population of the user directory via the background update
  401. self._add_background_updates()
  402. while not self.get_success(
  403. self.store.db_pool.updates.has_completed_background_updates()
  404. ):
  405. self.get_success(
  406. self.store.db_pool.updates.do_next_background_update(100), by=0.1
  407. )
  408. shares_private = self.get_users_who_share_private_rooms()
  409. public_users = self.get_users_in_public_rooms()
  410. # User 1 and User 2 are in the same public room
  411. self.assertEqual(set(public_users), {(u1, room), (u2, room)})
  412. # User 1 and User 3 share private rooms
  413. self.assertEqual(
  414. self._compress_shared(shares_private),
  415. {(u1, u3, private_room), (u3, u1, private_room)},
  416. )
  417. def test_initial_share_all_users(self):
  418. """
  419. Search all users = True means that a user does not have to share a
  420. private room with the searching user or be in a public room to be search
  421. visible.
  422. """
  423. self.handler.search_all_users = True
  424. self.hs.config.user_directory_search_all_users = True
  425. u1 = self.register_user("user1", "pass")
  426. self.register_user("user2", "pass")
  427. u3 = self.register_user("user3", "pass")
  428. # Wipe the user dir
  429. self.get_success(self.store.update_user_directory_stream_pos(None))
  430. self.get_success(self.store.delete_all_from_user_dir())
  431. # Do the initial population of the user directory via the background update
  432. self._add_background_updates()
  433. while not self.get_success(
  434. self.store.db_pool.updates.has_completed_background_updates()
  435. ):
  436. self.get_success(
  437. self.store.db_pool.updates.do_next_background_update(100), by=0.1
  438. )
  439. shares_private = self.get_users_who_share_private_rooms()
  440. public_users = self.get_users_in_public_rooms()
  441. # No users share rooms
  442. self.assertEqual(public_users, [])
  443. self.assertEqual(self._compress_shared(shares_private), set())
  444. # Despite not sharing a room, search_all_users means we get a search
  445. # result.
  446. s = self.get_success(self.handler.search_users(u1, u3, 10))
  447. self.assertEqual(len(s["results"]), 1)
  448. # We can find the other two users
  449. s = self.get_success(self.handler.search_users(u1, "user", 10))
  450. self.assertEqual(len(s["results"]), 2)
  451. # Registering a user and then searching for them works.
  452. u4 = self.register_user("user4", "pass")
  453. s = self.get_success(self.handler.search_users(u1, u4, 10))
  454. self.assertEqual(len(s["results"]), 1)
  455. @override_config(
  456. {
  457. "user_directory": {
  458. "enabled": True,
  459. "search_all_users": True,
  460. "prefer_local_users": True,
  461. }
  462. }
  463. )
  464. def test_prefer_local_users(self):
  465. """Tests that local users are shown higher in search results when
  466. user_directory.prefer_local_users is True.
  467. """
  468. # Create a room and few users to test the directory with
  469. searching_user = self.register_user("searcher", "password")
  470. searching_user_tok = self.login("searcher", "password")
  471. room_id = self.helper.create_room_as(
  472. searching_user,
  473. room_version=RoomVersions.V1.identifier,
  474. tok=searching_user_tok,
  475. )
  476. # Create a few local users and join them to the room
  477. local_user_1 = self.register_user("user_xxxxx", "password")
  478. local_user_2 = self.register_user("user_bbbbb", "password")
  479. local_user_3 = self.register_user("user_zzzzz", "password")
  480. self._add_user_to_room(room_id, RoomVersions.V1, local_user_1)
  481. self._add_user_to_room(room_id, RoomVersions.V1, local_user_2)
  482. self._add_user_to_room(room_id, RoomVersions.V1, local_user_3)
  483. # Create a few "remote" users and join them to the room
  484. remote_user_1 = "@user_aaaaa:remote_server"
  485. remote_user_2 = "@user_yyyyy:remote_server"
  486. remote_user_3 = "@user_ccccc:remote_server"
  487. self._add_user_to_room(room_id, RoomVersions.V1, remote_user_1)
  488. self._add_user_to_room(room_id, RoomVersions.V1, remote_user_2)
  489. self._add_user_to_room(room_id, RoomVersions.V1, remote_user_3)
  490. local_users = [local_user_1, local_user_2, local_user_3]
  491. remote_users = [remote_user_1, remote_user_2, remote_user_3]
  492. # Populate the user directory via background update
  493. self._add_background_updates()
  494. while not self.get_success(
  495. self.store.db_pool.updates.has_completed_background_updates()
  496. ):
  497. self.get_success(
  498. self.store.db_pool.updates.do_next_background_update(100), by=0.1
  499. )
  500. # The local searching user searches for the term "user", which other users have
  501. # in their user id
  502. results = self.get_success(
  503. self.handler.search_users(searching_user, "user", 20)
  504. )["results"]
  505. received_user_id_ordering = [result["user_id"] for result in results]
  506. # Typically we'd expect Synapse to return users in lexicographical order,
  507. # assuming they have similar User IDs/display names, and profile information.
  508. # Check that the order of returned results using our module is as we expect,
  509. # i.e our local users show up first, despite all users having lexographically mixed
  510. # user IDs.
  511. [self.assertIn(user, local_users) for user in received_user_id_ordering[:3]]
  512. [self.assertIn(user, remote_users) for user in received_user_id_ordering[3:]]
  513. def _add_user_to_room(
  514. self,
  515. room_id: str,
  516. room_version: RoomVersion,
  517. user_id: str,
  518. ):
  519. # Add a user to the room.
  520. builder = self.event_builder_factory.for_room_version(
  521. room_version,
  522. {
  523. "type": "m.room.member",
  524. "sender": user_id,
  525. "state_key": user_id,
  526. "room_id": room_id,
  527. "content": {"membership": "join"},
  528. },
  529. )
  530. event, context = self.get_success(
  531. self.event_creation_handler.create_new_client_event(builder)
  532. )
  533. self.get_success(
  534. self.hs.get_storage().persistence.persist_event(event, context)
  535. )
  536. class TestUserDirSearchDisabled(unittest.HomeserverTestCase):
  537. user_id = "@test:test"
  538. servlets = [
  539. user_directory.register_servlets,
  540. room.register_servlets,
  541. login.register_servlets,
  542. synapse.rest.admin.register_servlets_for_client_rest_resource,
  543. ]
  544. def make_homeserver(self, reactor, clock):
  545. config = self.default_config()
  546. config["update_user_directory"] = True
  547. hs = self.setup_test_homeserver(config=config)
  548. self.config = hs.config
  549. return hs
  550. def test_disabling_room_list(self):
  551. self.config.user_directory_search_enabled = True
  552. # First we create a room with another user so that user dir is non-empty
  553. # for our user
  554. self.helper.create_room_as(self.user_id)
  555. u2 = self.register_user("user2", "pass")
  556. room = self.helper.create_room_as(self.user_id)
  557. self.helper.join(room, user=u2)
  558. # Assert user directory is not empty
  559. channel = self.make_request(
  560. "POST", b"user_directory/search", b'{"search_term":"user2"}'
  561. )
  562. self.assertEquals(200, channel.code, channel.result)
  563. self.assertTrue(len(channel.json_body["results"]) > 0)
  564. # Disable user directory and check search returns nothing
  565. self.config.user_directory_search_enabled = False
  566. channel = self.make_request(
  567. "POST", b"user_directory/search", b'{"search_term":"user2"}'
  568. )
  569. self.assertEquals(200, channel.code, channel.result)
  570. self.assertTrue(len(channel.json_body["results"]) == 0)