[Backport] Throttling membership creation
parent
ed9ddf9aa9
commit
ec049521e4
|
@ -424,7 +424,7 @@ REST_FRAMEWORK = {
|
|||
"user": None,
|
||||
"import-mode": None,
|
||||
"import-dump-mode": "1/minute",
|
||||
"memberships": None,
|
||||
"create-memberships": None
|
||||
},
|
||||
"FILTER_BACKEND": "taiga.base.filters.FilterBackend",
|
||||
"EXCEPTION_HANDLER": "taiga.base.exceptions.exception_handler",
|
||||
|
|
|
@ -33,5 +33,5 @@ REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"] = {
|
|||
"user": None,
|
||||
"import-mode": None,
|
||||
"import-dump-mode": None,
|
||||
"memberships": None,
|
||||
"create-memberships": None,
|
||||
}
|
||||
|
|
|
@ -153,11 +153,15 @@ class SimpleRateThrottle(BaseThrottle):
|
|||
# throttle duration
|
||||
while self.history and self.history[-1] <= self.now - self.duration:
|
||||
self.history.pop()
|
||||
if len(self.history) >= self.num_requests:
|
||||
return self.throttle_failure()
|
||||
return self.throttle_success()
|
||||
|
||||
def throttle_success(self):
|
||||
if self.exceeded_throttling_restriction(request, view):
|
||||
return self.throttle_failure()
|
||||
return self.throttle_success(request, view)
|
||||
|
||||
def exceeded_throttling_restriction(self, request, view):
|
||||
return len(self.history) >= self.num_requests
|
||||
|
||||
def throttle_success(self, request, view):
|
||||
"""
|
||||
Inserts the current request's timestamp along with the key
|
||||
into the cache.
|
||||
|
|
|
@ -20,5 +20,20 @@ from taiga.base import throttling
|
|||
|
||||
|
||||
class MembershipsRateThrottle(throttling.UserRateThrottle):
|
||||
scope = "memberships"
|
||||
scope = "create-memberships"
|
||||
throttled_methods = ["POST", "PUT"]
|
||||
|
||||
def exceeded_throttling_restriction(self, request, view):
|
||||
self.created_memberships = 0
|
||||
if view.action in ["create", "resend_invitation"]:
|
||||
self.created_memberships = 1
|
||||
elif view.action == "bulk_create":
|
||||
self.created_memberships = len(request.DATA.get("bulk_memberships", []))
|
||||
return len(self.history) + self.created_memberships > self.num_requests
|
||||
|
||||
def throttle_success(self, request, view):
|
||||
for i in range(self.created_memberships):
|
||||
self.history.insert(0, self.now)
|
||||
|
||||
self.cache.set(self.key, self.history, self.duration)
|
||||
return True
|
||||
|
|
|
@ -606,7 +606,7 @@ def test_api_create_bulk_members_max_pending_memberships(client, settings):
|
|||
|
||||
|
||||
def test_create_memberhips_throttling(client, settings):
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["memberships"] = "1/minute"
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = "1/minute"
|
||||
|
||||
membership = f.MembershipFactory(is_admin=True)
|
||||
role = f.RoleFactory.create(project=membership.project)
|
||||
|
@ -625,11 +625,11 @@ def test_create_memberhips_throttling(client, settings):
|
|||
response = client.json.post(url, json.dumps(data))
|
||||
|
||||
assert response.status_code == 429
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["memberships"] = None
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = None
|
||||
|
||||
|
||||
def test_api_resend_invitation_throttling(client, outbox, settings):
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["memberships"] = "1/minute"
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = "1/minute"
|
||||
|
||||
invitation = f.create_invitation(user=None)
|
||||
f.MembershipFactory(project=invitation.project, user=invitation.project.owner, is_admin=True)
|
||||
|
@ -647,11 +647,11 @@ def test_api_resend_invitation_throttling(client, outbox, settings):
|
|||
assert response.status_code == 429
|
||||
assert len(outbox) == 1
|
||||
assert outbox[0].to == [invitation.email]
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["memberships"] = None
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = None
|
||||
|
||||
|
||||
def test_api_create_bulk_members_throttling(client, settings):
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["memberships"] = "1/minute"
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = "2/minute"
|
||||
|
||||
project = f.ProjectFactory()
|
||||
john = f.UserFactory.create()
|
||||
|
@ -686,4 +686,4 @@ def test_api_create_bulk_members_throttling(client, settings):
|
|||
response = client.json.post(url, json.dumps(data))
|
||||
|
||||
assert response.status_code == 429
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["memberships"] = None
|
||||
settings.REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]["create-memberships"] = None
|
||||
|
|
Loading…
Reference in New Issue