Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 0bfd099

Browse files
committed
Squashed commit of the following:
commit c2ca163 Author: Amber H. Brown <[email protected]> Date: Fri Jul 26 22:48:20 2019 +1000 don't block commit 8d9a56e Merge: b50d8a9 4a5fb54 Author: Amber H. Brown <[email protected]> Date: Fri Jul 26 21:35:42 2019 +1000 Merge branch 'shhs' of ssh://github.com/matrix-org/synapse into shhs commit 4a5fb54 Merge: 95a0386 992333b Author: Amber Brown <[email protected]> Date: Fri Jul 26 20:59:41 2019 +1000 Merge tag 'v1.2.1' into shhs Synapse 1.2.1 (2019-07-26) ========================== Security update --------------- This release includes *four* security fixes: - Prevent an attack where a federated server could send redactions for arbitrary events in v1 and v2 rooms. ([\#5767](#5767)) - Prevent a denial-of-service attack where cycles of redaction events would make Synapse spin infinitely. Thanks to `@lrizika:matrix.org` for identifying and responsibly disclosing this issue. ([0f2ecb9](0f2ecb961)) - Prevent an attack where users could be joined or parted from public rooms without their consent. Thanks to @dylanger for identifying and responsibly disclosing this issue. ([\#5744](#5744)) - Fix a vulnerability where a federated server could spoof read-receipts from users on other servers. Thanks to @dylanger for identifying this issue too. ([\#5743](#5743)) Additionally, the following fix was in Synapse **1.2.0**, but was not correctly identified during the original release: - It was possible for a room moderator to send a redaction for an `m.room.create` event, which would downgrade the room to version 1. Thanks to `/dev/ponies` for identifying and responsibly disclosing this issue! ([\#5701](#5701)) commit 95a0386 Author: Amber Brown <[email protected]> Date: Fri Jul 26 20:27:31 2019 +1000 don't have a circleci config commit b50d8a9 Author: Amber H. Brown <[email protected]> Date: Fri Jul 26 02:26:23 2019 +1000 fix merging forward commit 3edf6e9 Author: Amber H. Brown <[email protected]> Date: Fri Jul 26 02:07:05 2019 +1000 fix this commit f61cdc1 Merge: 43cf234 c0a1301 Author: Amber H. Brown <[email protected]> Date: Fri Jul 26 01:48:50 2019 +1000 Merge tag 'v1.2.0' into shhs No changes since v1.2.0rc2. commit 43cf234 Author: Amber H. Brown <[email protected]> Date: Fri Jul 26 01:48:20 2019 +1000 dockerfile update commit b7962f5 Author: Amber H. Brown <[email protected]> Date: Thu Jul 18 23:23:12 2019 +1000 add a wait commit 9bbf2d2 Author: Amber H. Brown <[email protected]> Date: Wed Jul 17 04:46:20 2019 +1000 fix commit 5daee2e Author: Amber H. Brown <[email protected]> Date: Wed Jul 17 04:41:00 2019 +1000 fix commit 14c8b03 Author: Amber H. Brown <[email protected]> Date: Wed Jul 17 04:36:27 2019 +1000 fix commit 7fcd6c1 Author: Amber H. Brown <[email protected]> Date: Wed Jul 17 04:32:50 2019 +1000 fix commit c43c1ad Author: Amber H. Brown <[email protected]> Date: Wed Jul 17 04:28:11 2019 +1000 fix commit a025abe Author: Amber H. Brown <[email protected]> Date: Wed Jul 17 04:02:15 2019 +1000 try now commit c1777f5 Author: Amber H. Brown <[email protected]> Date: Wed Jul 17 04:00:34 2019 +1000 try now commit 646292c Author: Amber H. Brown <[email protected]> Date: Wed Jul 17 03:58:34 2019 +1000 see if we can do a build! commit a175e60 Merge: 9b3a63e 0e54342 Author: Amber H. Brown <[email protected]> Date: Fri Jul 5 23:49:13 2019 +1000 Merge remote-tracking branch 'origin/develop' into shhs commit 9b3a63e Author: Amber H. Brown <[email protected]> Date: Fri Jul 5 23:36:41 2019 +1000 linting commit 3d89feb Author: Amber H. Brown <[email protected]> Date: Fri Jul 5 23:34:24 2019 +1000 linting commit 400bc06 Author: Amber H. Brown <[email protected]> Date: Fri Jul 5 22:44:22 2019 +1000 linting commit a1de642 Merge: f4343c7 54283f3 Author: Amber H. Brown <[email protected]> Date: Fri Jul 5 19:46:11 2019 +1000 Merge tag 'v1.1.0' into shhs Synapse 1.1.0 (2019-07-04) ========================== As of v1.1.0, Synapse no longer supports Python 2, nor Postgres version 9.4. See the [upgrade notes](UPGRADE.rst#upgrading-to-v110) for more details. This release also deprecates the use of environment variables to configure the docker image. See the [docker README](https://github.com/matrix-org/synapse/blob/release-v1.1.0/docker/README.md#legacy-dynamic-configuration-file-support) for more details. No changes since 1.1.0rc2. Synapse 1.1.0rc2 (2019-07-03) ============================= Bugfixes -------- - Fix regression in 1.1rc1 where OPTIONS requests to the media repo would fail. ([\#5593](#5593)) - Removed the `SYNAPSE_SMTP_*` docker container environment variables. Using these environment variables prevented the docker container from starting in Synapse v1.0, even though they didn't actually allow any functionality anyway. ([\#5596](#5596)) - Fix a number of "Starting txn from sentinel context" warnings. ([\#5605](#5605)) Internal Changes ---------------- - Update github templates. ([\#5552](#5552)) Synapse 1.1.0rc1 (2019-07-02) ============================= As of v1.1.0, Synapse no longer supports Python 2, nor Postgres version 9.4. See the [upgrade notes](UPGRADE.rst#upgrading-to-v110) for more details. Features -------- - Added possibilty to disable local password authentication. Contributed by Daniel Hoffend. ([\#5092](#5092)) - Add monthly active users to phonehome stats. ([\#5252](#5252)) - Allow expired user to trigger renewal email sending manually. ([\#5363](#5363)) - Statistics on forward extremities per room are now exposed via Prometheus. ([\#5384](#5384), [\#5458](#5458), [\#5461](#5461)) - Add --no-daemonize option to run synapse in the foreground, per issue #4130. Contributed by Soham Gumaste. ([\#5412](#5412), [\#5587](#5587)) - Fully support SAML2 authentication. Contributed by [Alexander Trost](https://github.com/galexrt) - thank you! ([\#5422](#5422)) - Allow server admins to define implementations of extra rules for allowing or denying incoming events. ([\#5440](#5440), [\#5474](#5474), [\#5477](#5477)) - Add support for handling pagination APIs on client reader worker. ([\#5505](#5505), [\#5513](#5513), [\#5531](#5531)) - Improve help and cmdline option names for --generate-config options. ([\#5512](#5512)) - Allow configuration of the path used for ACME account keys. ([\#5516](#5516), [\#5521](#5521), [\#5522](#5522)) - Add --data-dir and --open-private-ports options. ([\#5524](#5524)) - Split public rooms directory auth config in two settings, in order to manage client auth independently from the federation part of it. Obsoletes the "restrict_public_rooms_to_local_users" configuration setting. If "restrict_public_rooms_to_local_users" is set in the config, Synapse will act as if both new options are enabled, i.e. require authentication through the client API and deny federation requests. ([\#5534](#5534)) - The minimum TLS version used for outgoing federation requests can now be set with `federation_client_minimum_tls_version`. ([\#5550](#5550)) - Optimise devices changed query to not pull unnecessary rows from the database, reducing database load. ([\#5559](#5559)) - Add new metrics for number of forward extremities being persisted and number of state groups involved in resolution. ([\#5476](#5476)) Bugfixes -------- - Fix bug processing incoming events over federation if call to `/get_missing_events` fails. ([\#5042](#5042)) - Prevent more than one room upgrade happening simultaneously on the same room. ([\#5051](#5051)) - Fix a bug where running synapse_port_db would cause the account validity feature to fail because it didn't set the type of the email_sent column to boolean. ([\#5325](#5325)) - Warn about disabling email-based password resets when a reset occurs, and remove warning when someone attempts a phone-based reset. ([\#5387](#5387)) - Fix email notifications for unnamed rooms with multiple people. ([\#5388](#5388)) - Fix exceptions in federation reader worker caused by attempting to renew attestations, which should only happen on master worker. ([\#5389](#5389)) - Fix handling of failures fetching remote content to not log failures as exceptions. ([\#5390](#5390)) - Fix a bug where deactivated users could receive renewal emails if the account validity feature is on. ([\#5394](#5394)) - Fix missing invite state after exchanging 3PID invites over federaton. ([\#5464](#5464)) - Fix intermittent exceptions on Apple hardware. Also fix bug that caused database activity times to be under-reported in log lines. ([\#5498](#5498)) - Fix logging error when a tampered event is detected. ([\#5500](#5500)) - Fix bug where clients could tight loop calling `/sync` for a period. ([\#5507](#5507)) - Fix bug with `jinja2` preventing Synapse from starting. Users who had this problem should now simply need to run `pip install matrix-synapse`. ([\#5514](#5514)) - Fix a regression where homeservers on private IP addresses were incorrectly blacklisted. ([\#5523](#5523)) - Fixed m.login.jwt using unregistred user_id and added pyjwt>=1.6.4 as jwt conditional dependencies. Contributed by Pau Rodriguez-Estivill. ([\#5555](#5555), [\#5586](#5586)) - Fix a bug that would cause invited users to receive several emails for a single 3PID invite in case the inviter is rate limited. ([\#5576](#5576)) Updates to the Docker image --------------------------- - Add ability to change Docker containers [timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) with the `TZ` variable. ([\#5383](#5383)) - Update docker image to use Python 3.7. ([\#5546](#5546)) - Deprecate the use of environment variables for configuration, and make the use of a static configuration the default. ([\#5561](#5561), [\#5562](#5562), [\#5566](#5566), [\#5567](#5567)) - Increase default log level for docker image to INFO. It can still be changed by editing the generated log.config file. ([\#5547](#5547)) - Send synapse logs to the docker logging system, by default. ([\#5565](#5565)) - Open the non-TLS port by default. ([\#5568](#5568)) - Fix failure to start under docker with SAML support enabled. ([\#5490](#5490)) - Use a sensible location for data files when generating a config file. ([\#5563](#5563)) Deprecations and Removals ------------------------- - Python 2.7 is no longer a supported platform. Synapse now requires Python 3.5+ to run. ([\#5425](#5425)) - PostgreSQL 9.4 is no longer supported. Synapse requires Postgres 9.5+ or above for Postgres support. ([\#5448](#5448)) - Remove support for cpu_affinity setting. ([\#5525](#5525)) Improved Documentation ---------------------- - Improve README section on performance troubleshooting. ([\#4276](#4276)) - Add information about how to install and run `black` on the codebase to code_style.rst. ([\#5537](#5537)) - Improve install docs on choosing server_name. ([\#5558](#5558)) Internal Changes ---------------- - Add logging to 3pid invite signature verification. ([\#5015](#5015)) - Update example haproxy config to a more compatible setup. ([\#5313](#5313)) - Track deactivated accounts in the database. ([\#5378](#5378), [\#5465](#5465), [\#5493](#5493)) - Clean up code for sending federation EDUs. ([\#5381](#5381)) - Add a sponsor button to the repo. ([\#5382](#5382), [\#5386](#5386)) - Don't log non-200 responses from federation queries as exceptions. ([\#5383](#5383)) - Update Python syntax in contrib/ to Python 3. ([\#5446](#5446)) - Update federation_client dev script to support `.well-known` and work with python3. ([\#5447](#5447)) - SyTest has been moved to Buildkite. ([\#5459](#5459)) - Demo script now uses python3. ([\#5460](#5460)) - Synapse can now handle RestServlets that return coroutines. ([\#5475](#5475), [\#5585](#5585)) - The demo servers talk to each other again. ([\#5478](#5478)) - Add an EXPERIMENTAL config option to try and periodically clean up extremities by sending dummy events. ([\#5480](#5480)) - Synapse's codebase is now formatted by `black`. ([\#5482](#5482)) - Some cleanups and sanity-checking in the CPU and database metrics. ([\#5499](#5499)) - Improve email notification logging. ([\#5502](#5502)) - Fix "Unexpected entry in 'full_schemas'" log warning. ([\#5509](#5509)) - Improve logging when generating config files. ([\#5510](#5510)) - Refactor and clean up Config parser for maintainability. ([\#5511](#5511)) - Make the config clearer in that email.template_dir is relative to the Synapse's root directory, not the `synapse/` folder within it. ([\#5543](#5543)) - Update v1.0.0 release changelog to include more information about changes to password resets. ([\#5545](#5545)) - Remove non-functioning check_event_hash.py dev script. ([\#5548](#5548)) - Synapse will now only allow TLS v1.2 connections when serving federation, if it terminates TLS. As Synapse's allowed ciphers were only able to be used in TLSv1.2 before, this does not change behaviour. ([\#5550](#5550)) - Logging when running GC collection on generation 0 is now at the DEBUG level, not INFO. ([\#5557](#5557)) - Reduce the amount of stuff we send in the docker context. ([\#5564](#5564)) - Point the reverse links in the Purge History contrib scripts at the intended location. ([\#5570](#5570)) commit f4343c7 Merge: 4689408 463d5a8 Author: Amber H. Brown <[email protected]> Date: Wed Jul 3 22:39:30 2019 +1000 Merge remote-tracking branch 'origin/develop' into shhs commit 4689408 Merge: bed45ab b491468 Author: Amber H. Brown <[email protected]> Date: Tue Jul 2 18:31:29 2019 +1000 Merge remote-tracking branch 'origin/develop' into shhs commit bed45ab Author: Amber H. Brown <[email protected]> Date: Tue Jul 2 18:18:09 2019 +1000 release shhs on tags commit 0993b05 Author: Amber H. Brown <[email protected]> Date: Mon Jul 1 23:13:21 2019 +1000 improve error text when room is too large commit e001115 Author: Amber H. Brown <[email protected]> Date: Tue Jun 18 21:24:56 2019 +1000 fix commit e60aab1 Merge: e7c1171 82d9d52 Author: Amber H. Brown <[email protected]> Date: Tue Jun 18 21:20:13 2019 +1000 Merge remote-tracking branch 'origin/develop' into shhs commit e7c1171 Merge: 8fe26db c831748 Author: Amber Brown <[email protected]> Date: Tue Jun 4 20:41:59 2019 +1000 Merge remote-tracking branch 'origin/master' into shhs commit 8fe26db Merge: c99c105 4a30e4a Author: Amber Brown <[email protected]> Date: Tue May 21 14:30:47 2019 -0500 Merge remote-tracking branch 'origin/develop' into HEAD commit c99c105 Author: Amber Brown <[email protected]> Date: Mon May 20 17:01:50 2019 -0500 SHHS - Room Join Complexity (#5072) commit d142e51 Merge: d424ba9 24b93b9 Author: Amber Brown <[email protected]> Date: Mon May 20 15:43:08 2019 -0500 Merge remote-tracking branch 'origin/develop' into shhs commit d424ba9 Merge: a1b8767 f1e5b41 Author: Amber Brown <[email protected]> Date: Wed May 15 23:30:22 2019 -0500 Merge remote-tracking branch 'origin/develop' into shhs commit a1b8767 Merge: faee1e9 df2ebd7 Author: Amber Brown <[email protected]> Date: Mon May 13 15:01:58 2019 -0500 Merge remote-tracking branch 'origin/develop' into shhs commit faee1e9 Merge: 12875f9 d216a36 Author: Amber Brown <[email protected]> Date: Wed May 8 16:29:45 2019 -0500 Merge remote-tracking branch 'origin/develop' into shhs commit 12875f9 Merge: ed38141 c1799b0 Author: Amber Brown <[email protected]> Date: Wed May 1 10:55:14 2019 -0400 Merge remote-tracking branch 'origin/develop' into shhs commit ed38141 Author: Amber Brown <[email protected]> Date: Mon Apr 29 20:57:42 2019 +1000 target better for the shhs release docker hub, pt 3 commit bd5f624 Author: Amber Brown <[email protected]> Date: Mon Apr 29 20:43:17 2019 +1000 target better for the shhs release docker hub, pt 2 commit c0f57ca Author: Amber Brown <[email protected]> Date: Mon Apr 29 20:36:35 2019 +1000 target better for the shhs release docker hub commit 1d5cf66 Author: Amber Brown <[email protected]> Date: Mon Apr 29 20:33:36 2019 +1000 no media repo == no path checks commit 25256f9 Author: Amber Brown <[email protected]> Date: Mon Apr 29 20:30:55 2019 +1000 release shhs as a release commit a32aa2c Author: Amber Brown <[email protected]> Date: Mon Apr 29 20:28:40 2019 +1000 patch up docker commit cbc866a Author: Amber Brown <[email protected]> Date: Fri Apr 26 01:40:01 2019 +1000 Remove Python 2 from the SHHS branch CI (#5099)
1 parent fa87004 commit 0bfd099

File tree

6 files changed

+212
-5
lines changed

6 files changed

+212
-5
lines changed

changelog.d/5072.feature

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Synapse can now be configured to not join remote rooms of a given "complexity" (currently, state events). This option can be used to prevent adverse performance on resource-constrained homeservers.

docs/sample_config.yaml

+11
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,17 @@ listeners:
278278
# Used by phonehome stats to group together related servers.
279279
#server_context: context
280280

281+
# Resource-constrained Homeserver Settings
282+
#
283+
# If limit_large_remote_room_joins is True, the room complexity will be
284+
# checked before a user joins a new remote room. If it is above
285+
# limit_large_remote_room_complexity, it will disallow joining or
286+
# instantly leave.
287+
#
288+
# Uncomment the below lines to enable:
289+
#limit_large_remote_room_joins: True
290+
#limit_large_remote_room_complexity: 1.0
291+
281292
# Whether to require a user to be in the room to add an alias to it.
282293
# Defaults to 'true'.
283294
#

synapse/config/server.py

+17
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,12 @@ def read_config(self, config, **kwargs):
247247

248248
self.gc_thresholds = read_gc_thresholds(config.get("gc_thresholds", None))
249249

250+
# Resource-constrained Homeserver Configuration
251+
self.limit_large_room_joins = config.get("limit_large_remote_room_joins", False)
252+
self.limit_large_room_complexity = config.get(
253+
"limit_large_remote_room_complexity", 1.0
254+
)
255+
250256
bind_port = config.get("bind_port")
251257
if bind_port:
252258
if config.get("no_tls", False):
@@ -617,6 +623,17 @@ def generate_config_section(
617623
# Used by phonehome stats to group together related servers.
618624
#server_context: context
619625
626+
# Resource-constrained Homeserver Settings
627+
#
628+
# If limit_large_remote_room_joins is True, the room complexity will be
629+
# checked before a user joins a new remote room. If it is above
630+
# limit_large_remote_room_complexity, it will disallow joining or
631+
# instantly leave.
632+
#
633+
# Uncomment the below lines to enable:
634+
#limit_large_remote_room_joins: True
635+
#limit_large_remote_room_complexity: 1.0
636+
620637
# Whether to require a user to be in the room to add an alias to it.
621638
# Defaults to 'true'.
622639
#

synapse/handlers/federation.py

+25
Original file line numberDiff line numberDiff line change
@@ -2796,3 +2796,28 @@ def user_joined_room(self, user, room_id):
27962796
)
27972797
else:
27982798
return user_joined_room(self.distributor, user, room_id)
2799+
2800+
@defer.inlineCallbacks
2801+
def get_room_complexity(self, remote_room_hosts, room_id):
2802+
"""
2803+
Fetch the complexity of a remote room over federation.
2804+
2805+
Args:
2806+
remote_room_hosts (list[str]): The remote servers to ask.
2807+
room_id (str): The room ID to ask about.
2808+
2809+
Returns:
2810+
Deferred[dict] or Deferred[None]: Dict contains the complexity
2811+
metric versions, while None means we could not fetch the complexity.
2812+
"""
2813+
2814+
for host in remote_room_hosts:
2815+
res = yield self.federation_client.get_room_complexity(host, room_id)
2816+
2817+
# We got a result, return it.
2818+
if res:
2819+
defer.returnValue(res)
2820+
2821+
# We fell off the bottom, couldn't get the complexity from anyone. Oh
2822+
# well.
2823+
defer.returnValue(None)

synapse/handlers/room_member.py

+85-4
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626

2727
from twisted.internet import defer
2828

29-
import synapse.server
30-
import synapse.types
29+
from synapse import types
3130
from synapse.api.constants import EventTypes, Membership
3231
from synapse.api.errors import AuthError, Codes, HttpResponseException, SynapseError
3332
from synapse.types import RoomID, UserID
@@ -39,6 +38,11 @@
3938
logger = logging.getLogger(__name__)
4039

4140
id_server_scheme = "https://"
41+
ROOM_COMPLEXITY_TOO_GREAT = (
42+
"Your homeserver is unable to join rooms this large or complex. "
43+
"Please speak to your server administrator, or upgrade your instance "
44+
"to join this room."
45+
)
4246

4347

4448
class RoomMemberHandler(object):
@@ -543,7 +547,7 @@ def send_membership_event(
543547
), "Sender (%s) must be same as requester (%s)" % (sender, requester.user)
544548
assert self.hs.is_mine(sender), "Sender must be our own: %s" % (sender,)
545549
else:
546-
requester = synapse.types.create_requester(target_user)
550+
requester = types.create_requester(target_user)
547551

548552
prev_event = yield self.event_creation_handler.deduplicate_state_event(
549553
event, context
@@ -945,21 +949,73 @@ def __init__(self, hs):
945949
self.distributor.declare("user_joined_room")
946950
self.distributor.declare("user_left_room")
947951

952+
@defer.inlineCallbacks
953+
def _is_remote_room_too_complex(self, room_id, remote_room_hosts):
954+
"""
955+
Check if complexity of a remote room is too great.
956+
957+
Args:
958+
room_id (str)
959+
remote_room_hosts (list[str])
960+
961+
Returns: bool of whether the complexity is too great, or None
962+
if unable to be fetched
963+
"""
964+
max_complexity = self.hs.config.limit_large_room_complexity
965+
complexity = yield self.federation_handler.get_room_complexity(
966+
remote_room_hosts, room_id
967+
)
968+
969+
if complexity:
970+
if complexity["v1"] > max_complexity:
971+
return True
972+
return False
973+
return None
974+
975+
@defer.inlineCallbacks
976+
def _is_local_room_too_complex(self, room_id):
977+
"""
978+
Check if the complexity of a local room is too great.
979+
980+
Args:
981+
room_id (str)
982+
983+
Returns: bool
984+
"""
985+
max_complexity = self.hs.config.limit_large_room_complexity
986+
complexity = yield self.store.get_room_complexity(room_id)
987+
988+
if complexity["v1"] > max_complexity:
989+
return True
990+
991+
return False
992+
948993
@defer.inlineCallbacks
949994
def _remote_join(self, requester, remote_room_hosts, room_id, user, content):
950995
"""Implements RoomMemberHandler._remote_join
951996
"""
952997
# filter ourselves out of remote_room_hosts: do_invite_join ignores it
953998
# and if it is the only entry we'd like to return a 404 rather than a
954999
# 500.
955-
9561000
remote_room_hosts = [
9571001
host for host in remote_room_hosts if host != self.hs.hostname
9581002
]
9591003

9601004
if len(remote_room_hosts) == 0:
9611005
raise SynapseError(404, "No known servers")
9621006

1007+
if self.hs.config.limit_large_room_joins:
1008+
# Fetch the room complexity
1009+
too_complex = yield self._is_remote_room_too_complex(
1010+
room_id, remote_room_hosts
1011+
)
1012+
if too_complex is True:
1013+
raise SynapseError(
1014+
code=400,
1015+
msg=ROOM_COMPLEXITY_TOO_GREAT,
1016+
errcode=Codes.RESOURCE_LIMIT_EXCEEDED,
1017+
)
1018+
9631019
# We don't do an auth check if we are doing an invite
9641020
# join dance for now, since we're kinda implicitly checking
9651021
# that we are allowed to join when we decide whether or not we
@@ -969,6 +1025,31 @@ def _remote_join(self, requester, remote_room_hosts, room_id, user, content):
9691025
)
9701026
yield self._user_joined_room(user, room_id)
9711027

1028+
# Check the room we just joined wasn't too large, if we didn't fetch the
1029+
# complexity of it before.
1030+
if self.hs.config.limit_large_room_joins:
1031+
if too_complex is False:
1032+
# We checked, and we're under the limit.
1033+
return
1034+
1035+
# Check again, but with the local state events
1036+
too_complex = yield self._is_local_room_too_complex(room_id)
1037+
1038+
if too_complex is False:
1039+
# We're under the limit.
1040+
return
1041+
1042+
# The room is too large. Leave.
1043+
requester = types.create_requester(user, None, False, None)
1044+
yield self.update_membership(
1045+
requester=requester, target=user, room_id=room_id, action="leave"
1046+
)
1047+
raise SynapseError(
1048+
code=400,
1049+
msg=ROOM_COMPLEXITY_TOO_GREAT,
1050+
errcode=Codes.RESOURCE_LIMIT_EXCEEDED,
1051+
)
1052+
9721053
@defer.inlineCallbacks
9731054
def _remote_reject_invite(self, requester, remote_room_hosts, room_id, target):
9741055
"""Implements RoomMemberHandler._remote_reject_invite

tests/federation/test_complexity.py

+73-1
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,16 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16+
from mock import Mock
17+
1618
from twisted.internet import defer
1719

20+
from synapse.api.errors import Codes, SynapseError
1821
from synapse.config.ratelimiting import FederationRateLimitConfig
1922
from synapse.federation.transport import server
2023
from synapse.rest import admin
2124
from synapse.rest.client.v1 import login, room
25+
from synapse.types import UserID
2226
from synapse.util.ratelimitutils import FederationRateLimiter
2327

2428
from tests import unittest
@@ -33,7 +37,7 @@ class RoomComplexityTests(unittest.HomeserverTestCase):
3337
]
3438

3539
def default_config(self, name="test"):
36-
config = super(RoomComplexityTests, self).default_config(name=name)
40+
config = super().default_config(name=name)
3741
config["limit_large_remote_room_joins"] = True
3842
config["limit_large_remote_room_complexity"] = 0.05
3943
return config
@@ -88,3 +92,71 @@ def test_complexity_simple(self):
8892
self.assertEquals(200, channel.code)
8993
complexity = channel.json_body["v1"]
9094
self.assertEqual(complexity, 1.23)
95+
96+
def test_join_too_large(self):
97+
98+
u1 = self.register_user("u1", "pass")
99+
100+
handler = self.hs.get_room_member_handler()
101+
fed_transport = self.hs.get_federation_transport_client()
102+
103+
# Mock out some things, because we don't want to test the whole join
104+
fed_transport.client.get_json = Mock(return_value=defer.succeed({"v1": 9999}))
105+
handler.federation_handler.do_invite_join = Mock(return_value=defer.succeed(1))
106+
107+
d = handler._remote_join(
108+
None,
109+
["otherserver.example"],
110+
"roomid",
111+
UserID.from_string(u1),
112+
{"membership": "join"},
113+
)
114+
115+
self.pump()
116+
117+
# The request failed with a SynapseError saying the resource limit was
118+
# exceeded.
119+
f = self.get_failure(d, SynapseError)
120+
self.assertEqual(f.value.code, 400, f.value)
121+
self.assertEqual(f.value.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)
122+
123+
def test_join_too_large_once_joined(self):
124+
125+
u1 = self.register_user("u1", "pass")
126+
u1_token = self.login("u1", "pass")
127+
128+
# Ok, this might seem a bit weird -- I want to test that we actually
129+
# leave the room, but I don't want to simulate two servers. So, we make
130+
# a local room, which we say we're joining remotely, even if there's no
131+
# remote, because we mock that out. Then, we'll leave the (actually
132+
# local) room, which will be propagated over federation in a real
133+
# scenario.
134+
room_1 = self.helper.create_room_as(u1, tok=u1_token)
135+
136+
handler = self.hs.get_room_member_handler()
137+
fed_transport = self.hs.get_federation_transport_client()
138+
139+
# Mock out some things, because we don't want to test the whole join
140+
fed_transport.client.get_json = Mock(return_value=defer.succeed(None))
141+
handler.federation_handler.do_invite_join = Mock(return_value=defer.succeed(1))
142+
143+
# Artificially raise the complexity
144+
self.hs.get_datastore().get_current_state_event_counts = lambda x: defer.succeed(
145+
600
146+
)
147+
148+
d = handler._remote_join(
149+
None,
150+
["otherserver.example"],
151+
room_1,
152+
UserID.from_string(u1),
153+
{"membership": "join"},
154+
)
155+
156+
self.pump()
157+
158+
# The request failed with a SynapseError saying the resource limit was
159+
# exceeded.
160+
f = self.get_failure(d, SynapseError)
161+
self.assertEqual(f.value.code, 400)
162+
self.assertEqual(f.value.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)

0 commit comments

Comments
 (0)