diff --git a/synapse/api/ratelimiting.py b/synapse/api/ratelimiting.py
index ec6b3a69a2..e62ae50ac2 100644
--- a/synapse/api/ratelimiting.py
+++ b/synapse/api/ratelimiting.py
@@ -17,6 +17,7 @@ from collections import OrderedDict
from typing import Any, Optional, Tuple
from synapse.api.errors import LimitExceededError
+from synapse.types import Requester
from synapse.util import Clock
@@ -43,6 +44,42 @@ class Ratelimiter(object):
# * The rate_hz of this particular entry. This can vary per request
self.actions = OrderedDict() # type: OrderedDict[Any, Tuple[float, int, float]]
+ def can_requester_do_action(
+ self,
+ requester: Requester,
+ rate_hz: Optional[float] = None,
+ burst_count: Optional[int] = None,
+ update: bool = True,
+ _time_now_s: Optional[int] = None,
+ ) -> Tuple[bool, float]:
+ """Can the requester perform the action?
+
+ Args:
+ requester: The requester to key off when rate limiting. The user property
+ will be used.
+ rate_hz: The long term number of actions that can be performed in a second.
+ Overrides the value set during instantiation if set.
+ burst_count: How many actions that can be performed before being limited.
+ Overrides the value set during instantiation if set.
+ update: Whether to count this check as performing the action
+ _time_now_s: The current time. Optional, defaults to the current time according
+ to self.clock. Only used by tests.
+
+ Returns:
+ A tuple containing:
+ * A bool indicating if they can perform the action now
+ * The reactor timestamp for when the action can be performed next.
+ -1 if rate_hz is less than or equal to zero
+ """
+ # Disable rate limiting of users belonging to any AS that is configured
+ # not to be rate limited in its registration file (rate_limited: true|false).
+ if requester.app_service and not requester.app_service.is_rate_limited():
+ return True, -1.0
+
+ return self.can_do_action(
+ requester.user.to_string(), rate_hz, burst_count, update, _time_now_s
+ )
+
def can_do_action(
self,
key: Any,
diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py
index 31705cdbdb..0cd59bce3b 100644
--- a/synapse/handlers/room_member.py
+++ b/synapse/handlers/room_member.py
@@ -459,9 +459,10 @@ class RoomMemberHandler(object):
if is_host_in_room:
time_now_s = self.clock.time()
- allowed, time_allowed = self._join_rate_limiter_local.can_do_action(
- requester.user.to_string(),
- )
+ (
+ allowed,
+ time_allowed,
+ ) = self._join_rate_limiter_local.can_requester_do_action(requester,)
if not allowed:
raise LimitExceededError(
@@ -470,9 +471,10 @@ class RoomMemberHandler(object):
else:
time_now_s = self.clock.time()
- allowed, time_allowed = self._join_rate_limiter_remote.can_do_action(
- requester.user.to_string(),
- )
+ (
+ allowed,
+ time_allowed,
+ ) = self._join_rate_limiter_remote.can_requester_do_action(requester,)
if not allowed:
raise LimitExceededError(
|