Skip to content

Commit aa38d2d

Browse files
committed
wip
Signed-off-by: Keshav Priyadarshi <git@keshav.space>
1 parent 79f181c commit aa38d2d

File tree

5 files changed

+54
-15
lines changed

5 files changed

+54
-15
lines changed

vulnerabilities/api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from vulnerabilities.models import get_purl_query_lookups
3535
from vulnerabilities.severity_systems import EPSS
3636
from vulnerabilities.severity_systems import SCORING_SYSTEMS
37-
from vulnerabilities.throttling import StaffUserRateThrottle
37+
from vulnerabilities.throttling import GroupUserRateThrottle
3838
from vulnerabilities.utils import get_severity_range
3939

4040

@@ -471,7 +471,7 @@ class PackageViewSet(viewsets.ReadOnlyModelViewSet):
471471
serializer_class = PackageSerializer
472472
filter_backends = (filters.DjangoFilterBackend,)
473473
filterset_class = PackageFilterSet
474-
throttle_classes = [StaffUserRateThrottle, AnonRateThrottle]
474+
throttle_classes = [AnonRateThrottle, GroupUserRateThrottle]
475475

476476
def get_queryset(self):
477477
return super().get_queryset().with_is_vulnerable()
@@ -688,7 +688,7 @@ def get_queryset(self):
688688
serializer_class = VulnerabilitySerializer
689689
filter_backends = (filters.DjangoFilterBackend,)
690690
filterset_class = VulnerabilityFilterSet
691-
throttle_classes = [StaffUserRateThrottle, AnonRateThrottle]
691+
throttle_classes = [AnonRateThrottle, GroupUserRateThrottle]
692692

693693

694694
class CPEFilterSet(filters.FilterSet):

vulnerabilities/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from cwe2.mappings import xml_database_path
2929
from cwe2.weakness import Weakness as DBWeakness
3030
from django.contrib.auth import get_user_model
31+
from django.contrib.auth.models import Group
3132
from django.contrib.auth.models import UserManager
3233
from django.core import exceptions
3334
from django.core.exceptions import ValidationError
@@ -1435,6 +1436,10 @@ def create_api_user(self, username, first_name="", last_name="", **extra_fields)
14351436
user.set_unusable_password()
14361437
user.save()
14371438

1439+
# Assign the default basic group
1440+
default_group, _ = Group.objects.get_or_create(name="silver")
1441+
user.groups.add(default_group)
1442+
14381443
Token._default_manager.get_or_create(user=user)
14391444

14401445
return user

vulnerabilities/tests/test_throttling.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import json
1111

12+
from django.contrib.auth.models import Group
1213
from django.core.cache import cache
1314
from rest_framework.test import APIClient
1415
from rest_framework.test import APITestCase
@@ -23,12 +24,20 @@ def setUp(self):
2324
# See https://www.django-rest-framework.org/api-guide/throttling/#setting-up-the-cache
2425
cache.clear()
2526

26-
# create a basic user
27+
# create a basic user (silver)
2728
self.user = ApiUser.objects.create_api_user(username="e@mail.com")
2829
self.auth = f"Token {self.user.auth_token.key}"
2930
self.csrf_client = APIClient(enforce_csrf_checks=True)
3031
self.csrf_client.credentials(HTTP_AUTHORIZATION=self.auth)
3132

33+
# create user (gold)
34+
self.gold_user = ApiUser.objects.create_api_user(username="g@mail.com")
35+
gold, _ = Group.objects.get_or_create(name="gold")
36+
self.gold_user.groups.add(gold)
37+
self.gold_auth = f"Token {self.gold_user.auth_token.key}"
38+
self.gold_csrf_client = APIClient(enforce_csrf_checks=True)
39+
self.gold_csrf_client.credentials(HTTP_AUTHORIZATION=self.gold_auth)
40+
3241
# create a staff user
3342
self.staff_user = ApiUser.objects.create_api_user(username="staff@mail.com", is_staff=True)
3443
self.staff_auth = f"Token {self.staff_user.auth_token.key}"
@@ -45,6 +54,12 @@ def test_package_endpoint_throttling(self):
4554
response = self.staff_csrf_client.get("/api/packages")
4655
self.assertEqual(response.status_code, 200)
4756

57+
for i in range(0, 25):
58+
response = self.gold_csrf_client.get("/api/packages")
59+
self.assertEqual(response.status_code, 200)
60+
response = self.csrf_client.get("/api/packages")
61+
self.assertEqual(response.status_code, 200)
62+
4863
response = self.csrf_client.get("/api/packages")
4964
# 429 - too many requests for basic user
5065
self.assertEqual(response.status_code, 429)

vulnerabilities/throttling.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,30 @@
66
# See https://github.com/aboutcode-org/vulnerablecode for support or download.
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
9+
910
from rest_framework.exceptions import Throttled
1011
from rest_framework.throttling import UserRateThrottle
1112
from rest_framework.views import exception_handler
1213

1314

14-
class StaffUserRateThrottle(UserRateThrottle):
15+
class GroupUserRateThrottle(UserRateThrottle):
16+
scope = "bronze"
17+
1518
def allow_request(self, request, view):
16-
"""
17-
Do not apply throttling for superusers and admins.
18-
"""
19-
if request.user.is_superuser or request.user.is_staff:
20-
return True
19+
user = request.user
20+
21+
if user and user.is_authenticated:
22+
if user.is_superuser or user.is_staff:
23+
return True
24+
25+
if user.groups.filter(name="gold").exists():
26+
return True
27+
28+
if user.groups.filter(name="silver").exists():
29+
self.scope = "silver"
30+
31+
self.rate = self.THROTTLE_RATES.get(self.scope)
32+
self.num_requests, self.duration = self.parse_rate(self.rate)
2133

2234
return super().allow_request(request, view)
2335

vulnerablecode/settings.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,20 @@
190190
LOGIN_REDIRECT_URL = "/"
191191
LOGOUT_REDIRECT_URL = "/"
192192

193-
REST_FRAMEWORK_DEFAULT_THROTTLE_RATES = {"anon": "3600/hour", "user": "10800/hour"}
193+
REST_FRAMEWORK_DEFAULT_THROTTLE_RATES = {
194+
# No throttling for users in gold group.
195+
"silver": "10800/hour",
196+
"bronze": "7200/hour",
197+
"anon": "3600/hour",
198+
}
194199

195200
if IS_TESTS:
196201
VULNERABLECODEIO_REQUIRE_AUTHENTICATION = False
197-
REST_FRAMEWORK_DEFAULT_THROTTLE_RATES = {"anon": "10/day", "user": "20/day"}
198-
202+
REST_FRAMEWORK_DEFAULT_THROTTLE_RATES = {
203+
"silver": "20/day",
204+
"bronze": "15/day",
205+
"anon": "10/day",
206+
}
199207

200208
USE_L10N = True
201209

@@ -235,9 +243,8 @@
235243
"rest_framework.filters.SearchFilter",
236244
),
237245
"DEFAULT_THROTTLE_CLASSES": [
238-
"vulnerabilities.throttling.StaffUserRateThrottle",
246+
"vulnerabilities.throttling.GroupUserRateThrottle",
239247
"rest_framework.throttling.AnonRateThrottle",
240-
"rest_framework.throttling.UserRateThrottle",
241248
],
242249
"DEFAULT_THROTTLE_RATES": REST_FRAMEWORK_DEFAULT_THROTTLE_RATES,
243250
"EXCEPTION_HANDLER": "vulnerabilities.throttling.throttled_exception_handler",

0 commit comments

Comments
 (0)