test_rooms.py 38 KB

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