test_user_directory.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  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. async def allow_all(user_profile):
  259. # Allow all users.
  260. return False
  261. # Configure a spam checker that does not filter any users.
  262. spam_checker = self.hs.get_spam_checker()
  263. spam_checker._check_username_for_spam_callbacks = [allow_all]
  264. # The results do not change:
  265. # We get one search result when searching for user2 by user1.
  266. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  267. self.assertEqual(len(s["results"]), 1)
  268. # Configure a spam checker that filters all users.
  269. async def block_all(user_profile):
  270. # All users are spammy.
  271. return True
  272. spam_checker._check_username_for_spam_callbacks = [block_all]
  273. # User1 now gets no search results for any of the other users.
  274. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  275. self.assertEqual(len(s["results"]), 0)
  276. def test_legacy_spam_checker(self):
  277. """
  278. A spam checker without the expected method should be ignored.
  279. """
  280. u1 = self.register_user("user1", "pass")
  281. u1_token = self.login(u1, "pass")
  282. u2 = self.register_user("user2", "pass")
  283. u2_token = self.login(u2, "pass")
  284. # We do not add users to the directory until they join a room.
  285. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  286. self.assertEqual(len(s["results"]), 0)
  287. room = self.helper.create_room_as(u1, is_public=False, tok=u1_token)
  288. self.helper.invite(room, src=u1, targ=u2, tok=u1_token)
  289. self.helper.join(room, user=u2, tok=u2_token)
  290. # Check we have populated the database correctly.
  291. shares_private = self.get_users_who_share_private_rooms()
  292. public_users = self.get_users_in_public_rooms()
  293. self.assertEqual(
  294. self._compress_shared(shares_private), {(u1, u2, room), (u2, u1, room)}
  295. )
  296. self.assertEqual(public_users, [])
  297. # Configure a spam checker.
  298. spam_checker = self.hs.get_spam_checker()
  299. # The spam checker doesn't need any methods, so create a bare object.
  300. spam_checker.spam_checker = object()
  301. # We get one search result when searching for user2 by user1.
  302. s = self.get_success(self.handler.search_users(u1, "user2", 10))
  303. self.assertEqual(len(s["results"]), 1)
  304. def _compress_shared(self, shared):
  305. """
  306. Compress a list of users who share rooms dicts to a list of tuples.
  307. """
  308. r = set()
  309. for i in shared:
  310. r.add((i["user_id"], i["other_user_id"], i["room_id"]))
  311. return r
  312. def get_users_in_public_rooms(self):
  313. r = self.get_success(
  314. self.store.db_pool.simple_select_list(
  315. "users_in_public_rooms", None, ("user_id", "room_id")
  316. )
  317. )
  318. retval = []
  319. for i in r:
  320. retval.append((i["user_id"], i["room_id"]))
  321. return retval
  322. def get_users_who_share_private_rooms(self):
  323. return self.get_success(
  324. self.store.db_pool.simple_select_list(
  325. "users_who_share_private_rooms",
  326. None,
  327. ["user_id", "other_user_id", "room_id"],
  328. )
  329. )
  330. def _add_background_updates(self):
  331. """
  332. Add the background updates we need to run.
  333. """
  334. # Ugh, have to reset this flag
  335. self.store.db_pool.updates._all_done = False
  336. self.get_success(
  337. self.store.db_pool.simple_insert(
  338. "background_updates",
  339. {
  340. "update_name": "populate_user_directory_createtables",
  341. "progress_json": "{}",
  342. },
  343. )
  344. )
  345. self.get_success(
  346. self.store.db_pool.simple_insert(
  347. "background_updates",
  348. {
  349. "update_name": "populate_user_directory_process_rooms",
  350. "progress_json": "{}",
  351. "depends_on": "populate_user_directory_createtables",
  352. },
  353. )
  354. )
  355. self.get_success(
  356. self.store.db_pool.simple_insert(
  357. "background_updates",
  358. {
  359. "update_name": "populate_user_directory_process_users",
  360. "progress_json": "{}",
  361. "depends_on": "populate_user_directory_process_rooms",
  362. },
  363. )
  364. )
  365. self.get_success(
  366. self.store.db_pool.simple_insert(
  367. "background_updates",
  368. {
  369. "update_name": "populate_user_directory_cleanup",
  370. "progress_json": "{}",
  371. "depends_on": "populate_user_directory_process_users",
  372. },
  373. )
  374. )
  375. def test_initial(self):
  376. """
  377. The user directory's initial handler correctly updates the search tables.
  378. """
  379. u1 = self.register_user("user1", "pass")
  380. u1_token = self.login(u1, "pass")
  381. u2 = self.register_user("user2", "pass")
  382. u2_token = self.login(u2, "pass")
  383. u3 = self.register_user("user3", "pass")
  384. u3_token = self.login(u3, "pass")
  385. room = self.helper.create_room_as(u1, is_public=True, tok=u1_token)
  386. self.helper.invite(room, src=u1, targ=u2, tok=u1_token)
  387. self.helper.join(room, user=u2, tok=u2_token)
  388. private_room = self.helper.create_room_as(u1, is_public=False, tok=u1_token)
  389. self.helper.invite(private_room, src=u1, targ=u3, tok=u1_token)
  390. self.helper.join(private_room, user=u3, tok=u3_token)
  391. self.get_success(self.store.update_user_directory_stream_pos(None))
  392. self.get_success(self.store.delete_all_from_user_dir())
  393. shares_private = self.get_users_who_share_private_rooms()
  394. public_users = self.get_users_in_public_rooms()
  395. # Nothing updated yet
  396. self.assertEqual(shares_private, [])
  397. self.assertEqual(public_users, [])
  398. # Do the initial population of the user directory via the background update
  399. self._add_background_updates()
  400. while not self.get_success(
  401. self.store.db_pool.updates.has_completed_background_updates()
  402. ):
  403. self.get_success(
  404. self.store.db_pool.updates.do_next_background_update(100), by=0.1
  405. )
  406. shares_private = self.get_users_who_share_private_rooms()
  407. public_users = self.get_users_in_public_rooms()
  408. # User 1 and User 2 are in the same public room
  409. self.assertEqual(set(public_users), {(u1, room), (u2, room)})
  410. # User 1 and User 3 share private rooms
  411. self.assertEqual(
  412. self._compress_shared(shares_private),
  413. {(u1, u3, private_room), (u3, u1, private_room)},
  414. )
  415. def test_initial_share_all_users(self):
  416. """
  417. Search all users = True means that a user does not have to share a
  418. private room with the searching user or be in a public room to be search
  419. visible.
  420. """
  421. self.handler.search_all_users = True
  422. self.hs.config.user_directory_search_all_users = True
  423. u1 = self.register_user("user1", "pass")
  424. self.register_user("user2", "pass")
  425. u3 = self.register_user("user3", "pass")
  426. # Wipe the user dir
  427. self.get_success(self.store.update_user_directory_stream_pos(None))
  428. self.get_success(self.store.delete_all_from_user_dir())
  429. # Do the initial population of the user directory via the background update
  430. self._add_background_updates()
  431. while not self.get_success(
  432. self.store.db_pool.updates.has_completed_background_updates()
  433. ):
  434. self.get_success(
  435. self.store.db_pool.updates.do_next_background_update(100), by=0.1
  436. )
  437. shares_private = self.get_users_who_share_private_rooms()
  438. public_users = self.get_users_in_public_rooms()
  439. # No users share rooms
  440. self.assertEqual(public_users, [])
  441. self.assertEqual(self._compress_shared(shares_private), set())
  442. # Despite not sharing a room, search_all_users means we get a search
  443. # result.
  444. s = self.get_success(self.handler.search_users(u1, u3, 10))
  445. self.assertEqual(len(s["results"]), 1)
  446. # We can find the other two users
  447. s = self.get_success(self.handler.search_users(u1, "user", 10))
  448. self.assertEqual(len(s["results"]), 2)
  449. # Registering a user and then searching for them works.
  450. u4 = self.register_user("user4", "pass")
  451. s = self.get_success(self.handler.search_users(u1, u4, 10))
  452. self.assertEqual(len(s["results"]), 1)
  453. @override_config(
  454. {
  455. "user_directory": {
  456. "enabled": True,
  457. "search_all_users": True,
  458. "prefer_local_users": True,
  459. }
  460. }
  461. )
  462. def test_prefer_local_users(self):
  463. """Tests that local users are shown higher in search results when
  464. user_directory.prefer_local_users is True.
  465. """
  466. # Create a room and few users to test the directory with
  467. searching_user = self.register_user("searcher", "password")
  468. searching_user_tok = self.login("searcher", "password")
  469. room_id = self.helper.create_room_as(
  470. searching_user,
  471. room_version=RoomVersions.V1.identifier,
  472. tok=searching_user_tok,
  473. )
  474. # Create a few local users and join them to the room
  475. local_user_1 = self.register_user("user_xxxxx", "password")
  476. local_user_2 = self.register_user("user_bbbbb", "password")
  477. local_user_3 = self.register_user("user_zzzzz", "password")
  478. self._add_user_to_room(room_id, RoomVersions.V1, local_user_1)
  479. self._add_user_to_room(room_id, RoomVersions.V1, local_user_2)
  480. self._add_user_to_room(room_id, RoomVersions.V1, local_user_3)
  481. # Create a few "remote" users and join them to the room
  482. remote_user_1 = "@user_aaaaa:remote_server"
  483. remote_user_2 = "@user_yyyyy:remote_server"
  484. remote_user_3 = "@user_ccccc:remote_server"
  485. self._add_user_to_room(room_id, RoomVersions.V1, remote_user_1)
  486. self._add_user_to_room(room_id, RoomVersions.V1, remote_user_2)
  487. self._add_user_to_room(room_id, RoomVersions.V1, remote_user_3)
  488. local_users = [local_user_1, local_user_2, local_user_3]
  489. remote_users = [remote_user_1, remote_user_2, remote_user_3]
  490. # Populate the user directory via background update
  491. self._add_background_updates()
  492. while not self.get_success(
  493. self.store.db_pool.updates.has_completed_background_updates()
  494. ):
  495. self.get_success(
  496. self.store.db_pool.updates.do_next_background_update(100), by=0.1
  497. )
  498. # The local searching user searches for the term "user", which other users have
  499. # in their user id
  500. results = self.get_success(
  501. self.handler.search_users(searching_user, "user", 20)
  502. )["results"]
  503. received_user_id_ordering = [result["user_id"] for result in results]
  504. # Typically we'd expect Synapse to return users in lexicographical order,
  505. # assuming they have similar User IDs/display names, and profile information.
  506. # Check that the order of returned results using our module is as we expect,
  507. # i.e our local users show up first, despite all users having lexographically mixed
  508. # user IDs.
  509. [self.assertIn(user, local_users) for user in received_user_id_ordering[:3]]
  510. [self.assertIn(user, remote_users) for user in received_user_id_ordering[3:]]
  511. def _add_user_to_room(
  512. self,
  513. room_id: str,
  514. room_version: RoomVersion,
  515. user_id: str,
  516. ):
  517. # Add a user to the room.
  518. builder = self.event_builder_factory.for_room_version(
  519. room_version,
  520. {
  521. "type": "m.room.member",
  522. "sender": user_id,
  523. "state_key": user_id,
  524. "room_id": room_id,
  525. "content": {"membership": "join"},
  526. },
  527. )
  528. event, context = self.get_success(
  529. self.event_creation_handler.create_new_client_event(builder)
  530. )
  531. self.get_success(
  532. self.hs.get_storage().persistence.persist_event(event, context)
  533. )
  534. class TestUserDirSearchDisabled(unittest.HomeserverTestCase):
  535. user_id = "@test:test"
  536. servlets = [
  537. user_directory.register_servlets,
  538. room.register_servlets,
  539. login.register_servlets,
  540. synapse.rest.admin.register_servlets_for_client_rest_resource,
  541. ]
  542. def make_homeserver(self, reactor, clock):
  543. config = self.default_config()
  544. config["update_user_directory"] = True
  545. hs = self.setup_test_homeserver(config=config)
  546. self.config = hs.config
  547. return hs
  548. def test_disabling_room_list(self):
  549. self.config.user_directory_search_enabled = True
  550. # First we create a room with another user so that user dir is non-empty
  551. # for our user
  552. self.helper.create_room_as(self.user_id)
  553. u2 = self.register_user("user2", "pass")
  554. room = self.helper.create_room_as(self.user_id)
  555. self.helper.join(room, user=u2)
  556. # Assert user directory is not empty
  557. channel = self.make_request(
  558. "POST", b"user_directory/search", b'{"search_term":"user2"}'
  559. )
  560. self.assertEquals(200, channel.code, channel.result)
  561. self.assertTrue(len(channel.json_body["results"]) > 0)
  562. # Disable user directory and check search returns nothing
  563. self.config.user_directory_search_enabled = False
  564. channel = self.make_request(
  565. "POST", b"user_directory/search", b'{"search_term":"user2"}'
  566. )
  567. self.assertEquals(200, channel.code, channel.result)
  568. self.assertTrue(len(channel.json_body["results"]) == 0)