summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/module_api/test_api.py56
-rw-r--r--tests/rest/client/test_room_access_rules.py253
-rw-r--r--tests/rest/client/third_party_rules.py31
3 files changed, 285 insertions, 55 deletions
diff --git a/tests/module_api/test_api.py b/tests/module_api/test_api.py

index 807cd65dd6..2d10931b33 100644 --- a/tests/module_api/test_api.py +++ b/tests/module_api/test_api.py
@@ -12,13 +12,20 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - from synapse.module_api import ModuleApi +from synapse.rest import admin +from synapse.rest.client.v1 import login, room from tests.unittest import HomeserverTestCase class ModuleApiTestCase(HomeserverTestCase): + servlets = [ + admin.register_servlets, + login.register_servlets, + room.register_servlets, + ] + def prepare(self, reactor, clock, homeserver): self.store = homeserver.get_datastore() self.module_api = ModuleApi(homeserver, homeserver.get_auth_handler()) @@ -52,3 +59,50 @@ class ModuleApiTestCase(HomeserverTestCase): # Check that the displayname was assigned displayname = self.get_success(self.store.get_profile_displayname("bob")) self.assertEqual(displayname, "Bobberino") + + def test_public_rooms(self): + """Tests that a room can be added and removed from the public rooms list, + as well as have its public rooms directory state queried. + """ + # Create a user and room to play with + user_id = self.register_user("kermit", "monkey") + tok = self.login("kermit", "monkey") + room_id = self.helper.create_room_as(user_id, tok=tok) + + # The room should not currently be in the public rooms directory + is_in_public_rooms = self.get_success( + self.module_api.public_room_list_manager.room_is_in_public_room_list( + room_id + ) + ) + self.assertFalse(is_in_public_rooms) + + # Let's try adding it to the public rooms directory + self.get_success( + self.module_api.public_room_list_manager.add_room_to_public_room_list( + room_id + ) + ) + + # And checking whether it's in there... + is_in_public_rooms = self.get_success( + self.module_api.public_room_list_manager.room_is_in_public_room_list( + room_id + ) + ) + self.assertTrue(is_in_public_rooms) + + # Let's remove it again + self.get_success( + self.module_api.public_room_list_manager.remove_room_from_public_room_list( + room_id + ) + ) + + # Should be gone + is_in_public_rooms = self.get_success( + self.module_api.public_room_list_manager.room_is_in_public_room_list( + room_id + ) + ) + self.assertFalse(is_in_public_rooms) diff --git a/tests/rest/client/test_room_access_rules.py b/tests/rest/client/test_room_access_rules.py
index fbb482f05b..ae59f8f911 100644 --- a/tests/rest/client/test_room_access_rules.py +++ b/tests/rest/client/test_room_access_rules.py
@@ -20,14 +20,15 @@ from mock import Mock from twisted.internet import defer -from synapse.api.constants import EventTypes, JoinRules, RoomCreationPreset +from synapse.api.constants import EventTypes, JoinRules, Membership, RoomCreationPreset from synapse.rest import admin -from synapse.rest.client.v1 import login, room +from synapse.rest.client.v1 import directory, login, room from synapse.third_party_rules.access_rules import ( ACCESS_RULES_TYPE, AccessRules, RoomAccessRules, ) +from synapse.types import create_requester from tests import unittest @@ -38,6 +39,7 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): admin.register_servlets, login.register_servlets, room.register_servlets, + directory.register_servlets, ] def make_homeserver(self, reactor, clock): @@ -99,6 +101,8 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): mock_http_client ) + self.third_party_event_rules = self.hs.get_third_party_event_rules() + return self.hs def prepare(self, reactor, clock, homeserver): @@ -200,8 +204,8 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): ) def test_public_room(self): - """Tests that it's not possible to have a room with the public join rule and an - access rule that's not restricted. + """Tests that it's only possible to have a room listed in the public room list + if the access rule is restricted. """ # Creating a room with the public_chat preset should succeed and set the access # rule to restricted. @@ -224,6 +228,26 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): self.current_rule_in_room(init_state_room_id), AccessRules.RESTRICTED ) + # List preset_room_id in the public room list + request, channel = self.make_request( + "PUT", + "/_matrix/client/r0/directory/list/room/%s" % (preset_room_id,), + {"visibility": "public"}, + access_token=self.tok, + ) + self.render(request) + self.assertEqual(channel.code, 200, channel.result) + + # List init_state_room_id in the public room list + request, channel = self.make_request( + "PUT", + "/_matrix/client/r0/directory/list/room/%s" % (init_state_room_id,), + {"visibility": "public"}, + access_token=self.tok, + ) + self.render(request) + self.assertEqual(channel.code, 200, channel.result) + # Changing access rule to unrestricted should fail. self.change_rule_in_room( preset_room_id, AccessRules.UNRESTRICTED, expected_code=403 @@ -238,54 +262,25 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): init_state_room_id, AccessRules.DIRECT, expected_code=403 ) - # Changing join rule to public in an unrestricted room should fail. - self.change_join_rule_in_room( - self.unrestricted_room, JoinRules.PUBLIC, expected_code=403 - ) - # Changing join rule to public in an direct room should fail. - self.change_join_rule_in_room( - self.direct_rooms[0], JoinRules.PUBLIC, expected_code=403 - ) - - # Creating a new room with the public_chat preset and an access rule that isn't - # restricted should fail. - self.create_room( - preset=RoomCreationPreset.PUBLIC_CHAT, - rule=AccessRules.UNRESTRICTED, - expected_code=400, - ) + # Creating a new room with the public_chat preset and an access rule of direct + # should fail. self.create_room( preset=RoomCreationPreset.PUBLIC_CHAT, rule=AccessRules.DIRECT, expected_code=400, ) - # Creating a room with the public join rule in its initial state and an access - # rule that isn't restricted should fail. - self.create_room( - initial_state=[ - { - "type": "m.room.join_rules", - "content": {"join_rule": JoinRules.PUBLIC}, - } - ], - rule=AccessRules.UNRESTRICTED, - expected_code=400, - ) - self.create_room( - initial_state=[ - { - "type": "m.room.join_rules", - "content": {"join_rule": JoinRules.PUBLIC}, - } - ], - rule=AccessRules.DIRECT, - expected_code=400, + # Changing join rule to public in an direct room should fail. + self.change_join_rule_in_room( + self.direct_rooms[0], JoinRules.PUBLIC, expected_code=403 ) def test_restricted(self): """Tests that in restricted mode we're unable to invite users from blacklisted servers but can invite other users. + + Also tests that the room can be published to, and removed from, the public room + list. """ # We can't invite a user from a forbidden HS. self.helper.invite( @@ -320,14 +315,33 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): expected_code=200, ) + # We are allowed to publish the room to the public room list + url = "/_matrix/client/r0/directory/list/room/%s" % self.restricted_room + data = {"visibility": "public"} + + request, channel = self.make_request("PUT", url, data, access_token=self.tok) + self.render(request) + self.assertEqual(channel.code, 200, channel.result) + + # We are allowed to remove the room from the public room list + url = "/_matrix/client/r0/directory/list/room/%s" % self.restricted_room + data = {"visibility": "private"} + + request, channel = self.make_request("PUT", url, data, access_token=self.tok) + self.render(request) + self.assertEqual(channel.code, 200, channel.result) + def test_direct(self): """Tests that, in direct mode, other users than the initial two can't be invited, but the following scenario works: * invited user joins the room * invited user leaves the room * room creator re-invites invited user - Also tests that a user from a HS that's in the list of forbidden domains (to use + + Tests that a user from a HS that's in the list of forbidden domains (to use in restricted mode) can be invited. + + Tests that the room cannot be published to the public room list. """ not_invited_user = "@not_invited:forbidden_domain" @@ -412,10 +426,20 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): self.hs.config.rc_third_party_invite.burst_count = burst self.hs.config.rc_third_party_invite.per_second = per_second + # We can't publish the room to the public room list + url = "/_matrix/client/r0/directory/list/room/%s" % self.direct_rooms[0] + data = {"visibility": "public"} + + request, channel = self.make_request("PUT", url, data, access_token=self.tok) + self.render(request) + self.assertEqual(channel.code, 403, channel.result) + def test_unrestricted(self): """Tests that, in unrestricted mode, we can invite whoever we want, but we can only change the power level of users that wouldn't be forbidden in restricted mode. + + Tests that the room cannot be published to the public room list. """ # We can invite self.helper.invite( @@ -482,6 +506,14 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): expect_code=403, ) + # We can't publish the room to the public room list + url = "/_matrix/client/r0/directory/list/room/%s" % self.unrestricted_room + data = {"visibility": "public"} + + request, channel = self.make_request("PUT", url, data, access_token=self.tok) + self.render(request) + self.assertEqual(channel.code, 403, channel.result) + def test_change_rules(self): """Tests that we can only change the current rule from restricted to unrestricted. @@ -526,6 +558,30 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): expected_code=403, ) + # We can't publish a room to the public room list and then change its rule to + # unrestricted + + # Create a restricted room + test_room_id = self.create_room(rule=AccessRules.RESTRICTED) + + # Publish the room to the public room list + url = "/_matrix/client/r0/directory/list/room/%s" % test_room_id + data = {"visibility": "public"} + + request, channel = self.make_request("PUT", url, data, access_token=self.tok) + self.render(request) + self.assertEqual(channel.code, 200, channel.result) + + # Attempt to switch the room to "unrestricted" + self.change_rule_in_room( + room_id=test_room_id, new_rule=AccessRules.UNRESTRICTED, expected_code=403 + ) + + # Attempt to switch the room to "direct" + self.change_rule_in_room( + room_id=test_room_id, new_rule=AccessRules.DIRECT, expected_code=403 + ) + def test_change_room_avatar(self): """Tests that changing the room avatar is always allowed unless the room is a direct chat, in which case it's forbidden. @@ -670,6 +726,119 @@ class RoomAccessTestCase(unittest.HomeserverTestCase): tok=self.tok, ) + def test_check_event_allowed(self): + """Tests that RoomAccessRules.check_event_allowed behaves accordingly. + + It tests that: + * forbidden users cannot join restricted rooms. + * forbidden users can only join unrestricted rooms if they have an invite. + """ + event_creator = self.hs.get_event_creation_handler() + + # Test that forbidden users cannot join restricted rooms + requester = create_requester(self.user_id) + allowed_requester = create_requester("@user:allowed_domain") + forbidden_requester = create_requester("@user:forbidden_domain") + + # Create a join event for a forbidden user + forbidden_join_event, forbidden_join_event_context = self.get_success( + event_creator.create_event( + forbidden_requester, + { + "type": EventTypes.Member, + "room_id": self.restricted_room, + "sender": forbidden_requester.user.to_string(), + "content": {"membership": Membership.JOIN}, + "state_key": forbidden_requester.user.to_string(), + }, + ) + ) + + # Create a join event for an allowed user + allowed_join_event, allowed_join_event_context = self.get_success( + event_creator.create_event( + allowed_requester, + { + "type": EventTypes.Member, + "room_id": self.restricted_room, + "sender": allowed_requester.user.to_string(), + "content": {"membership": Membership.JOIN}, + "state_key": allowed_requester.user.to_string(), + }, + ) + ) + + # Assert a join event from a forbidden user to a restricted room is rejected + can_join = self.get_success( + self.third_party_event_rules.check_event_allowed( + forbidden_join_event, forbidden_join_event_context + ) + ) + self.assertFalse(can_join) + + # But a join event from an non-forbidden user to a restricted room is allowed + can_join = self.get_success( + self.third_party_event_rules.check_event_allowed( + allowed_join_event, allowed_join_event_context + ) + ) + self.assertTrue(can_join) + + # Test that forbidden users can only join unrestricted rooms if they have an invite + + # Recreate the forbidden join event for the unrestricted room instead + forbidden_join_event, forbidden_join_event_context = self.get_success( + event_creator.create_event( + forbidden_requester, + { + "type": EventTypes.Member, + "room_id": self.unrestricted_room, + "sender": forbidden_requester.user.to_string(), + "content": {"membership": Membership.JOIN}, + "state_key": forbidden_requester.user.to_string(), + }, + ) + ) + + # A forbidden user without an invite should not be able to join an unrestricted room + can_join = self.get_success( + self.third_party_event_rules.check_event_allowed( + forbidden_join_event, forbidden_join_event_context + ) + ) + self.assertFalse(can_join) + + # However, if we then invite this user... + self.helper.invite( + room=self.unrestricted_room, + src=requester.user.to_string(), + targ=forbidden_requester.user.to_string(), + tok=self.tok, + ) + + # And create another join event, making sure that its context states it's coming + # in after the above invite was made... + forbidden_join_event, forbidden_join_event_context = self.get_success( + event_creator.create_event( + forbidden_requester, + { + "type": EventTypes.Member, + "room_id": self.unrestricted_room, + "sender": forbidden_requester.user.to_string(), + "content": {"membership": Membership.JOIN}, + "state_key": forbidden_requester.user.to_string(), + }, + ) + ) + + # Then the forbidden user should be able to join! + can_join = self.get_success( + self.third_party_event_rules.check_event_allowed( + forbidden_join_event, forbidden_join_event_context + ) + ) + self.assertTrue(can_join) + def create_room( self, direct=False, diff --git a/tests/rest/client/third_party_rules.py b/tests/rest/client/third_party_rules.py
index 7167fc56b6..9b79e9de6e 100644 --- a/tests/rest/client/third_party_rules.py +++ b/tests/rest/client/third_party_rules.py
@@ -12,18 +12,23 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - from synapse.rest import admin from synapse.rest.client.v1 import login, room +from synapse.types import Requester from tests import unittest class ThirdPartyRulesTestModule(object): - def __init__(self, config): + def __init__(self, config, *args, **kwargs): pass - def check_event_allowed(self, event, context): + async def on_create_room( + self, requester: Requester, config: dict, is_requester_admin: bool + ): + return True + + async def check_event_allowed(self, event, context): if event.type == "foo.bar.forbidden": return False else: @@ -51,29 +56,31 @@ class ThirdPartyRulesTestCase(unittest.HomeserverTestCase): self.hs = self.setup_test_homeserver(config=config) return self.hs + def prepare(self, reactor, clock, homeserver): + # Create a user and room to play with during the tests + self.user_id = self.register_user("kermit", "monkey") + self.tok = self.login("kermit", "monkey") + + self.room_id = self.helper.create_room_as(self.user_id, tok=self.tok) + def test_third_party_rules(self): """Tests that a forbidden event is forbidden from being sent, but an allowed one can be sent. """ - user_id = self.register_user("kermit", "monkey") - tok = self.login("kermit", "monkey") - - room_id = self.helper.create_room_as(user_id, tok=tok) - request, channel = self.make_request( "PUT", - "/_matrix/client/r0/rooms/%s/send/foo.bar.allowed/1" % room_id, + "/_matrix/client/r0/rooms/%s/send/foo.bar.allowed/1" % self.room_id, {}, - access_token=tok, + access_token=self.tok, ) self.render(request) self.assertEquals(channel.result["code"], b"200", channel.result) request, channel = self.make_request( "PUT", - "/_matrix/client/r0/rooms/%s/send/foo.bar.forbidden/1" % room_id, + "/_matrix/client/r0/rooms/%s/send/foo.bar.forbidden/1" % self.room_id, {}, - access_token=tok, + access_token=self.tok, ) self.render(request) self.assertEquals(channel.result["code"], b"403", channel.result)