Honour ratelimit flag for application services for invite ratelimiting (#9302)
This commit is contained in:
parent
eec9ab3225
commit
ff55300b91
|
@ -0,0 +1 @@
|
||||||
|
Fix new ratelimiting for invites to respect the `ratelimit` flag on application services. Introduced in v1.27.0rc1.
|
|
@ -1619,7 +1619,9 @@ class FederationHandler(BaseHandler):
|
||||||
|
|
||||||
# We retrieve the room member handler here as to not cause a cyclic dependency
|
# We retrieve the room member handler here as to not cause a cyclic dependency
|
||||||
member_handler = self.hs.get_room_member_handler()
|
member_handler = self.hs.get_room_member_handler()
|
||||||
member_handler.ratelimit_invite(event.room_id, event.state_key)
|
# We don't rate limit based on room ID, as that should be done by
|
||||||
|
# sending server.
|
||||||
|
member_handler.ratelimit_invite(None, event.state_key)
|
||||||
|
|
||||||
# keep a record of the room version, if we don't yet know it.
|
# keep a record of the room version, if we don't yet know it.
|
||||||
# (this may get overwritten if we later get a different room version in a
|
# (this may get overwritten if we later get a different room version in a
|
||||||
|
|
|
@ -155,10 +155,14 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def ratelimit_invite(self, room_id: str, invitee_user_id: str):
|
def ratelimit_invite(self, room_id: Optional[str], invitee_user_id: str):
|
||||||
"""Ratelimit invites by room and by target user.
|
"""Ratelimit invites by room and by target user.
|
||||||
|
|
||||||
|
If room ID is missing then we just rate limit by target user.
|
||||||
"""
|
"""
|
||||||
self._invites_per_room_limiter.ratelimit(room_id)
|
if room_id:
|
||||||
|
self._invites_per_room_limiter.ratelimit(room_id)
|
||||||
|
|
||||||
self._invites_per_user_limiter.ratelimit(invitee_user_id)
|
self._invites_per_user_limiter.ratelimit(invitee_user_id)
|
||||||
|
|
||||||
async def _local_membership_update(
|
async def _local_membership_update(
|
||||||
|
@ -406,7 +410,9 @@ class RoomMemberHandler(metaclass=abc.ABCMeta):
|
||||||
if effective_membership_state == Membership.INVITE:
|
if effective_membership_state == Membership.INVITE:
|
||||||
target_id = target.to_string()
|
target_id = target.to_string()
|
||||||
if ratelimit:
|
if ratelimit:
|
||||||
self.ratelimit_invite(room_id, target_id)
|
# Don't ratelimit application services.
|
||||||
|
if not requester.app_service or requester.app_service.is_rate_limited():
|
||||||
|
self.ratelimit_invite(room_id, target_id)
|
||||||
|
|
||||||
# block any attempts to invite the server notices mxid
|
# block any attempts to invite the server notices mxid
|
||||||
if target_id == self._server_notices_mxid:
|
if target_id == self._server_notices_mxid:
|
||||||
|
|
|
@ -191,53 +191,6 @@ class FederationTestCase(unittest.HomeserverTestCase):
|
||||||
|
|
||||||
self.assertEqual(sg, sg2)
|
self.assertEqual(sg, sg2)
|
||||||
|
|
||||||
@unittest.override_config(
|
|
||||||
{"rc_invites": {"per_room": {"per_second": 0.5, "burst_count": 3}}}
|
|
||||||
)
|
|
||||||
def test_invite_by_room_ratelimit(self):
|
|
||||||
"""Tests that invites from federation in a room are actually rate-limited.
|
|
||||||
"""
|
|
||||||
other_server = "otherserver"
|
|
||||||
other_user = "@otheruser:" + other_server
|
|
||||||
|
|
||||||
# create the room
|
|
||||||
user_id = self.register_user("kermit", "test")
|
|
||||||
tok = self.login("kermit", "test")
|
|
||||||
room_id = self.helper.create_room_as(room_creator=user_id, tok=tok)
|
|
||||||
room_version = self.get_success(self.store.get_room_version(room_id))
|
|
||||||
|
|
||||||
def create_invite_for(local_user):
|
|
||||||
return event_from_pdu_json(
|
|
||||||
{
|
|
||||||
"type": EventTypes.Member,
|
|
||||||
"content": {"membership": "invite"},
|
|
||||||
"room_id": room_id,
|
|
||||||
"sender": other_user,
|
|
||||||
"state_key": local_user,
|
|
||||||
"depth": 32,
|
|
||||||
"prev_events": [],
|
|
||||||
"auth_events": [],
|
|
||||||
"origin_server_ts": self.clock.time_msec(),
|
|
||||||
},
|
|
||||||
room_version,
|
|
||||||
)
|
|
||||||
|
|
||||||
for i in range(3):
|
|
||||||
self.get_success(
|
|
||||||
self.handler.on_invite_request(
|
|
||||||
other_server,
|
|
||||||
create_invite_for("@user-%d:test" % (i,)),
|
|
||||||
room_version,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.get_failure(
|
|
||||||
self.handler.on_invite_request(
|
|
||||||
other_server, create_invite_for("@user-4:test"), room_version,
|
|
||||||
),
|
|
||||||
exc=LimitExceededError,
|
|
||||||
)
|
|
||||||
|
|
||||||
@unittest.override_config(
|
@unittest.override_config(
|
||||||
{"rc_invites": {"per_user": {"per_second": 0.5, "burst_count": 3}}}
|
{"rc_invites": {"per_user": {"per_second": 0.5, "burst_count": 3}}}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue