test_federation.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. from mock import Mock
  2. from twisted.internet.defer import maybeDeferred, succeed
  3. from synapse.events import FrozenEvent
  4. from synapse.types import Requester, UserID
  5. from synapse.util import Clock
  6. from tests import unittest
  7. from tests.server import ThreadedMemoryReactorClock, setup_test_homeserver
  8. class MessageAcceptTests(unittest.TestCase):
  9. def setUp(self):
  10. self.http_client = Mock()
  11. self.reactor = ThreadedMemoryReactorClock()
  12. self.hs_clock = Clock(self.reactor)
  13. self.homeserver = setup_test_homeserver(
  14. self.addCleanup,
  15. http_client=self.http_client,
  16. clock=self.hs_clock,
  17. reactor=self.reactor,
  18. )
  19. user_id = UserID("us", "test")
  20. our_user = Requester(user_id, None, False, None, None)
  21. room_creator = self.homeserver.get_room_creation_handler()
  22. room = room_creator.create_room(
  23. our_user, room_creator.PRESETS_DICT["public_chat"], ratelimit=False
  24. )
  25. self.reactor.advance(0.1)
  26. self.room_id = self.successResultOf(room)["room_id"]
  27. # Figure out what the most recent event is
  28. most_recent = self.successResultOf(
  29. maybeDeferred(
  30. self.homeserver.datastore.get_latest_event_ids_in_room, self.room_id
  31. )
  32. )[0]
  33. join_event = FrozenEvent(
  34. {
  35. "room_id": self.room_id,
  36. "sender": "@baduser:test.serv",
  37. "state_key": "@baduser:test.serv",
  38. "event_id": "$join:test.serv",
  39. "depth": 1000,
  40. "origin_server_ts": 1,
  41. "type": "m.room.member",
  42. "origin": "test.servx",
  43. "content": {"membership": "join"},
  44. "auth_events": [],
  45. "prev_state": [(most_recent, {})],
  46. "prev_events": [(most_recent, {})],
  47. }
  48. )
  49. self.handler = self.homeserver.get_handlers().federation_handler
  50. self.handler.do_auth = lambda *a, **b: succeed(True)
  51. self.client = self.homeserver.get_federation_client()
  52. self.client._check_sigs_and_hash_and_fetch = lambda dest, pdus, **k: succeed(
  53. pdus
  54. )
  55. # Send the join, it should return None (which is not an error)
  56. d = self.handler.on_receive_pdu(
  57. "test.serv", join_event, sent_to_us_directly=True
  58. )
  59. self.reactor.advance(1)
  60. self.assertEqual(self.successResultOf(d), None)
  61. # Make sure we actually joined the room
  62. self.assertEqual(
  63. self.successResultOf(
  64. maybeDeferred(
  65. self.homeserver.datastore.get_latest_event_ids_in_room, self.room_id
  66. )
  67. )[0],
  68. "$join:test.serv",
  69. )
  70. def test_cant_hide_direct_ancestors(self):
  71. """
  72. If you send a message, you must be able to provide the direct
  73. prev_events that said event references.
  74. """
  75. def post_json(destination, path, data, headers=None, timeout=0):
  76. # If it asks us for new missing events, give them NOTHING
  77. if path.startswith("/_matrix/federation/v1/get_missing_events/"):
  78. return {"events": []}
  79. self.http_client.post_json = post_json
  80. # Figure out what the most recent event is
  81. most_recent = self.successResultOf(
  82. maybeDeferred(
  83. self.homeserver.datastore.get_latest_event_ids_in_room, self.room_id
  84. )
  85. )[0]
  86. # Now lie about an event
  87. lying_event = FrozenEvent(
  88. {
  89. "room_id": self.room_id,
  90. "sender": "@baduser:test.serv",
  91. "event_id": "one:test.serv",
  92. "depth": 1000,
  93. "origin_server_ts": 1,
  94. "type": "m.room.message",
  95. "origin": "test.serv",
  96. "content": "hewwo?",
  97. "auth_events": [],
  98. "prev_events": [("two:test.serv", {}), (most_recent, {})],
  99. }
  100. )
  101. d = self.handler.on_receive_pdu(
  102. "test.serv", lying_event, sent_to_us_directly=True
  103. )
  104. # Step the reactor, so the database fetches come back
  105. self.reactor.advance(1)
  106. # on_receive_pdu should throw an error
  107. failure = self.failureResultOf(d)
  108. self.assertEqual(
  109. failure.value.args[0],
  110. (
  111. "ERROR 403: Your server isn't divulging details about prev_events "
  112. "referenced in this event."
  113. ),
  114. )
  115. # Make sure the invalid event isn't there
  116. extrem = maybeDeferred(
  117. self.homeserver.datastore.get_latest_event_ids_in_room, self.room_id
  118. )
  119. self.assertEqual(self.successResultOf(extrem)[0], "$join:test.serv")
  120. def test_cant_hide_past_history(self):
  121. """
  122. If you send a message, you must be able to provide the direct
  123. prev_events that said event references.
  124. """
  125. def post_json(destination, path, data, headers=None, timeout=0):
  126. if path.startswith("/_matrix/federation/v1/get_missing_events/"):
  127. return {
  128. "events": [
  129. {
  130. "room_id": self.room_id,
  131. "sender": "@baduser:test.serv",
  132. "event_id": "three:test.serv",
  133. "depth": 1000,
  134. "origin_server_ts": 1,
  135. "type": "m.room.message",
  136. "origin": "test.serv",
  137. "content": "hewwo?",
  138. "auth_events": [],
  139. "prev_events": [("four:test.serv", {})],
  140. }
  141. ]
  142. }
  143. self.http_client.post_json = post_json
  144. def get_json(destination, path, args, headers=None):
  145. if path.startswith("/_matrix/federation/v1/state_ids/"):
  146. d = self.successResultOf(
  147. self.homeserver.datastore.get_state_ids_for_event("one:test.serv")
  148. )
  149. return succeed(
  150. {
  151. "pdu_ids": [
  152. y
  153. for x, y in d.items()
  154. if x == ("m.room.member", "@us:test")
  155. ],
  156. "auth_chain_ids": list(d.values()),
  157. }
  158. )
  159. self.http_client.get_json = get_json
  160. # Figure out what the most recent event is
  161. most_recent = self.successResultOf(
  162. maybeDeferred(
  163. self.homeserver.datastore.get_latest_event_ids_in_room, self.room_id
  164. )
  165. )[0]
  166. # Make a good event
  167. good_event = FrozenEvent(
  168. {
  169. "room_id": self.room_id,
  170. "sender": "@baduser:test.serv",
  171. "event_id": "one:test.serv",
  172. "depth": 1000,
  173. "origin_server_ts": 1,
  174. "type": "m.room.message",
  175. "origin": "test.serv",
  176. "content": "hewwo?",
  177. "auth_events": [],
  178. "prev_events": [(most_recent, {})],
  179. }
  180. )
  181. d = self.handler.on_receive_pdu(
  182. "test.serv", good_event, sent_to_us_directly=True
  183. )
  184. self.reactor.advance(1)
  185. self.assertEqual(self.successResultOf(d), None)
  186. bad_event = FrozenEvent(
  187. {
  188. "room_id": self.room_id,
  189. "sender": "@baduser:test.serv",
  190. "event_id": "two:test.serv",
  191. "depth": 1000,
  192. "origin_server_ts": 1,
  193. "type": "m.room.message",
  194. "origin": "test.serv",
  195. "content": "hewwo?",
  196. "auth_events": [],
  197. "prev_events": [("one:test.serv", {}), ("three:test.serv", {})],
  198. }
  199. )
  200. d = self.handler.on_receive_pdu(
  201. "test.serv", bad_event, sent_to_us_directly=True
  202. )
  203. self.reactor.advance(1)
  204. extrem = maybeDeferred(
  205. self.homeserver.datastore.get_latest_event_ids_in_room, self.room_id
  206. )
  207. self.assertEqual(self.successResultOf(extrem)[0], "two:test.serv")
  208. state = self.homeserver.get_state_handler().get_current_state_ids(self.room_id)
  209. self.reactor.advance(1)
  210. self.assertIn(("m.room.member", "@us:test"), self.successResultOf(state).keys())