test_event_auth.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. # Copyright 2018 New Vector Ltd
  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. import unittest
  15. from synapse import event_auth
  16. from synapse.api.errors import AuthError
  17. from synapse.api.room_versions import RoomVersions
  18. from synapse.events import make_event_from_dict
  19. from synapse.types import get_domain_from_id
  20. class EventAuthTestCase(unittest.TestCase):
  21. def test_random_users_cannot_send_state_before_first_pl(self):
  22. """
  23. Check that, before the first PL lands, the creator is the only user
  24. that can send a state event.
  25. """
  26. creator = "@creator:example.com"
  27. joiner = "@joiner:example.com"
  28. auth_events = {
  29. ("m.room.create", ""): _create_event(creator),
  30. ("m.room.member", creator): _join_event(creator),
  31. ("m.room.member", joiner): _join_event(joiner),
  32. }
  33. # creator should be able to send state
  34. event_auth.check(
  35. RoomVersions.V1,
  36. _random_state_event(creator),
  37. auth_events,
  38. do_sig_check=False,
  39. )
  40. # joiner should not be able to send state
  41. self.assertRaises(
  42. AuthError,
  43. event_auth.check,
  44. RoomVersions.V1,
  45. _random_state_event(joiner),
  46. auth_events,
  47. do_sig_check=False,
  48. )
  49. def test_state_default_level(self):
  50. """
  51. Check that users above the state_default level can send state and
  52. those below cannot
  53. """
  54. creator = "@creator:example.com"
  55. pleb = "@joiner:example.com"
  56. king = "@joiner2:example.com"
  57. auth_events = {
  58. ("m.room.create", ""): _create_event(creator),
  59. ("m.room.member", creator): _join_event(creator),
  60. ("m.room.power_levels", ""): _power_levels_event(
  61. creator, {"state_default": "30", "users": {pleb: "29", king: "30"}}
  62. ),
  63. ("m.room.member", pleb): _join_event(pleb),
  64. ("m.room.member", king): _join_event(king),
  65. }
  66. # pleb should not be able to send state
  67. self.assertRaises(
  68. AuthError,
  69. event_auth.check,
  70. RoomVersions.V1,
  71. _random_state_event(pleb),
  72. auth_events,
  73. do_sig_check=False,
  74. ),
  75. # king should be able to send state
  76. event_auth.check(
  77. RoomVersions.V1,
  78. _random_state_event(king),
  79. auth_events,
  80. do_sig_check=False,
  81. )
  82. def test_alias_event(self):
  83. """Alias events have special behavior up through room version 6."""
  84. creator = "@creator:example.com"
  85. other = "@other:example.com"
  86. auth_events = {
  87. ("m.room.create", ""): _create_event(creator),
  88. ("m.room.member", creator): _join_event(creator),
  89. }
  90. # creator should be able to send aliases
  91. event_auth.check(
  92. RoomVersions.V1,
  93. _alias_event(creator),
  94. auth_events,
  95. do_sig_check=False,
  96. )
  97. # Reject an event with no state key.
  98. with self.assertRaises(AuthError):
  99. event_auth.check(
  100. RoomVersions.V1,
  101. _alias_event(creator, state_key=""),
  102. auth_events,
  103. do_sig_check=False,
  104. )
  105. # If the domain of the sender does not match the state key, reject.
  106. with self.assertRaises(AuthError):
  107. event_auth.check(
  108. RoomVersions.V1,
  109. _alias_event(creator, state_key="test.com"),
  110. auth_events,
  111. do_sig_check=False,
  112. )
  113. # Note that the member does *not* need to be in the room.
  114. event_auth.check(
  115. RoomVersions.V1,
  116. _alias_event(other),
  117. auth_events,
  118. do_sig_check=False,
  119. )
  120. def test_msc2432_alias_event(self):
  121. """After MSC2432, alias events have no special behavior."""
  122. creator = "@creator:example.com"
  123. other = "@other:example.com"
  124. auth_events = {
  125. ("m.room.create", ""): _create_event(creator),
  126. ("m.room.member", creator): _join_event(creator),
  127. }
  128. # creator should be able to send aliases
  129. event_auth.check(
  130. RoomVersions.V6,
  131. _alias_event(creator),
  132. auth_events,
  133. do_sig_check=False,
  134. )
  135. # No particular checks are done on the state key.
  136. event_auth.check(
  137. RoomVersions.V6,
  138. _alias_event(creator, state_key=""),
  139. auth_events,
  140. do_sig_check=False,
  141. )
  142. event_auth.check(
  143. RoomVersions.V6,
  144. _alias_event(creator, state_key="test.com"),
  145. auth_events,
  146. do_sig_check=False,
  147. )
  148. # Per standard auth rules, the member must be in the room.
  149. with self.assertRaises(AuthError):
  150. event_auth.check(
  151. RoomVersions.V6,
  152. _alias_event(other),
  153. auth_events,
  154. do_sig_check=False,
  155. )
  156. def test_msc2209(self):
  157. """
  158. Notifications power levels get checked due to MSC2209.
  159. """
  160. creator = "@creator:example.com"
  161. pleb = "@joiner:example.com"
  162. auth_events = {
  163. ("m.room.create", ""): _create_event(creator),
  164. ("m.room.member", creator): _join_event(creator),
  165. ("m.room.power_levels", ""): _power_levels_event(
  166. creator, {"state_default": "30", "users": {pleb: "30"}}
  167. ),
  168. ("m.room.member", pleb): _join_event(pleb),
  169. }
  170. # pleb should be able to modify the notifications power level.
  171. event_auth.check(
  172. RoomVersions.V1,
  173. _power_levels_event(pleb, {"notifications": {"room": 100}}),
  174. auth_events,
  175. do_sig_check=False,
  176. )
  177. # But an MSC2209 room rejects this change.
  178. with self.assertRaises(AuthError):
  179. event_auth.check(
  180. RoomVersions.V6,
  181. _power_levels_event(pleb, {"notifications": {"room": 100}}),
  182. auth_events,
  183. do_sig_check=False,
  184. )
  185. def test_join_rules_public(self):
  186. """
  187. Test joining a public room.
  188. """
  189. creator = "@creator:example.com"
  190. pleb = "@joiner:example.com"
  191. auth_events = {
  192. ("m.room.create", ""): _create_event(creator),
  193. ("m.room.member", creator): _join_event(creator),
  194. ("m.room.join_rules", ""): _join_rules_event(creator, "public"),
  195. }
  196. # Check join.
  197. event_auth.check(
  198. RoomVersions.V6,
  199. _join_event(pleb),
  200. auth_events,
  201. do_sig_check=False,
  202. )
  203. # A user cannot be force-joined to a room.
  204. with self.assertRaises(AuthError):
  205. event_auth.check(
  206. RoomVersions.V6,
  207. _member_event(pleb, "join", sender=creator),
  208. auth_events,
  209. do_sig_check=False,
  210. )
  211. # Banned should be rejected.
  212. auth_events[("m.room.member", pleb)] = _member_event(pleb, "ban")
  213. with self.assertRaises(AuthError):
  214. event_auth.check(
  215. RoomVersions.V6,
  216. _join_event(pleb),
  217. auth_events,
  218. do_sig_check=False,
  219. )
  220. # A user who left can re-join.
  221. auth_events[("m.room.member", pleb)] = _member_event(pleb, "leave")
  222. event_auth.check(
  223. RoomVersions.V6,
  224. _join_event(pleb),
  225. auth_events,
  226. do_sig_check=False,
  227. )
  228. # A user can send a join if they're in the room.
  229. auth_events[("m.room.member", pleb)] = _member_event(pleb, "join")
  230. event_auth.check(
  231. RoomVersions.V6,
  232. _join_event(pleb),
  233. auth_events,
  234. do_sig_check=False,
  235. )
  236. # A user can accept an invite.
  237. auth_events[("m.room.member", pleb)] = _member_event(
  238. pleb, "invite", sender=creator
  239. )
  240. event_auth.check(
  241. RoomVersions.V6,
  242. _join_event(pleb),
  243. auth_events,
  244. do_sig_check=False,
  245. )
  246. def test_join_rules_invite(self):
  247. """
  248. Test joining an invite only room.
  249. """
  250. creator = "@creator:example.com"
  251. pleb = "@joiner:example.com"
  252. auth_events = {
  253. ("m.room.create", ""): _create_event(creator),
  254. ("m.room.member", creator): _join_event(creator),
  255. ("m.room.join_rules", ""): _join_rules_event(creator, "invite"),
  256. }
  257. # A join without an invite is rejected.
  258. with self.assertRaises(AuthError):
  259. event_auth.check(
  260. RoomVersions.V6,
  261. _join_event(pleb),
  262. auth_events,
  263. do_sig_check=False,
  264. )
  265. # A user cannot be force-joined to a room.
  266. with self.assertRaises(AuthError):
  267. event_auth.check(
  268. RoomVersions.V6,
  269. _member_event(pleb, "join", sender=creator),
  270. auth_events,
  271. do_sig_check=False,
  272. )
  273. # Banned should be rejected.
  274. auth_events[("m.room.member", pleb)] = _member_event(pleb, "ban")
  275. with self.assertRaises(AuthError):
  276. event_auth.check(
  277. RoomVersions.V6,
  278. _join_event(pleb),
  279. auth_events,
  280. do_sig_check=False,
  281. )
  282. # A user who left cannot re-join.
  283. auth_events[("m.room.member", pleb)] = _member_event(pleb, "leave")
  284. with self.assertRaises(AuthError):
  285. event_auth.check(
  286. RoomVersions.V6,
  287. _join_event(pleb),
  288. auth_events,
  289. do_sig_check=False,
  290. )
  291. # A user can send a join if they're in the room.
  292. auth_events[("m.room.member", pleb)] = _member_event(pleb, "join")
  293. event_auth.check(
  294. RoomVersions.V6,
  295. _join_event(pleb),
  296. auth_events,
  297. do_sig_check=False,
  298. )
  299. # A user can accept an invite.
  300. auth_events[("m.room.member", pleb)] = _member_event(
  301. pleb, "invite", sender=creator
  302. )
  303. event_auth.check(
  304. RoomVersions.V6,
  305. _join_event(pleb),
  306. auth_events,
  307. do_sig_check=False,
  308. )
  309. def test_join_rules_msc3083_restricted(self):
  310. """
  311. Test joining a restricted room from MSC3083.
  312. This is pretty much the same test as public.
  313. """
  314. creator = "@creator:example.com"
  315. pleb = "@joiner:example.com"
  316. auth_events = {
  317. ("m.room.create", ""): _create_event(creator),
  318. ("m.room.member", creator): _join_event(creator),
  319. ("m.room.join_rules", ""): _join_rules_event(creator, "restricted"),
  320. }
  321. # Older room versions don't understand this join rule
  322. with self.assertRaises(AuthError):
  323. event_auth.check(
  324. RoomVersions.V6,
  325. _join_event(pleb),
  326. auth_events,
  327. do_sig_check=False,
  328. )
  329. # Check join.
  330. event_auth.check(
  331. RoomVersions.MSC3083,
  332. _join_event(pleb),
  333. auth_events,
  334. do_sig_check=False,
  335. )
  336. # A user cannot be force-joined to a room.
  337. with self.assertRaises(AuthError):
  338. event_auth.check(
  339. RoomVersions.MSC3083,
  340. _member_event(pleb, "join", sender=creator),
  341. auth_events,
  342. do_sig_check=False,
  343. )
  344. # Banned should be rejected.
  345. auth_events[("m.room.member", pleb)] = _member_event(pleb, "ban")
  346. with self.assertRaises(AuthError):
  347. event_auth.check(
  348. RoomVersions.MSC3083,
  349. _join_event(pleb),
  350. auth_events,
  351. do_sig_check=False,
  352. )
  353. # A user who left can re-join.
  354. auth_events[("m.room.member", pleb)] = _member_event(pleb, "leave")
  355. event_auth.check(
  356. RoomVersions.MSC3083,
  357. _join_event(pleb),
  358. auth_events,
  359. do_sig_check=False,
  360. )
  361. # A user can send a join if they're in the room.
  362. auth_events[("m.room.member", pleb)] = _member_event(pleb, "join")
  363. event_auth.check(
  364. RoomVersions.MSC3083,
  365. _join_event(pleb),
  366. auth_events,
  367. do_sig_check=False,
  368. )
  369. # A user can accept an invite.
  370. auth_events[("m.room.member", pleb)] = _member_event(
  371. pleb, "invite", sender=creator
  372. )
  373. event_auth.check(
  374. RoomVersions.MSC3083,
  375. _join_event(pleb),
  376. auth_events,
  377. do_sig_check=False,
  378. )
  379. # helpers for making events
  380. TEST_ROOM_ID = "!test:room"
  381. def _create_event(user_id):
  382. return make_event_from_dict(
  383. {
  384. "room_id": TEST_ROOM_ID,
  385. "event_id": _get_event_id(),
  386. "type": "m.room.create",
  387. "sender": user_id,
  388. "content": {"creator": user_id},
  389. }
  390. )
  391. def _member_event(user_id, membership, sender=None):
  392. return make_event_from_dict(
  393. {
  394. "room_id": TEST_ROOM_ID,
  395. "event_id": _get_event_id(),
  396. "type": "m.room.member",
  397. "sender": sender or user_id,
  398. "state_key": user_id,
  399. "content": {"membership": membership},
  400. "prev_events": [],
  401. }
  402. )
  403. def _join_event(user_id):
  404. return _member_event(user_id, "join")
  405. def _power_levels_event(sender, content):
  406. return make_event_from_dict(
  407. {
  408. "room_id": TEST_ROOM_ID,
  409. "event_id": _get_event_id(),
  410. "type": "m.room.power_levels",
  411. "sender": sender,
  412. "state_key": "",
  413. "content": content,
  414. }
  415. )
  416. def _alias_event(sender, **kwargs):
  417. data = {
  418. "room_id": TEST_ROOM_ID,
  419. "event_id": _get_event_id(),
  420. "type": "m.room.aliases",
  421. "sender": sender,
  422. "state_key": get_domain_from_id(sender),
  423. "content": {"aliases": []},
  424. }
  425. data.update(**kwargs)
  426. return make_event_from_dict(data)
  427. def _random_state_event(sender):
  428. return make_event_from_dict(
  429. {
  430. "room_id": TEST_ROOM_ID,
  431. "event_id": _get_event_id(),
  432. "type": "test.state",
  433. "sender": sender,
  434. "state_key": "",
  435. "content": {"membership": "join"},
  436. }
  437. )
  438. def _join_rules_event(sender, join_rule):
  439. return make_event_from_dict(
  440. {
  441. "room_id": TEST_ROOM_ID,
  442. "event_id": _get_event_id(),
  443. "type": "m.room.join_rules",
  444. "sender": sender,
  445. "state_key": "",
  446. "content": {
  447. "join_rule": join_rule,
  448. },
  449. }
  450. )
  451. event_count = 0
  452. def _get_event_id():
  453. global event_count
  454. c = event_count
  455. event_count += 1
  456. return "!%i:example.com" % (c,)