Skip to content

Commit ed8a2c1

Browse files
committed
Enable throttling
Signed-off-by: Tushar Goel <[email protected]>
1 parent 0475246 commit ed8a2c1

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

vulnerabilities/tests/test_fix_api.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,13 @@ def test_api_with_single_vulnerability_and_vulnerable_package(self):
259259
}
260260

261261
def test_api_with_all_vulnerable_packages(self):
262-
with self.assertNumQueries(4):
262+
with self.assertNumQueries(5):
263263
# There are 4 queries:
264264
# 1. SAVEPOINT
265265
# 2. Authenticating user
266-
# 3. Get all vulnerable packages
267-
# 4. RELEASE SAVEPOINT
266+
# 3. Checking if user is staff user for throttling purposes
267+
# 4. Get all vulnerable packages
268+
# 5. RELEASE SAVEPOINT
268269
response = self.csrf_client.get(f"/api/packages/all", format="json").data
269270
assert len(response) == 11
270271
assert response == [

vulnerabilities/throttling.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# VulnerableCode is a trademark of nexB Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
6+
# See https://github.com/nexB/vulnerablecode for support or download.
7+
# See https://aboutcode.org for more information about nexB OSS projects.
8+
#
9+
10+
from django.contrib.auth import get_user_model
11+
from rest_framework.throttling import UserRateThrottle
12+
13+
User = get_user_model()
14+
15+
16+
class ExceptionalUserRateThrottle(UserRateThrottle):
17+
def allow_request(self, request, view):
18+
"""
19+
Give special access to a few special accounts.
20+
21+
Mirrors code in super class with minor tweaks.
22+
"""
23+
if self.rate is None:
24+
return True
25+
26+
self.key = self.get_cache_key(request, view)
27+
if self.key is None:
28+
return True
29+
30+
self.history = self.cache.get(self.key, [])
31+
self.now = self.timer()
32+
33+
# Adjust if user has special privileges.
34+
35+
user = User.objects.get(username=request.user.username)
36+
37+
if user:
38+
if user.is_superuser or user.is_staff:
39+
# No throttling for superusers or staff.
40+
return True
41+
42+
else:
43+
self.num_requests = self.num_requests
44+
self.duration = self.duration
45+
46+
# Drop any requests from the history which have now passed the
47+
# throttle duration
48+
while self.history and self.history[-1] <= self.now - self.duration:
49+
self.history.pop()
50+
if len(self.history) >= self.num_requests:
51+
return self.throttle_failure()
52+
return self.throttle_success()

vulnerablecode/settings.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@
184184
"django_filters.rest_framework.DjangoFilterBackend",
185185
"rest_framework.filters.SearchFilter",
186186
),
187+
"DEFAULT_THROTTLE_CLASSES": [
188+
"vulnerabilities.throttling.ExceptionalUserRateThrottle",
189+
],
190+
"DEFAULT_THROTTLE_RATES": {"user": "1000/hour"},
187191
"DEFAULT_PAGINATION_CLASS": "vulnerabilities.pagination.SmallResultSetPagination",
188192
# Limit the load on the Database returning a small number of records by default. https://github.com/nexB/vulnerablecode/issues/819
189193
"PAGE_SIZE": 10,

0 commit comments

Comments
 (0)