diff --git a/tests/federation/test_complexity.py b/tests/federation/test_complexity.py
index 1e3e5aec66..24fa8dbb45 100644
--- a/tests/federation/test_complexity.py
+++ b/tests/federation/test_complexity.py
@@ -13,18 +13,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from mock import Mock
+
from twisted.internet import defer
-from synapse.config.ratelimiting import FederationRateLimitConfig
-from synapse.federation.transport import server
+from synapse.api.errors import Codes, SynapseError
from synapse.rest import admin
from synapse.rest.client.v1 import login, room
-from synapse.util.ratelimitutils import FederationRateLimiter
+from synapse.types import UserID
from tests import unittest
-class RoomComplexityTests(unittest.HomeserverTestCase):
+class RoomComplexityTests(unittest.FederatingHomeserverTestCase):
servlets = [
admin.register_servlets,
@@ -32,31 +33,11 @@ class RoomComplexityTests(unittest.HomeserverTestCase):
login.register_servlets,
]
- def default_config(self, name='test'):
- config = super(RoomComplexityTests, self).default_config(name=name)
- config["limit_large_remote_room_joins"] = True
- config["limit_large_remote_room_complexity"] = 0.05
+ def default_config(self, name="test"):
+ config = super().default_config(name=name)
+ config["limit_remote_rooms"] = {"enabled": True, "complexity": 0.05}
return config
- def prepare(self, reactor, clock, homeserver):
- class Authenticator(object):
- def authenticate_request(self, request, content):
- return defer.succeed("otherserver.nottld")
-
- ratelimiter = FederationRateLimiter(
- clock,
- FederationRateLimitConfig(
- window_size=1,
- sleep_limit=1,
- sleep_msec=1,
- reject_limit=1000,
- concurrent_requests=1000,
- ),
- )
- server.register_servlets(
- homeserver, self.resource, Authenticator(), ratelimiter
- )
-
def test_complexity_simple(self):
u1 = self.register_user("u1", "pass")
@@ -88,3 +69,71 @@ class RoomComplexityTests(unittest.HomeserverTestCase):
self.assertEquals(200, channel.code)
complexity = channel.json_body["v1"]
self.assertEqual(complexity, 1.23)
+
+ def test_join_too_large(self):
+
+ u1 = self.register_user("u1", "pass")
+
+ handler = self.hs.get_room_member_handler()
+ fed_transport = self.hs.get_federation_transport_client()
+
+ # Mock out some things, because we don't want to test the whole join
+ fed_transport.client.get_json = Mock(return_value=defer.succeed({"v1": 9999}))
+ handler.federation_handler.do_invite_join = Mock(return_value=defer.succeed(1))
+
+ d = handler._remote_join(
+ None,
+ ["other.example.com"],
+ "roomid",
+ UserID.from_string(u1),
+ {"membership": "join"},
+ )
+
+ self.pump()
+
+ # The request failed with a SynapseError saying the resource limit was
+ # exceeded.
+ f = self.get_failure(d, SynapseError)
+ self.assertEqual(f.value.code, 400, f.value)
+ self.assertEqual(f.value.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)
+
+ def test_join_too_large_once_joined(self):
+
+ u1 = self.register_user("u1", "pass")
+ u1_token = self.login("u1", "pass")
+
+ # Ok, this might seem a bit weird -- I want to test that we actually
+ # leave the room, but I don't want to simulate two servers. So, we make
+ # a local room, which we say we're joining remotely, even if there's no
+ # remote, because we mock that out. Then, we'll leave the (actually
+ # local) room, which will be propagated over federation in a real
+ # scenario.
+ room_1 = self.helper.create_room_as(u1, tok=u1_token)
+
+ handler = self.hs.get_room_member_handler()
+ fed_transport = self.hs.get_federation_transport_client()
+
+ # Mock out some things, because we don't want to test the whole join
+ fed_transport.client.get_json = Mock(return_value=defer.succeed(None))
+ handler.federation_handler.do_invite_join = Mock(return_value=defer.succeed(1))
+
+ # Artificially raise the complexity
+ self.hs.get_datastore().get_current_state_event_counts = lambda x: defer.succeed(
+ 600
+ )
+
+ d = handler._remote_join(
+ None,
+ ["other.example.com"],
+ room_1,
+ UserID.from_string(u1),
+ {"membership": "join"},
+ )
+
+ self.pump()
+
+ # The request failed with a SynapseError saying the resource limit was
+ # exceeded.
+ f = self.get_failure(d, SynapseError)
+ self.assertEqual(f.value.code, 400)
+ self.assertEqual(f.value.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)
diff --git a/tests/federation/test_federation_sender.py b/tests/federation/test_federation_sender.py
index 7bb106b5f7..d456267b87 100644
--- a/tests/federation/test_federation_sender.py
+++ b/tests/federation/test_federation_sender.py
@@ -19,7 +19,7 @@ from twisted.internet import defer
from synapse.types import ReadReceipt
-from tests.unittest import HomeserverTestCase
+from tests.unittest import HomeserverTestCase, override_config
class FederationSenderTestCases(HomeserverTestCase):
@@ -29,6 +29,7 @@ class FederationSenderTestCases(HomeserverTestCase):
federation_transport_client=Mock(spec=["send_transaction"]),
)
+ @override_config({"send_federation": True})
def test_send_receipts(self):
mock_state_handler = self.hs.get_state_handler()
mock_state_handler.get_current_hosts_in_room.return_value = ["test", "host2"]
@@ -51,16 +52,16 @@ class FederationSenderTestCases(HomeserverTestCase):
json_cb = mock_send_transaction.call_args[0][1]
data = json_cb()
self.assertEqual(
- data['edus'],
+ data["edus"],
[
{
- 'edu_type': 'm.receipt',
- 'content': {
- 'room_id': {
- 'm.read': {
- 'user_id': {
- 'event_ids': ['event_id'],
- 'data': {'ts': 1234},
+ "edu_type": "m.receipt",
+ "content": {
+ "room_id": {
+ "m.read": {
+ "user_id": {
+ "event_ids": ["event_id"],
+ "data": {"ts": 1234},
}
}
}
@@ -69,6 +70,7 @@ class FederationSenderTestCases(HomeserverTestCase):
],
)
+ @override_config({"send_federation": True})
def test_send_receipts_with_backoff(self):
"""Send two receipts in quick succession; the second should be flushed, but
only after 20ms"""
@@ -93,16 +95,16 @@ class FederationSenderTestCases(HomeserverTestCase):
json_cb = mock_send_transaction.call_args[0][1]
data = json_cb()
self.assertEqual(
- data['edus'],
+ data["edus"],
[
{
- 'edu_type': 'm.receipt',
- 'content': {
- 'room_id': {
- 'm.read': {
- 'user_id': {
- 'event_ids': ['event_id'],
- 'data': {'ts': 1234},
+ "edu_type": "m.receipt",
+ "content": {
+ "room_id": {
+ "m.read": {
+ "user_id": {
+ "event_ids": ["event_id"],
+ "data": {"ts": 1234},
}
}
}
@@ -128,16 +130,16 @@ class FederationSenderTestCases(HomeserverTestCase):
json_cb = mock_send_transaction.call_args[0][1]
data = json_cb()
self.assertEqual(
- data['edus'],
+ data["edus"],
[
{
- 'edu_type': 'm.receipt',
- 'content': {
- 'room_id': {
- 'm.read': {
- 'user_id': {
- 'event_ids': ['other_id'],
- 'data': {'ts': 1234},
+ "edu_type": "m.receipt",
+ "content": {
+ "room_id": {
+ "m.read": {
+ "user_id": {
+ "event_ids": ["other_id"],
+ "data": {"ts": 1234},
}
}
}
diff --git a/tests/federation/test_federation_server.py b/tests/federation/test_federation_server.py
index af15f4cc5a..296dc887be 100644
--- a/tests/federation/test_federation_server.py
+++ b/tests/federation/test_federation_server.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2018 New Vector Ltd
+# Copyright 2019 Matrix.org Federation C.I.C
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -14,13 +15,14 @@
# limitations under the License.
import logging
-from synapse.events import FrozenEvent
+from synapse.events import make_event_from_dict
from synapse.federation.federation_server import server_matches_acl_event
+from synapse.rest import admin
+from synapse.rest.client.v1 import login, room
from tests import unittest
-@unittest.DEBUG
class ServerACLsTestCase(unittest.TestCase):
def test_blacklisted_server(self):
e = _create_acl_event({"allow": ["*"], "deny": ["evil.com"]})
@@ -42,8 +44,68 @@ class ServerACLsTestCase(unittest.TestCase):
self.assertTrue(server_matches_acl_event("1:2:3:4", e))
+class StateQueryTests(unittest.FederatingHomeserverTestCase):
+
+ servlets = [
+ admin.register_servlets,
+ room.register_servlets,
+ login.register_servlets,
+ ]
+
+ def test_without_event_id(self):
+ """
+ Querying v1/state/<room_id> without an event ID will return the current
+ known state.
+ """
+ u1 = self.register_user("u1", "pass")
+ u1_token = self.login("u1", "pass")
+
+ room_1 = self.helper.create_room_as(u1, tok=u1_token)
+ self.inject_room_member(room_1, "@user:other.example.com", "join")
+
+ request, channel = self.make_request(
+ "GET", "/_matrix/federation/v1/state/%s" % (room_1,)
+ )
+ self.render(request)
+ self.assertEquals(200, channel.code, channel.result)
+
+ self.assertEqual(
+ channel.json_body["room_version"],
+ self.hs.config.default_room_version.identifier,
+ )
+
+ members = set(
+ map(
+ lambda x: x["state_key"],
+ filter(
+ lambda x: x["type"] == "m.room.member", channel.json_body["pdus"]
+ ),
+ )
+ )
+
+ self.assertEqual(members, {"@user:other.example.com", u1})
+ self.assertEqual(len(channel.json_body["pdus"]), 6)
+
+ def test_needs_to_be_in_room(self):
+ """
+ Querying v1/state/<room_id> requires the server
+ be in the room to provide data.
+ """
+ u1 = self.register_user("u1", "pass")
+ u1_token = self.login("u1", "pass")
+
+ room_1 = self.helper.create_room_as(u1, tok=u1_token)
+
+ request, channel = self.make_request(
+ "GET", "/_matrix/federation/v1/state/%s" % (room_1,)
+ )
+ self.render(request)
+ self.assertEquals(403, channel.code, channel.result)
+ self.assertEqual(channel.json_body["errcode"], "M_FORBIDDEN")
+
+
def _create_acl_event(content):
- return FrozenEvent(
+ return make_event_from_dict(
{
"room_id": "!a:b",
"event_id": "$a:b",
diff --git a/tests/federation/transport/test_server.py b/tests/federation/transport/test_server.py
new file mode 100644
index 0000000000..27d83bb7d9
--- /dev/null
+++ b/tests/federation/transport/test_server.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+# Copyright 2019 The Matrix.org Foundation C.I.C.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# 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 twisted.internet import defer
+
+from synapse.config.ratelimiting import FederationRateLimitConfig
+from synapse.federation.transport import server
+from synapse.util.ratelimitutils import FederationRateLimiter
+
+from tests import unittest
+from tests.unittest import override_config
+
+
+class RoomDirectoryFederationTests(unittest.HomeserverTestCase):
+ def prepare(self, reactor, clock, homeserver):
+ class Authenticator(object):
+ def authenticate_request(self, request, content):
+ return defer.succeed("otherserver.nottld")
+
+ ratelimiter = FederationRateLimiter(clock, FederationRateLimitConfig())
+ server.register_servlets(
+ homeserver, self.resource, Authenticator(), ratelimiter
+ )
+
+ @override_config({"allow_public_rooms_over_federation": False})
+ def test_blocked_public_room_list_over_federation(self):
+ request, channel = self.make_request(
+ "GET", "/_matrix/federation/v1/publicRooms"
+ )
+ self.render(request)
+ self.assertEquals(403, channel.code)
+
+ @override_config({"allow_public_rooms_over_federation": True})
+ def test_open_public_room_list_over_federation(self):
+ request, channel = self.make_request(
+ "GET", "/_matrix/federation/v1/publicRooms"
+ )
+ self.render(request)
+ self.assertEquals(200, channel.code)
|