test_sendtodevice.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. # Copyright 2021 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 synapse.api.constants import EduTypes
  15. from synapse.rest import admin
  16. from synapse.rest.client import login, sendtodevice, sync
  17. from tests.unittest import HomeserverTestCase, override_config
  18. class SendToDeviceTestCase(HomeserverTestCase):
  19. servlets = [
  20. admin.register_servlets,
  21. login.register_servlets,
  22. sendtodevice.register_servlets,
  23. sync.register_servlets,
  24. ]
  25. def test_user_to_user(self) -> None:
  26. """A to-device message from one user to another should get delivered"""
  27. user1 = self.register_user("u1", "pass")
  28. user1_tok = self.login("u1", "pass", "d1")
  29. user2 = self.register_user("u2", "pass")
  30. user2_tok = self.login("u2", "pass", "d2")
  31. # send the message
  32. test_msg = {"foo": "bar"}
  33. chan = self.make_request(
  34. "PUT",
  35. "/_matrix/client/r0/sendToDevice/m.test/1234",
  36. content={"messages": {user2: {"d2": test_msg}}},
  37. access_token=user1_tok,
  38. )
  39. self.assertEqual(chan.code, 200, chan.result)
  40. # check it appears
  41. channel = self.make_request("GET", "/sync", access_token=user2_tok)
  42. self.assertEqual(channel.code, 200, channel.result)
  43. expected_result = {
  44. "events": [
  45. {
  46. "sender": user1,
  47. "type": "m.test",
  48. "content": test_msg,
  49. }
  50. ]
  51. }
  52. self.assertEqual(channel.json_body["to_device"], expected_result)
  53. # it should re-appear if we do another sync
  54. channel = self.make_request("GET", "/sync", access_token=user2_tok)
  55. self.assertEqual(channel.code, 200, channel.result)
  56. self.assertEqual(channel.json_body["to_device"], expected_result)
  57. # it should *not* appear if we do an incremental sync
  58. sync_token = channel.json_body["next_batch"]
  59. channel = self.make_request(
  60. "GET", f"/sync?since={sync_token}", access_token=user2_tok
  61. )
  62. self.assertEqual(channel.code, 200, channel.result)
  63. self.assertEqual(channel.json_body.get("to_device", {}).get("events", []), [])
  64. @override_config({"rc_key_requests": {"per_second": 10, "burst_count": 2}})
  65. def test_local_room_key_request(self) -> None:
  66. """m.room_key_request has special-casing; test from local user"""
  67. user1 = self.register_user("u1", "pass")
  68. user1_tok = self.login("u1", "pass", "d1")
  69. user2 = self.register_user("u2", "pass")
  70. user2_tok = self.login("u2", "pass", "d2")
  71. # send three messages
  72. for i in range(3):
  73. chan = self.make_request(
  74. "PUT",
  75. f"/_matrix/client/r0/sendToDevice/m.room_key_request/{i}",
  76. content={"messages": {user2: {"d2": {"idx": i}}}},
  77. access_token=user1_tok,
  78. )
  79. self.assertEqual(chan.code, 200, chan.result)
  80. # now sync: we should get two of the three
  81. channel = self.make_request("GET", "/sync", access_token=user2_tok)
  82. self.assertEqual(channel.code, 200, channel.result)
  83. msgs = channel.json_body["to_device"]["events"]
  84. self.assertEqual(len(msgs), 2)
  85. for i in range(2):
  86. self.assertEqual(
  87. msgs[i],
  88. {"sender": user1, "type": "m.room_key_request", "content": {"idx": i}},
  89. )
  90. sync_token = channel.json_body["next_batch"]
  91. # ... time passes
  92. self.reactor.advance(1)
  93. # and we can send more messages
  94. chan = self.make_request(
  95. "PUT",
  96. "/_matrix/client/r0/sendToDevice/m.room_key_request/3",
  97. content={"messages": {user2: {"d2": {"idx": 3}}}},
  98. access_token=user1_tok,
  99. )
  100. self.assertEqual(chan.code, 200, chan.result)
  101. # ... which should arrive
  102. channel = self.make_request(
  103. "GET", f"/sync?since={sync_token}", access_token=user2_tok
  104. )
  105. self.assertEqual(channel.code, 200, channel.result)
  106. msgs = channel.json_body["to_device"]["events"]
  107. self.assertEqual(len(msgs), 1)
  108. self.assertEqual(
  109. msgs[0],
  110. {"sender": user1, "type": "m.room_key_request", "content": {"idx": 3}},
  111. )
  112. @override_config({"rc_key_requests": {"per_second": 10, "burst_count": 2}})
  113. def test_remote_room_key_request(self) -> None:
  114. """m.room_key_request has special-casing; test from remote user"""
  115. user2 = self.register_user("u2", "pass")
  116. user2_tok = self.login("u2", "pass", "d2")
  117. federation_registry = self.hs.get_federation_registry()
  118. # send three messages
  119. for i in range(3):
  120. self.get_success(
  121. federation_registry.on_edu(
  122. EduTypes.DIRECT_TO_DEVICE,
  123. "remote_server",
  124. {
  125. "sender": "@user:remote_server",
  126. "type": "m.room_key_request",
  127. "messages": {user2: {"d2": {"idx": i}}},
  128. "message_id": f"{i}",
  129. },
  130. )
  131. )
  132. # now sync: we should get two of the three
  133. channel = self.make_request("GET", "/sync", access_token=user2_tok)
  134. self.assertEqual(channel.code, 200, channel.result)
  135. msgs = channel.json_body["to_device"]["events"]
  136. self.assertEqual(len(msgs), 2)
  137. for i in range(2):
  138. self.assertEqual(
  139. msgs[i],
  140. {
  141. "sender": "@user:remote_server",
  142. "type": "m.room_key_request",
  143. "content": {"idx": i},
  144. },
  145. )
  146. sync_token = channel.json_body["next_batch"]
  147. # ... time passes
  148. self.reactor.advance(1)
  149. # and we can send more messages
  150. self.get_success(
  151. federation_registry.on_edu(
  152. EduTypes.DIRECT_TO_DEVICE,
  153. "remote_server",
  154. {
  155. "sender": "@user:remote_server",
  156. "type": "m.room_key_request",
  157. "messages": {user2: {"d2": {"idx": 3}}},
  158. "message_id": "3",
  159. },
  160. )
  161. )
  162. # ... which should arrive
  163. channel = self.make_request(
  164. "GET", f"/sync?since={sync_token}", access_token=user2_tok
  165. )
  166. self.assertEqual(channel.code, 200, channel.result)
  167. msgs = channel.json_body["to_device"]["events"]
  168. self.assertEqual(len(msgs), 1)
  169. self.assertEqual(
  170. msgs[0],
  171. {
  172. "sender": "@user:remote_server",
  173. "type": "m.room_key_request",
  174. "content": {"idx": 3},
  175. },
  176. )
  177. def test_limited_sync(self) -> None:
  178. """If a limited sync for to-devices happens the next /sync should respond immediately."""
  179. self.register_user("u1", "pass")
  180. user1_tok = self.login("u1", "pass", "d1")
  181. user2 = self.register_user("u2", "pass")
  182. user2_tok = self.login("u2", "pass", "d2")
  183. # Do an initial sync
  184. channel = self.make_request("GET", "/sync", access_token=user2_tok)
  185. self.assertEqual(channel.code, 200, channel.result)
  186. sync_token = channel.json_body["next_batch"]
  187. # Send 150 to-device messages. We limit to 100 in `/sync`
  188. for i in range(150):
  189. test_msg = {"foo": "bar"}
  190. chan = self.make_request(
  191. "PUT",
  192. f"/_matrix/client/r0/sendToDevice/m.test/1234-{i}",
  193. content={"messages": {user2: {"d2": test_msg}}},
  194. access_token=user1_tok,
  195. )
  196. self.assertEqual(chan.code, 200, chan.result)
  197. channel = self.make_request(
  198. "GET", f"/sync?since={sync_token}&timeout=300000", access_token=user2_tok
  199. )
  200. self.assertEqual(channel.code, 200, channel.result)
  201. messages = channel.json_body.get("to_device", {}).get("events", [])
  202. self.assertEqual(len(messages), 100)
  203. sync_token = channel.json_body["next_batch"]
  204. channel = self.make_request(
  205. "GET", f"/sync?since={sync_token}&timeout=300000", access_token=user2_tok
  206. )
  207. self.assertEqual(channel.code, 200, channel.result)
  208. messages = channel.json_body.get("to_device", {}).get("events", [])
  209. self.assertEqual(len(messages), 50)