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

Add a ratelimiter for 3pid invite #11892

Merged
merged 8 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/11892.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use a dedicated configurable rate limiter for 3PID invites.
7 changes: 7 additions & 0 deletions docs/sample_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,9 @@ log_config: "CONFDIR/SERVERNAME.log.config"
# - one for ratelimiting how often a user or IP can attempt to validate a 3PID.
# - two for ratelimiting how often invites can be sent in a room or to a
# specific user.
# - one for ratelimiting 3PID invites (i.e. invites sent to a third-party ID
# such as an email address or a phone number) based on the account that's
# sending the invite.
#
# The defaults are as shown below.
#
Expand Down Expand Up @@ -906,6 +909,10 @@ log_config: "CONFDIR/SERVERNAME.log.config"
# per_user:
# per_second: 0.003
# burst_count: 5
#
#rc_third_party_invite:
# per_second: 0.2
# burst_count: 10

# Ratelimiting settings for incoming federation
#
Expand Down
12 changes: 12 additions & 0 deletions synapse/config/ratelimiting.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ def read_config(self, config, **kwargs):
defaults={"per_second": 0.003, "burst_count": 5},
)

self.rc_third_party_invite = RateLimitConfig(
config.get("rc_third_party_invite", {}),
defaults={"per_second": 0.2, "burst_count": 10},
babolivier marked this conversation as resolved.
Show resolved Hide resolved
)

def generate_config_section(self, **kwargs):
return """\
## Ratelimiting ##
Expand Down Expand Up @@ -168,6 +173,9 @@ def generate_config_section(self, **kwargs):
# - one for ratelimiting how often a user or IP can attempt to validate a 3PID.
# - two for ratelimiting how often invites can be sent in a room or to a
# specific user.
# - one for ratelimiting 3PID invites (i.e. invites sent to a third-party ID
# such as an email address or a phone number) based on the account that's
# sending the invite.
#
# The defaults are as shown below.
#
Expand Down Expand Up @@ -217,6 +225,10 @@ def generate_config_section(self, **kwargs):
# per_user:
# per_second: 0.003
# burst_count: 5
#
#rc_third_party_invite:
# per_second: 0.2
# burst_count: 10

# Ratelimiting settings for incoming federation
#
Expand Down
12 changes: 11 additions & 1 deletion synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ def __init__(self, hs: "HomeServer"):
burst_count=hs.config.ratelimiting.rc_invites_per_user.burst_count,
)

self._third_party_invite_limiter = Ratelimiter(
store=self.store,
clock=self.clock,
rate_hz=hs.config.ratelimiting.rc_third_party_invite.per_second,
burst_count=hs.config.ratelimiting.rc_third_party_invite.burst_count,
)

self.request_ratelimiter = hs.get_request_ratelimiter()

@abc.abstractmethod
Expand Down Expand Up @@ -1295,7 +1302,10 @@ async def do_3pid_invite(

# We need to rate limit *before* we send out any 3PID invites, so we
# can't just rely on the standard ratelimiting of events.
await self.request_ratelimiter.ratelimit(requester)
await self._third_party_invite_limiter.ratelimit(
requester=requester,
key=requester.user.to_string(),
)
babolivier marked this conversation as resolved.
Show resolved Hide resolved

can_invite = await self.third_party_event_rules.check_threepid_can_be_invited(
medium, address, room_id
Expand Down