test_federation.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2019 The Matrix.org Foundation C.I.C.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import logging
  16. from synapse.api.constants import EventTypes
  17. from synapse.api.errors import AuthError, Codes
  18. from synapse.federation.federation_base import event_from_pdu_json
  19. from synapse.logging.context import LoggingContext, run_in_background
  20. from synapse.rest import admin
  21. from synapse.rest.client.v1 import login, room
  22. from tests import unittest
  23. logger = logging.getLogger(__name__)
  24. class FederationTestCase(unittest.HomeserverTestCase):
  25. servlets = [
  26. admin.register_servlets,
  27. login.register_servlets,
  28. room.register_servlets,
  29. ]
  30. def make_homeserver(self, reactor, clock):
  31. hs = self.setup_test_homeserver(http_client=None)
  32. self.handler = hs.get_handlers().federation_handler
  33. self.store = hs.get_datastore()
  34. return hs
  35. def test_exchange_revoked_invite(self):
  36. user_id = self.register_user("kermit", "test")
  37. tok = self.login("kermit", "test")
  38. room_id = self.helper.create_room_as(room_creator=user_id, tok=tok)
  39. # Send a 3PID invite event with an empty body so it's considered as a revoked one.
  40. invite_token = "sometoken"
  41. self.helper.send_state(
  42. room_id=room_id,
  43. event_type=EventTypes.ThirdPartyInvite,
  44. state_key=invite_token,
  45. body={},
  46. tok=tok,
  47. )
  48. d = self.handler.on_exchange_third_party_invite_request(
  49. room_id=room_id,
  50. event_dict={
  51. "type": EventTypes.Member,
  52. "room_id": room_id,
  53. "sender": user_id,
  54. "state_key": "@someone:example.org",
  55. "content": {
  56. "membership": "invite",
  57. "third_party_invite": {
  58. "display_name": "alice",
  59. "signed": {
  60. "mxid": "@alice:localhost",
  61. "token": invite_token,
  62. "signatures": {
  63. "magic.forest": {
  64. "ed25519:3": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg"
  65. }
  66. },
  67. },
  68. },
  69. },
  70. },
  71. )
  72. failure = self.get_failure(d, AuthError).value
  73. self.assertEqual(failure.code, 403, failure)
  74. self.assertEqual(failure.errcode, Codes.FORBIDDEN, failure)
  75. self.assertEqual(failure.msg, "You are not invited to this room.")
  76. def test_rejected_message_event_state(self):
  77. """
  78. Check that we store the state group correctly for rejected non-state events.
  79. Regression test for #6289.
  80. """
  81. OTHER_SERVER = "otherserver"
  82. OTHER_USER = "@otheruser:" + OTHER_SERVER
  83. # create the room
  84. user_id = self.register_user("kermit", "test")
  85. tok = self.login("kermit", "test")
  86. room_id = self.helper.create_room_as(room_creator=user_id, tok=tok)
  87. # pretend that another server has joined
  88. join_event = self._build_and_send_join_event(OTHER_SERVER, OTHER_USER, room_id)
  89. # check the state group
  90. sg = self.successResultOf(
  91. self.store._get_state_group_for_event(join_event.event_id)
  92. )
  93. # build and send an event which will be rejected
  94. ev = event_from_pdu_json(
  95. {
  96. "type": EventTypes.Message,
  97. "content": {},
  98. "room_id": room_id,
  99. "sender": "@yetanotheruser:" + OTHER_SERVER,
  100. "depth": join_event["depth"] + 1,
  101. "prev_events": [join_event.event_id],
  102. "auth_events": [],
  103. "origin_server_ts": self.clock.time_msec(),
  104. },
  105. join_event.format_version,
  106. )
  107. with LoggingContext(request="send_rejected"):
  108. d = run_in_background(self.handler.on_receive_pdu, OTHER_SERVER, ev)
  109. self.get_success(d)
  110. # that should have been rejected
  111. e = self.get_success(self.store.get_event(ev.event_id, allow_rejected=True))
  112. self.assertIsNotNone(e.rejected_reason)
  113. # ... and the state group should be the same as before
  114. sg2 = self.successResultOf(self.store._get_state_group_for_event(ev.event_id))
  115. self.assertEqual(sg, sg2)
  116. def test_rejected_state_event_state(self):
  117. """
  118. Check that we store the state group correctly for rejected state events.
  119. Regression test for #6289.
  120. """
  121. OTHER_SERVER = "otherserver"
  122. OTHER_USER = "@otheruser:" + OTHER_SERVER
  123. # create the room
  124. user_id = self.register_user("kermit", "test")
  125. tok = self.login("kermit", "test")
  126. room_id = self.helper.create_room_as(room_creator=user_id, tok=tok)
  127. # pretend that another server has joined
  128. join_event = self._build_and_send_join_event(OTHER_SERVER, OTHER_USER, room_id)
  129. # check the state group
  130. sg = self.successResultOf(
  131. self.store._get_state_group_for_event(join_event.event_id)
  132. )
  133. # build and send an event which will be rejected
  134. ev = event_from_pdu_json(
  135. {
  136. "type": "org.matrix.test",
  137. "state_key": "test_key",
  138. "content": {},
  139. "room_id": room_id,
  140. "sender": "@yetanotheruser:" + OTHER_SERVER,
  141. "depth": join_event["depth"] + 1,
  142. "prev_events": [join_event.event_id],
  143. "auth_events": [],
  144. "origin_server_ts": self.clock.time_msec(),
  145. },
  146. join_event.format_version,
  147. )
  148. with LoggingContext(request="send_rejected"):
  149. d = run_in_background(self.handler.on_receive_pdu, OTHER_SERVER, ev)
  150. self.get_success(d)
  151. # that should have been rejected
  152. e = self.get_success(self.store.get_event(ev.event_id, allow_rejected=True))
  153. self.assertIsNotNone(e.rejected_reason)
  154. # ... and the state group should be the same as before
  155. sg2 = self.successResultOf(self.store._get_state_group_for_event(ev.event_id))
  156. self.assertEqual(sg, sg2)
  157. def _build_and_send_join_event(self, other_server, other_user, room_id):
  158. join_event = self.get_success(
  159. self.handler.on_make_join_request(other_server, room_id, other_user)
  160. )
  161. # the auth code requires that a signature exists, but doesn't check that
  162. # signature... go figure.
  163. join_event.signatures[other_server] = {"x": "y"}
  164. with LoggingContext(request="send_join"):
  165. d = run_in_background(
  166. self.handler.on_send_join_request, other_server, join_event
  167. )
  168. self.get_success(d)
  169. # sanity-check: the room should show that the new user is a member
  170. r = self.get_success(self.store.get_current_state_ids(room_id))
  171. self.assertEqual(r[(EventTypes.Member, other_user)], join_event.event_id)
  172. return join_event