1
0

test_rooms.py 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2014 OpenMarket Ltd
  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. """Tests REST events for /rooms paths."""
  16. # twisted imports
  17. from twisted.internet import defer
  18. import synapse.rest.client.v1.room
  19. from synapse.api.constants import Membership
  20. from synapse.types import UserID
  21. import json
  22. import urllib
  23. from ....utils import MockHttpResource, setup_test_homeserver
  24. from .utils import RestTestCase
  25. from mock import Mock, NonCallableMock
  26. PATH_PREFIX = "/_matrix/client/api/v1"
  27. class RoomPermissionsTestCase(RestTestCase):
  28. """ Tests room permissions. """
  29. user_id = "@sid1:red"
  30. rmcreator_id = "@notme:red"
  31. @defer.inlineCallbacks
  32. def setUp(self):
  33. self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
  34. hs = yield setup_test_homeserver(
  35. "red",
  36. http_client=None,
  37. replication_layer=Mock(),
  38. ratelimiter=NonCallableMock(spec_set=["send_message"]),
  39. )
  40. self.ratelimiter = hs.get_ratelimiter()
  41. self.ratelimiter.send_message.return_value = (True, 0)
  42. hs.get_handlers().federation_handler = Mock()
  43. def _get_user_by_access_token(token=None):
  44. return {
  45. "user": UserID.from_string(self.auth_user_id),
  46. "token_id": 1,
  47. }
  48. hs.get_v1auth()._get_user_by_access_token = _get_user_by_access_token
  49. def _insert_client_ip(*args, **kwargs):
  50. return defer.succeed(None)
  51. hs.get_datastore().insert_client_ip = _insert_client_ip
  52. self.auth_user_id = self.rmcreator_id
  53. synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource)
  54. self.auth = hs.get_v1auth()
  55. # create some rooms under the name rmcreator_id
  56. self.uncreated_rmid = "!aa:test"
  57. self.created_rmid = yield self.create_room_as(self.rmcreator_id,
  58. is_public=False)
  59. self.created_public_rmid = yield self.create_room_as(self.rmcreator_id,
  60. is_public=True)
  61. # send a message in one of the rooms
  62. self.created_rmid_msg_path = ("/rooms/%s/send/m.room.message/a1" %
  63. (self.created_rmid))
  64. (code, response) = yield self.mock_resource.trigger(
  65. "PUT",
  66. self.created_rmid_msg_path,
  67. '{"msgtype":"m.text","body":"test msg"}')
  68. self.assertEquals(200, code, msg=str(response))
  69. # set topic for public room
  70. (code, response) = yield self.mock_resource.trigger(
  71. "PUT",
  72. "/rooms/%s/state/m.room.topic" % self.created_public_rmid,
  73. '{"topic":"Public Room Topic"}')
  74. self.assertEquals(200, code, msg=str(response))
  75. # auth as user_id now
  76. self.auth_user_id = self.user_id
  77. def tearDown(self):
  78. pass
  79. # @defer.inlineCallbacks
  80. # def test_get_message(self):
  81. # # get message in uncreated room, expect 403
  82. # (code, response) = yield self.mock_resource.trigger_get(
  83. # "/rooms/noroom/messages/someid/m1")
  84. # self.assertEquals(403, code, msg=str(response))
  85. #
  86. # # get message in created room not joined (no state), expect 403
  87. # (code, response) = yield self.mock_resource.trigger_get(
  88. # self.created_rmid_msg_path)
  89. # self.assertEquals(403, code, msg=str(response))
  90. #
  91. # # get message in created room and invited, expect 403
  92. # yield self.invite(room=self.created_rmid, src=self.rmcreator_id,
  93. # targ=self.user_id)
  94. # (code, response) = yield self.mock_resource.trigger_get(
  95. # self.created_rmid_msg_path)
  96. # self.assertEquals(403, code, msg=str(response))
  97. #
  98. # # get message in created room and joined, expect 200
  99. # yield self.join(room=self.created_rmid, user=self.user_id)
  100. # (code, response) = yield self.mock_resource.trigger_get(
  101. # self.created_rmid_msg_path)
  102. # self.assertEquals(200, code, msg=str(response))
  103. #
  104. # # get message in created room and left, expect 403
  105. # yield self.leave(room=self.created_rmid, user=self.user_id)
  106. # (code, response) = yield self.mock_resource.trigger_get(
  107. # self.created_rmid_msg_path)
  108. # self.assertEquals(403, code, msg=str(response))
  109. @defer.inlineCallbacks
  110. def test_send_message(self):
  111. msg_content = '{"msgtype":"m.text","body":"hello"}'
  112. send_msg_path = (
  113. "/rooms/%s/send/m.room.message/mid1" % (self.created_rmid,)
  114. )
  115. # send message in uncreated room, expect 403
  116. (code, response) = yield self.mock_resource.trigger(
  117. "PUT",
  118. "/rooms/%s/send/m.room.message/mid2" % (self.uncreated_rmid,),
  119. msg_content
  120. )
  121. self.assertEquals(403, code, msg=str(response))
  122. # send message in created room not joined (no state), expect 403
  123. (code, response) = yield self.mock_resource.trigger(
  124. "PUT",
  125. send_msg_path,
  126. msg_content
  127. )
  128. self.assertEquals(403, code, msg=str(response))
  129. # send message in created room and invited, expect 403
  130. yield self.invite(
  131. room=self.created_rmid,
  132. src=self.rmcreator_id,
  133. targ=self.user_id
  134. )
  135. (code, response) = yield self.mock_resource.trigger(
  136. "PUT",
  137. send_msg_path,
  138. msg_content
  139. )
  140. self.assertEquals(403, code, msg=str(response))
  141. # send message in created room and joined, expect 200
  142. yield self.join(room=self.created_rmid, user=self.user_id)
  143. (code, response) = yield self.mock_resource.trigger(
  144. "PUT",
  145. send_msg_path,
  146. msg_content
  147. )
  148. self.assertEquals(200, code, msg=str(response))
  149. # send message in created room and left, expect 403
  150. yield self.leave(room=self.created_rmid, user=self.user_id)
  151. (code, response) = yield self.mock_resource.trigger(
  152. "PUT",
  153. send_msg_path,
  154. msg_content
  155. )
  156. self.assertEquals(403, code, msg=str(response))
  157. @defer.inlineCallbacks
  158. def test_topic_perms(self):
  159. topic_content = '{"topic":"My Topic Name"}'
  160. topic_path = "/rooms/%s/state/m.room.topic" % self.created_rmid
  161. # set/get topic in uncreated room, expect 403
  162. (code, response) = yield self.mock_resource.trigger(
  163. "PUT", "/rooms/%s/state/m.room.topic" % self.uncreated_rmid,
  164. topic_content)
  165. self.assertEquals(403, code, msg=str(response))
  166. (code, response) = yield self.mock_resource.trigger_get(
  167. "/rooms/%s/state/m.room.topic" % self.uncreated_rmid)
  168. self.assertEquals(403, code, msg=str(response))
  169. # set/get topic in created PRIVATE room not joined, expect 403
  170. (code, response) = yield self.mock_resource.trigger(
  171. "PUT", topic_path, topic_content)
  172. self.assertEquals(403, code, msg=str(response))
  173. (code, response) = yield self.mock_resource.trigger_get(topic_path)
  174. self.assertEquals(403, code, msg=str(response))
  175. # set topic in created PRIVATE room and invited, expect 403
  176. yield self.invite(room=self.created_rmid, src=self.rmcreator_id,
  177. targ=self.user_id)
  178. (code, response) = yield self.mock_resource.trigger(
  179. "PUT", topic_path, topic_content)
  180. self.assertEquals(403, code, msg=str(response))
  181. # get topic in created PRIVATE room and invited, expect 403
  182. (code, response) = yield self.mock_resource.trigger_get(topic_path)
  183. self.assertEquals(403, code, msg=str(response))
  184. # set/get topic in created PRIVATE room and joined, expect 200
  185. yield self.join(room=self.created_rmid, user=self.user_id)
  186. # Only room ops can set topic by default
  187. self.auth_user_id = self.rmcreator_id
  188. (code, response) = yield self.mock_resource.trigger(
  189. "PUT", topic_path, topic_content)
  190. self.assertEquals(200, code, msg=str(response))
  191. self.auth_user_id = self.user_id
  192. (code, response) = yield self.mock_resource.trigger_get(topic_path)
  193. self.assertEquals(200, code, msg=str(response))
  194. self.assert_dict(json.loads(topic_content), response)
  195. # set/get topic in created PRIVATE room and left, expect 403
  196. yield self.leave(room=self.created_rmid, user=self.user_id)
  197. (code, response) = yield self.mock_resource.trigger(
  198. "PUT", topic_path, topic_content)
  199. self.assertEquals(403, code, msg=str(response))
  200. (code, response) = yield self.mock_resource.trigger_get(topic_path)
  201. self.assertEquals(200, code, msg=str(response))
  202. # get topic in PUBLIC room, not joined, expect 403
  203. (code, response) = yield self.mock_resource.trigger_get(
  204. "/rooms/%s/state/m.room.topic" % self.created_public_rmid)
  205. self.assertEquals(403, code, msg=str(response))
  206. # set topic in PUBLIC room, not joined, expect 403
  207. (code, response) = yield self.mock_resource.trigger(
  208. "PUT",
  209. "/rooms/%s/state/m.room.topic" % self.created_public_rmid,
  210. topic_content)
  211. self.assertEquals(403, code, msg=str(response))
  212. @defer.inlineCallbacks
  213. def _test_get_membership(self, room=None, members=[], expect_code=None):
  214. path = "/rooms/%s/state/m.room.member/%s"
  215. for member in members:
  216. (code, response) = yield self.mock_resource.trigger_get(
  217. path %
  218. (room, member))
  219. self.assertEquals(expect_code, code)
  220. @defer.inlineCallbacks
  221. def test_membership_basic_room_perms(self):
  222. # === room does not exist ===
  223. room = self.uncreated_rmid
  224. # get membership of self, get membership of other, uncreated room
  225. # expect all 403s
  226. yield self._test_get_membership(
  227. members=[self.user_id, self.rmcreator_id],
  228. room=room, expect_code=403)
  229. # trying to invite people to this room should 403
  230. yield self.invite(room=room, src=self.user_id, targ=self.rmcreator_id,
  231. expect_code=403)
  232. # set [invite/join/left] of self, set [invite/join/left] of other,
  233. # expect all 403s
  234. for usr in [self.user_id, self.rmcreator_id]:
  235. yield self.join(room=room, user=usr, expect_code=404)
  236. yield self.leave(room=room, user=usr, expect_code=403)
  237. @defer.inlineCallbacks
  238. def test_membership_private_room_perms(self):
  239. room = self.created_rmid
  240. # get membership of self, get membership of other, private room + invite
  241. # expect all 403s
  242. yield self.invite(room=room, src=self.rmcreator_id,
  243. targ=self.user_id)
  244. yield self._test_get_membership(
  245. members=[self.user_id, self.rmcreator_id],
  246. room=room, expect_code=403)
  247. # get membership of self, get membership of other, private room + joined
  248. # expect all 200s
  249. yield self.join(room=room, user=self.user_id)
  250. yield self._test_get_membership(
  251. members=[self.user_id, self.rmcreator_id],
  252. room=room, expect_code=200)
  253. # get membership of self, get membership of other, private room + left
  254. # expect all 200s
  255. yield self.leave(room=room, user=self.user_id)
  256. yield self._test_get_membership(
  257. members=[self.user_id, self.rmcreator_id],
  258. room=room, expect_code=200)
  259. @defer.inlineCallbacks
  260. def test_membership_public_room_perms(self):
  261. room = self.created_public_rmid
  262. # get membership of self, get membership of other, public room + invite
  263. # expect 403
  264. yield self.invite(room=room, src=self.rmcreator_id,
  265. targ=self.user_id)
  266. yield self._test_get_membership(
  267. members=[self.user_id, self.rmcreator_id],
  268. room=room, expect_code=403)
  269. # get membership of self, get membership of other, public room + joined
  270. # expect all 200s
  271. yield self.join(room=room, user=self.user_id)
  272. yield self._test_get_membership(
  273. members=[self.user_id, self.rmcreator_id],
  274. room=room, expect_code=200)
  275. # get membership of self, get membership of other, public room + left
  276. # expect 200.
  277. yield self.leave(room=room, user=self.user_id)
  278. yield self._test_get_membership(
  279. members=[self.user_id, self.rmcreator_id],
  280. room=room, expect_code=200)
  281. @defer.inlineCallbacks
  282. def test_invited_permissions(self):
  283. room = self.created_rmid
  284. yield self.invite(room=room, src=self.rmcreator_id, targ=self.user_id)
  285. # set [invite/join/left] of other user, expect 403s
  286. yield self.invite(room=room, src=self.user_id, targ=self.rmcreator_id,
  287. expect_code=403)
  288. yield self.change_membership(room=room, src=self.user_id,
  289. targ=self.rmcreator_id,
  290. membership=Membership.JOIN,
  291. expect_code=403)
  292. yield self.change_membership(room=room, src=self.user_id,
  293. targ=self.rmcreator_id,
  294. membership=Membership.LEAVE,
  295. expect_code=403)
  296. @defer.inlineCallbacks
  297. def test_joined_permissions(self):
  298. room = self.created_rmid
  299. yield self.invite(room=room, src=self.rmcreator_id, targ=self.user_id)
  300. yield self.join(room=room, user=self.user_id)
  301. # set invited of self, expect 403
  302. yield self.invite(room=room, src=self.user_id, targ=self.user_id,
  303. expect_code=403)
  304. # set joined of self, expect 200 (NOOP)
  305. yield self.join(room=room, user=self.user_id)
  306. other = "@burgundy:red"
  307. # set invited of other, expect 200
  308. yield self.invite(room=room, src=self.user_id, targ=other,
  309. expect_code=200)
  310. # set joined of other, expect 403
  311. yield self.change_membership(room=room, src=self.user_id,
  312. targ=other,
  313. membership=Membership.JOIN,
  314. expect_code=403)
  315. # set left of other, expect 403
  316. yield self.change_membership(room=room, src=self.user_id,
  317. targ=other,
  318. membership=Membership.LEAVE,
  319. expect_code=403)
  320. # set left of self, expect 200
  321. yield self.leave(room=room, user=self.user_id)
  322. @defer.inlineCallbacks
  323. def test_leave_permissions(self):
  324. room = self.created_rmid
  325. yield self.invite(room=room, src=self.rmcreator_id, targ=self.user_id)
  326. yield self.join(room=room, user=self.user_id)
  327. yield self.leave(room=room, user=self.user_id)
  328. # set [invite/join/left] of self, set [invite/join/left] of other,
  329. # expect all 403s
  330. for usr in [self.user_id, self.rmcreator_id]:
  331. yield self.change_membership(
  332. room=room,
  333. src=self.user_id,
  334. targ=usr,
  335. membership=Membership.INVITE,
  336. expect_code=403
  337. )
  338. yield self.change_membership(
  339. room=room,
  340. src=self.user_id,
  341. targ=usr,
  342. membership=Membership.JOIN,
  343. expect_code=403
  344. )
  345. # It is always valid to LEAVE if you've already left (currently.)
  346. yield self.change_membership(
  347. room=room,
  348. src=self.user_id,
  349. targ=self.rmcreator_id,
  350. membership=Membership.LEAVE,
  351. expect_code=403
  352. )
  353. class RoomsMemberListTestCase(RestTestCase):
  354. """ Tests /rooms/$room_id/members/list REST events."""
  355. user_id = "@sid1:red"
  356. @defer.inlineCallbacks
  357. def setUp(self):
  358. self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
  359. hs = yield setup_test_homeserver(
  360. "red",
  361. http_client=None,
  362. replication_layer=Mock(),
  363. ratelimiter=NonCallableMock(spec_set=["send_message"]),
  364. )
  365. self.ratelimiter = hs.get_ratelimiter()
  366. self.ratelimiter.send_message.return_value = (True, 0)
  367. hs.get_handlers().federation_handler = Mock()
  368. self.auth_user_id = self.user_id
  369. def _get_user_by_access_token(token=None):
  370. return {
  371. "user": UserID.from_string(self.auth_user_id),
  372. "token_id": 1,
  373. }
  374. hs.get_v1auth()._get_user_by_access_token = _get_user_by_access_token
  375. def _insert_client_ip(*args, **kwargs):
  376. return defer.succeed(None)
  377. hs.get_datastore().insert_client_ip = _insert_client_ip
  378. synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource)
  379. def tearDown(self):
  380. pass
  381. @defer.inlineCallbacks
  382. def test_get_member_list(self):
  383. room_id = yield self.create_room_as(self.user_id)
  384. (code, response) = yield self.mock_resource.trigger_get(
  385. "/rooms/%s/members" % room_id)
  386. self.assertEquals(200, code, msg=str(response))
  387. @defer.inlineCallbacks
  388. def test_get_member_list_no_room(self):
  389. (code, response) = yield self.mock_resource.trigger_get(
  390. "/rooms/roomdoesnotexist/members")
  391. self.assertEquals(403, code, msg=str(response))
  392. @defer.inlineCallbacks
  393. def test_get_member_list_no_permission(self):
  394. room_id = yield self.create_room_as("@some_other_guy:red")
  395. (code, response) = yield self.mock_resource.trigger_get(
  396. "/rooms/%s/members" % room_id)
  397. self.assertEquals(403, code, msg=str(response))
  398. @defer.inlineCallbacks
  399. def test_get_member_list_mixed_memberships(self):
  400. room_creator = "@some_other_guy:red"
  401. room_id = yield self.create_room_as(room_creator)
  402. room_path = "/rooms/%s/members" % room_id
  403. yield self.invite(room=room_id, src=room_creator,
  404. targ=self.user_id)
  405. # can't see list if you're just invited.
  406. (code, response) = yield self.mock_resource.trigger_get(room_path)
  407. self.assertEquals(403, code, msg=str(response))
  408. yield self.join(room=room_id, user=self.user_id)
  409. # can see list now joined
  410. (code, response) = yield self.mock_resource.trigger_get(room_path)
  411. self.assertEquals(200, code, msg=str(response))
  412. yield self.leave(room=room_id, user=self.user_id)
  413. # can see old list once left
  414. (code, response) = yield self.mock_resource.trigger_get(room_path)
  415. self.assertEquals(200, code, msg=str(response))
  416. class RoomsCreateTestCase(RestTestCase):
  417. """ Tests /rooms and /rooms/$room_id REST events. """
  418. user_id = "@sid1:red"
  419. @defer.inlineCallbacks
  420. def setUp(self):
  421. self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
  422. self.auth_user_id = self.user_id
  423. hs = yield setup_test_homeserver(
  424. "red",
  425. http_client=None,
  426. replication_layer=Mock(),
  427. ratelimiter=NonCallableMock(spec_set=["send_message"]),
  428. )
  429. self.ratelimiter = hs.get_ratelimiter()
  430. self.ratelimiter.send_message.return_value = (True, 0)
  431. hs.get_handlers().federation_handler = Mock()
  432. def _get_user_by_access_token(token=None):
  433. return {
  434. "user": UserID.from_string(self.auth_user_id),
  435. "token_id": 1,
  436. }
  437. hs.get_v1auth()._get_user_by_access_token = _get_user_by_access_token
  438. def _insert_client_ip(*args, **kwargs):
  439. return defer.succeed(None)
  440. hs.get_datastore().insert_client_ip = _insert_client_ip
  441. synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource)
  442. def tearDown(self):
  443. pass
  444. @defer.inlineCallbacks
  445. def test_post_room_no_keys(self):
  446. # POST with no config keys, expect new room id
  447. (code, response) = yield self.mock_resource.trigger("POST",
  448. "/createRoom",
  449. "{}")
  450. self.assertEquals(200, code, response)
  451. self.assertTrue("room_id" in response)
  452. @defer.inlineCallbacks
  453. def test_post_room_visibility_key(self):
  454. # POST with visibility config key, expect new room id
  455. (code, response) = yield self.mock_resource.trigger(
  456. "POST",
  457. "/createRoom",
  458. '{"visibility":"private"}')
  459. self.assertEquals(200, code)
  460. self.assertTrue("room_id" in response)
  461. @defer.inlineCallbacks
  462. def test_post_room_custom_key(self):
  463. # POST with custom config keys, expect new room id
  464. (code, response) = yield self.mock_resource.trigger(
  465. "POST",
  466. "/createRoom",
  467. '{"custom":"stuff"}')
  468. self.assertEquals(200, code)
  469. self.assertTrue("room_id" in response)
  470. @defer.inlineCallbacks
  471. def test_post_room_known_and_unknown_keys(self):
  472. # POST with custom + known config keys, expect new room id
  473. (code, response) = yield self.mock_resource.trigger(
  474. "POST",
  475. "/createRoom",
  476. '{"visibility":"private","custom":"things"}')
  477. self.assertEquals(200, code)
  478. self.assertTrue("room_id" in response)
  479. @defer.inlineCallbacks
  480. def test_post_room_invalid_content(self):
  481. # POST with invalid content / paths, expect 400
  482. (code, response) = yield self.mock_resource.trigger(
  483. "POST",
  484. "/createRoom",
  485. '{"visibili')
  486. self.assertEquals(400, code)
  487. (code, response) = yield self.mock_resource.trigger(
  488. "POST",
  489. "/createRoom",
  490. '["hello"]')
  491. self.assertEquals(400, code)
  492. class RoomTopicTestCase(RestTestCase):
  493. """ Tests /rooms/$room_id/topic REST events. """
  494. user_id = "@sid1:red"
  495. @defer.inlineCallbacks
  496. def setUp(self):
  497. self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
  498. self.auth_user_id = self.user_id
  499. hs = yield setup_test_homeserver(
  500. "red",
  501. http_client=None,
  502. replication_layer=Mock(),
  503. ratelimiter=NonCallableMock(spec_set=["send_message"]),
  504. )
  505. self.ratelimiter = hs.get_ratelimiter()
  506. self.ratelimiter.send_message.return_value = (True, 0)
  507. hs.get_handlers().federation_handler = Mock()
  508. def _get_user_by_access_token(token=None):
  509. return {
  510. "user": UserID.from_string(self.auth_user_id),
  511. "token_id": 1,
  512. }
  513. hs.get_v1auth()._get_user_by_access_token = _get_user_by_access_token
  514. def _insert_client_ip(*args, **kwargs):
  515. return defer.succeed(None)
  516. hs.get_datastore().insert_client_ip = _insert_client_ip
  517. synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource)
  518. # create the room
  519. self.room_id = yield self.create_room_as(self.user_id)
  520. self.path = "/rooms/%s/state/m.room.topic" % (self.room_id,)
  521. def tearDown(self):
  522. pass
  523. @defer.inlineCallbacks
  524. def test_invalid_puts(self):
  525. # missing keys or invalid json
  526. (code, response) = yield self.mock_resource.trigger("PUT",
  527. self.path, '{}')
  528. self.assertEquals(400, code, msg=str(response))
  529. (code, response) = yield self.mock_resource.trigger("PUT",
  530. self.path, '{"_name":"bob"}')
  531. self.assertEquals(400, code, msg=str(response))
  532. (code, response) = yield self.mock_resource.trigger("PUT",
  533. self.path, '{"nao')
  534. self.assertEquals(400, code, msg=str(response))
  535. (code, response) = yield self.mock_resource.trigger("PUT",
  536. self.path, '[{"_name":"bob"},{"_name":"jill"}]')
  537. self.assertEquals(400, code, msg=str(response))
  538. (code, response) = yield self.mock_resource.trigger("PUT",
  539. self.path, 'text only')
  540. self.assertEquals(400, code, msg=str(response))
  541. (code, response) = yield self.mock_resource.trigger("PUT",
  542. self.path, '')
  543. self.assertEquals(400, code, msg=str(response))
  544. # valid key, wrong type
  545. content = '{"topic":["Topic name"]}'
  546. (code, response) = yield self.mock_resource.trigger("PUT",
  547. self.path, content)
  548. self.assertEquals(400, code, msg=str(response))
  549. @defer.inlineCallbacks
  550. def test_rooms_topic(self):
  551. # nothing should be there
  552. (code, response) = yield self.mock_resource.trigger_get(self.path)
  553. self.assertEquals(404, code, msg=str(response))
  554. # valid put
  555. content = '{"topic":"Topic name"}'
  556. (code, response) = yield self.mock_resource.trigger("PUT",
  557. self.path, content)
  558. self.assertEquals(200, code, msg=str(response))
  559. # valid get
  560. (code, response) = yield self.mock_resource.trigger_get(self.path)
  561. self.assertEquals(200, code, msg=str(response))
  562. self.assert_dict(json.loads(content), response)
  563. @defer.inlineCallbacks
  564. def test_rooms_topic_with_extra_keys(self):
  565. # valid put with extra keys
  566. content = '{"topic":"Seasons","subtopic":"Summer"}'
  567. (code, response) = yield self.mock_resource.trigger("PUT",
  568. self.path, content)
  569. self.assertEquals(200, code, msg=str(response))
  570. # valid get
  571. (code, response) = yield self.mock_resource.trigger_get(self.path)
  572. self.assertEquals(200, code, msg=str(response))
  573. self.assert_dict(json.loads(content), response)
  574. class RoomMemberStateTestCase(RestTestCase):
  575. """ Tests /rooms/$room_id/members/$user_id/state REST events. """
  576. user_id = "@sid1:red"
  577. @defer.inlineCallbacks
  578. def setUp(self):
  579. self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
  580. self.auth_user_id = self.user_id
  581. hs = yield setup_test_homeserver(
  582. "red",
  583. http_client=None,
  584. replication_layer=Mock(),
  585. ratelimiter=NonCallableMock(spec_set=["send_message"]),
  586. )
  587. self.ratelimiter = hs.get_ratelimiter()
  588. self.ratelimiter.send_message.return_value = (True, 0)
  589. hs.get_handlers().federation_handler = Mock()
  590. def _get_user_by_access_token(token=None):
  591. return {
  592. "user": UserID.from_string(self.auth_user_id),
  593. "token_id": 1,
  594. }
  595. hs.get_v1auth()._get_user_by_access_token = _get_user_by_access_token
  596. def _insert_client_ip(*args, **kwargs):
  597. return defer.succeed(None)
  598. hs.get_datastore().insert_client_ip = _insert_client_ip
  599. synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource)
  600. self.room_id = yield self.create_room_as(self.user_id)
  601. def tearDown(self):
  602. pass
  603. @defer.inlineCallbacks
  604. def test_invalid_puts(self):
  605. path = "/rooms/%s/state/m.room.member/%s" % (self.room_id, self.user_id)
  606. # missing keys or invalid json
  607. (code, response) = yield self.mock_resource.trigger("PUT",
  608. path, '{}')
  609. self.assertEquals(400, code, msg=str(response))
  610. (code, response) = yield self.mock_resource.trigger("PUT",
  611. path, '{"_name":"bob"}')
  612. self.assertEquals(400, code, msg=str(response))
  613. (code, response) = yield self.mock_resource.trigger("PUT",
  614. path, '{"nao')
  615. self.assertEquals(400, code, msg=str(response))
  616. (code, response) = yield self.mock_resource.trigger("PUT",
  617. path, '[{"_name":"bob"},{"_name":"jill"}]')
  618. self.assertEquals(400, code, msg=str(response))
  619. (code, response) = yield self.mock_resource.trigger("PUT",
  620. path, 'text only')
  621. self.assertEquals(400, code, msg=str(response))
  622. (code, response) = yield self.mock_resource.trigger("PUT",
  623. path, '')
  624. self.assertEquals(400, code, msg=str(response))
  625. # valid keys, wrong types
  626. content = ('{"membership":["%s","%s","%s"]}' %
  627. (Membership.INVITE, Membership.JOIN, Membership.LEAVE))
  628. (code, response) = yield self.mock_resource.trigger("PUT", path, content)
  629. self.assertEquals(400, code, msg=str(response))
  630. @defer.inlineCallbacks
  631. def test_rooms_members_self(self):
  632. path = "/rooms/%s/state/m.room.member/%s" % (
  633. urllib.quote(self.room_id), self.user_id
  634. )
  635. # valid join message (NOOP since we made the room)
  636. content = '{"membership":"%s"}' % Membership.JOIN
  637. (code, response) = yield self.mock_resource.trigger("PUT", path, content)
  638. self.assertEquals(200, code, msg=str(response))
  639. (code, response) = yield self.mock_resource.trigger("GET", path, None)
  640. self.assertEquals(200, code, msg=str(response))
  641. expected_response = {
  642. "membership": Membership.JOIN,
  643. }
  644. self.assertEquals(expected_response, response)
  645. @defer.inlineCallbacks
  646. def test_rooms_members_other(self):
  647. self.other_id = "@zzsid1:red"
  648. path = "/rooms/%s/state/m.room.member/%s" % (
  649. urllib.quote(self.room_id), self.other_id
  650. )
  651. # valid invite message
  652. content = '{"membership":"%s"}' % Membership.INVITE
  653. (code, response) = yield self.mock_resource.trigger("PUT", path, content)
  654. self.assertEquals(200, code, msg=str(response))
  655. (code, response) = yield self.mock_resource.trigger("GET", path, None)
  656. self.assertEquals(200, code, msg=str(response))
  657. self.assertEquals(json.loads(content), response)
  658. @defer.inlineCallbacks
  659. def test_rooms_members_other_custom_keys(self):
  660. self.other_id = "@zzsid1:red"
  661. path = "/rooms/%s/state/m.room.member/%s" % (
  662. urllib.quote(self.room_id), self.other_id
  663. )
  664. # valid invite message with custom key
  665. content = ('{"membership":"%s","invite_text":"%s"}' %
  666. (Membership.INVITE, "Join us!"))
  667. (code, response) = yield self.mock_resource.trigger("PUT", path, content)
  668. self.assertEquals(200, code, msg=str(response))
  669. (code, response) = yield self.mock_resource.trigger("GET", path, None)
  670. self.assertEquals(200, code, msg=str(response))
  671. self.assertEquals(json.loads(content), response)
  672. class RoomMessagesTestCase(RestTestCase):
  673. """ Tests /rooms/$room_id/messages/$user_id/$msg_id REST events. """
  674. user_id = "@sid1:red"
  675. @defer.inlineCallbacks
  676. def setUp(self):
  677. self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
  678. self.auth_user_id = self.user_id
  679. hs = yield setup_test_homeserver(
  680. "red",
  681. http_client=None,
  682. replication_layer=Mock(),
  683. ratelimiter=NonCallableMock(spec_set=["send_message"]),
  684. )
  685. self.ratelimiter = hs.get_ratelimiter()
  686. self.ratelimiter.send_message.return_value = (True, 0)
  687. hs.get_handlers().federation_handler = Mock()
  688. def _get_user_by_access_token(token=None):
  689. return {
  690. "user": UserID.from_string(self.auth_user_id),
  691. "token_id": 1,
  692. }
  693. hs.get_v1auth()._get_user_by_access_token = _get_user_by_access_token
  694. def _insert_client_ip(*args, **kwargs):
  695. return defer.succeed(None)
  696. hs.get_datastore().insert_client_ip = _insert_client_ip
  697. synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource)
  698. self.room_id = yield self.create_room_as(self.user_id)
  699. def tearDown(self):
  700. pass
  701. @defer.inlineCallbacks
  702. def test_invalid_puts(self):
  703. path = "/rooms/%s/send/m.room.message/mid1" % (
  704. urllib.quote(self.room_id))
  705. # missing keys or invalid json
  706. (code, response) = yield self.mock_resource.trigger("PUT",
  707. path, '{}')
  708. self.assertEquals(400, code, msg=str(response))
  709. (code, response) = yield self.mock_resource.trigger("PUT",
  710. path, '{"_name":"bob"}')
  711. self.assertEquals(400, code, msg=str(response))
  712. (code, response) = yield self.mock_resource.trigger("PUT",
  713. path, '{"nao')
  714. self.assertEquals(400, code, msg=str(response))
  715. (code, response) = yield self.mock_resource.trigger("PUT",
  716. path, '[{"_name":"bob"},{"_name":"jill"}]')
  717. self.assertEquals(400, code, msg=str(response))
  718. (code, response) = yield self.mock_resource.trigger("PUT",
  719. path, 'text only')
  720. self.assertEquals(400, code, msg=str(response))
  721. (code, response) = yield self.mock_resource.trigger("PUT",
  722. path, '')
  723. self.assertEquals(400, code, msg=str(response))
  724. @defer.inlineCallbacks
  725. def test_rooms_messages_sent(self):
  726. path = "/rooms/%s/send/m.room.message/mid1" % (
  727. urllib.quote(self.room_id))
  728. content = '{"body":"test","msgtype":{"type":"a"}}'
  729. (code, response) = yield self.mock_resource.trigger("PUT", path, content)
  730. self.assertEquals(400, code, msg=str(response))
  731. # custom message types
  732. content = '{"body":"test","msgtype":"test.custom.text"}'
  733. (code, response) = yield self.mock_resource.trigger("PUT", path, content)
  734. self.assertEquals(200, code, msg=str(response))
  735. # (code, response) = yield self.mock_resource.trigger("GET", path, None)
  736. # self.assertEquals(200, code, msg=str(response))
  737. # self.assert_dict(json.loads(content), response)
  738. # m.text message type
  739. path = "/rooms/%s/send/m.room.message/mid2" % (
  740. urllib.quote(self.room_id))
  741. content = '{"body":"test2","msgtype":"m.text"}'
  742. (code, response) = yield self.mock_resource.trigger("PUT", path, content)
  743. self.assertEquals(200, code, msg=str(response))
  744. class RoomInitialSyncTestCase(RestTestCase):
  745. """ Tests /rooms/$room_id/initialSync. """
  746. user_id = "@sid1:red"
  747. @defer.inlineCallbacks
  748. def setUp(self):
  749. self.mock_resource = MockHttpResource(prefix=PATH_PREFIX)
  750. self.auth_user_id = self.user_id
  751. hs = yield setup_test_homeserver(
  752. "red",
  753. http_client=None,
  754. replication_layer=Mock(),
  755. ratelimiter=NonCallableMock(spec_set=[
  756. "send_message",
  757. ]),
  758. )
  759. self.ratelimiter = hs.get_ratelimiter()
  760. self.ratelimiter.send_message.return_value = (True, 0)
  761. hs.get_handlers().federation_handler = Mock()
  762. def _get_user_by_access_token(token=None):
  763. return {
  764. "user": UserID.from_string(self.auth_user_id),
  765. "token_id": 1,
  766. }
  767. hs.get_v1auth()._get_user_by_access_token = _get_user_by_access_token
  768. def _insert_client_ip(*args, **kwargs):
  769. return defer.succeed(None)
  770. hs.get_datastore().insert_client_ip = _insert_client_ip
  771. synapse.rest.client.v1.room.register_servlets(hs, self.mock_resource)
  772. # Since I'm getting my own presence I need to exist as far as presence
  773. # is concerned.
  774. hs.get_handlers().presence_handler.registered_user(
  775. UserID.from_string(self.user_id)
  776. )
  777. # create the room
  778. self.room_id = yield self.create_room_as(self.user_id)
  779. @defer.inlineCallbacks
  780. def test_initial_sync(self):
  781. (code, response) = yield self.mock_resource.trigger_get(
  782. "/rooms/%s/initialSync" % self.room_id)
  783. self.assertEquals(200, code)
  784. self.assertEquals(self.room_id, response["room_id"])
  785. self.assertEquals("join", response["membership"])
  786. # Room state is easier to assert on if we unpack it into a dict
  787. state = {}
  788. for event in response["state"]:
  789. if "state_key" not in event:
  790. continue
  791. t = event["type"]
  792. if t not in state:
  793. state[t] = []
  794. state[t].append(event)
  795. self.assertTrue("m.room.create" in state)
  796. self.assertTrue("messages" in response)
  797. self.assertTrue("chunk" in response["messages"])
  798. self.assertTrue("end" in response["messages"])
  799. self.assertTrue("presence" in response)
  800. presence_by_user = {e["content"]["user_id"]: e
  801. for e in response["presence"]
  802. }
  803. self.assertTrue(self.user_id in presence_by_user)
  804. self.assertEquals("m.presence", presence_by_user[self.user_id]["type"])