test_shadow_banned.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. # Copyright 2020 The Matrix.org Foundation C.I.C.
  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 mock import Mock, patch
  15. import synapse.rest.admin
  16. from synapse.api.constants import EventTypes
  17. from synapse.rest.client.v1 import directory, login, profile, room
  18. from synapse.rest.client.v2_alpha import room_upgrade_rest_servlet
  19. from synapse.types import UserID
  20. from tests import unittest
  21. class _ShadowBannedBase(unittest.HomeserverTestCase):
  22. def prepare(self, reactor, clock, homeserver):
  23. # Create two users, one of which is shadow-banned.
  24. self.banned_user_id = self.register_user("banned", "test")
  25. self.banned_access_token = self.login("banned", "test")
  26. self.store = self.hs.get_datastore()
  27. self.get_success(
  28. self.store.set_shadow_banned(UserID.from_string(self.banned_user_id), True)
  29. )
  30. self.other_user_id = self.register_user("otheruser", "pass")
  31. self.other_access_token = self.login("otheruser", "pass")
  32. # To avoid the tests timing out don't add a delay to "annoy the requester".
  33. @patch("random.randint", new=lambda a, b: 0)
  34. class RoomTestCase(_ShadowBannedBase):
  35. servlets = [
  36. synapse.rest.admin.register_servlets_for_client_rest_resource,
  37. directory.register_servlets,
  38. login.register_servlets,
  39. room.register_servlets,
  40. room_upgrade_rest_servlet.register_servlets,
  41. ]
  42. def test_invite(self):
  43. """Invites from shadow-banned users don't actually get sent."""
  44. # The create works fine.
  45. room_id = self.helper.create_room_as(
  46. self.banned_user_id, tok=self.banned_access_token
  47. )
  48. # Inviting the user completes successfully.
  49. self.helper.invite(
  50. room=room_id,
  51. src=self.banned_user_id,
  52. tok=self.banned_access_token,
  53. targ=self.other_user_id,
  54. )
  55. # But the user wasn't actually invited.
  56. invited_rooms = self.get_success(
  57. self.store.get_invited_rooms_for_local_user(self.other_user_id)
  58. )
  59. self.assertEqual(invited_rooms, [])
  60. def test_invite_3pid(self):
  61. """Ensure that a 3PID invite does not attempt to contact the identity server."""
  62. identity_handler = self.hs.get_identity_handler()
  63. identity_handler.lookup_3pid = Mock(
  64. side_effect=AssertionError("This should not get called")
  65. )
  66. # The create works fine.
  67. room_id = self.helper.create_room_as(
  68. self.banned_user_id, tok=self.banned_access_token
  69. )
  70. # Inviting the user completes successfully.
  71. channel = self.make_request(
  72. "POST",
  73. "/rooms/%s/invite" % (room_id,),
  74. {"id_server": "test", "medium": "email", "address": "test@test.test"},
  75. access_token=self.banned_access_token,
  76. )
  77. self.assertEquals(200, channel.code, channel.result)
  78. # This should have raised an error earlier, but double check this wasn't called.
  79. identity_handler.lookup_3pid.assert_not_called()
  80. def test_create_room(self):
  81. """Invitations during a room creation should be discarded, but the room still gets created."""
  82. # The room creation is successful.
  83. channel = self.make_request(
  84. "POST",
  85. "/_matrix/client/r0/createRoom",
  86. {"visibility": "public", "invite": [self.other_user_id]},
  87. access_token=self.banned_access_token,
  88. )
  89. self.assertEquals(200, channel.code, channel.result)
  90. room_id = channel.json_body["room_id"]
  91. # But the user wasn't actually invited.
  92. invited_rooms = self.get_success(
  93. self.store.get_invited_rooms_for_local_user(self.other_user_id)
  94. )
  95. self.assertEqual(invited_rooms, [])
  96. # Since a real room was created, the other user should be able to join it.
  97. self.helper.join(room_id, self.other_user_id, tok=self.other_access_token)
  98. # Both users should be in the room.
  99. users = self.get_success(self.store.get_users_in_room(room_id))
  100. self.assertCountEqual(users, ["@banned:test", "@otheruser:test"])
  101. def test_message(self):
  102. """Messages from shadow-banned users don't actually get sent."""
  103. room_id = self.helper.create_room_as(
  104. self.other_user_id, tok=self.other_access_token
  105. )
  106. # The user should be in the room.
  107. self.helper.join(room_id, self.banned_user_id, tok=self.banned_access_token)
  108. # Sending a message should complete successfully.
  109. result = self.helper.send_event(
  110. room_id=room_id,
  111. type=EventTypes.Message,
  112. content={"msgtype": "m.text", "body": "with right label"},
  113. tok=self.banned_access_token,
  114. )
  115. self.assertIn("event_id", result)
  116. event_id = result["event_id"]
  117. latest_events = self.get_success(
  118. self.store.get_latest_event_ids_in_room(room_id)
  119. )
  120. self.assertNotIn(event_id, latest_events)
  121. def test_upgrade(self):
  122. """A room upgrade should fail, but look like it succeeded."""
  123. # The create works fine.
  124. room_id = self.helper.create_room_as(
  125. self.banned_user_id, tok=self.banned_access_token
  126. )
  127. channel = self.make_request(
  128. "POST",
  129. "/_matrix/client/r0/rooms/%s/upgrade" % (room_id,),
  130. {"new_version": "6"},
  131. access_token=self.banned_access_token,
  132. )
  133. self.assertEquals(200, channel.code, channel.result)
  134. # A new room_id should be returned.
  135. self.assertIn("replacement_room", channel.json_body)
  136. new_room_id = channel.json_body["replacement_room"]
  137. # It doesn't really matter what API we use here, we just want to assert
  138. # that the room doesn't exist.
  139. summary = self.get_success(self.store.get_room_summary(new_room_id))
  140. # The summary should be empty since the room doesn't exist.
  141. self.assertEqual(summary, {})
  142. def test_typing(self):
  143. """Typing notifications should not be propagated into the room."""
  144. # The create works fine.
  145. room_id = self.helper.create_room_as(
  146. self.banned_user_id, tok=self.banned_access_token
  147. )
  148. channel = self.make_request(
  149. "PUT",
  150. "/rooms/%s/typing/%s" % (room_id, self.banned_user_id),
  151. {"typing": True, "timeout": 30000},
  152. access_token=self.banned_access_token,
  153. )
  154. self.assertEquals(200, channel.code)
  155. # There should be no typing events.
  156. event_source = self.hs.get_event_sources().sources["typing"]
  157. self.assertEquals(event_source.get_current_key(), 0)
  158. # The other user can join and send typing events.
  159. self.helper.join(room_id, self.other_user_id, tok=self.other_access_token)
  160. channel = self.make_request(
  161. "PUT",
  162. "/rooms/%s/typing/%s" % (room_id, self.other_user_id),
  163. {"typing": True, "timeout": 30000},
  164. access_token=self.other_access_token,
  165. )
  166. self.assertEquals(200, channel.code)
  167. # These appear in the room.
  168. self.assertEquals(event_source.get_current_key(), 1)
  169. events = self.get_success(
  170. event_source.get_new_events(from_key=0, room_ids=[room_id])
  171. )
  172. self.assertEquals(
  173. events[0],
  174. [
  175. {
  176. "type": "m.typing",
  177. "room_id": room_id,
  178. "content": {"user_ids": [self.other_user_id]},
  179. }
  180. ],
  181. )
  182. # To avoid the tests timing out don't add a delay to "annoy the requester".
  183. @patch("random.randint", new=lambda a, b: 0)
  184. class ProfileTestCase(_ShadowBannedBase):
  185. servlets = [
  186. synapse.rest.admin.register_servlets_for_client_rest_resource,
  187. login.register_servlets,
  188. profile.register_servlets,
  189. room.register_servlets,
  190. ]
  191. def test_displayname(self):
  192. """Profile changes should succeed, but don't end up in a room."""
  193. original_display_name = "banned"
  194. new_display_name = "new name"
  195. # Join a room.
  196. room_id = self.helper.create_room_as(
  197. self.banned_user_id, tok=self.banned_access_token
  198. )
  199. # The update should succeed.
  200. channel = self.make_request(
  201. "PUT",
  202. "/_matrix/client/r0/profile/%s/displayname" % (self.banned_user_id,),
  203. {"displayname": new_display_name},
  204. access_token=self.banned_access_token,
  205. )
  206. self.assertEquals(200, channel.code, channel.result)
  207. self.assertEqual(channel.json_body, {})
  208. # The user's display name should be updated.
  209. channel = self.make_request(
  210. "GET", "/profile/%s/displayname" % (self.banned_user_id,)
  211. )
  212. self.assertEqual(channel.code, 200, channel.result)
  213. self.assertEqual(channel.json_body["displayname"], new_display_name)
  214. # But the display name in the room should not be.
  215. message_handler = self.hs.get_message_handler()
  216. event = self.get_success(
  217. message_handler.get_room_data(
  218. self.banned_user_id, room_id, "m.room.member", self.banned_user_id,
  219. )
  220. )
  221. self.assertEqual(
  222. event.content, {"membership": "join", "displayname": original_display_name}
  223. )
  224. def test_room_displayname(self):
  225. """Changes to state events for a room should be processed, but not end up in the room."""
  226. original_display_name = "banned"
  227. new_display_name = "new name"
  228. # Join a room.
  229. room_id = self.helper.create_room_as(
  230. self.banned_user_id, tok=self.banned_access_token
  231. )
  232. # The update should succeed.
  233. channel = self.make_request(
  234. "PUT",
  235. "/_matrix/client/r0/rooms/%s/state/m.room.member/%s"
  236. % (room_id, self.banned_user_id),
  237. {"membership": "join", "displayname": new_display_name},
  238. access_token=self.banned_access_token,
  239. )
  240. self.assertEquals(200, channel.code, channel.result)
  241. self.assertIn("event_id", channel.json_body)
  242. # The display name in the room should not be changed.
  243. message_handler = self.hs.get_message_handler()
  244. event = self.get_success(
  245. message_handler.get_room_data(
  246. self.banned_user_id, room_id, "m.room.member", self.banned_user_id,
  247. )
  248. )
  249. self.assertEqual(
  250. event.content, {"membership": "join", "displayname": original_display_name}
  251. )