Skip to content

Commit 68a375c

Browse files
committed
Add tests for user permission based API throttling
Signed-off-by: Keshav Priyadarshi <git@keshav.space>
1 parent dba5b6c commit 68a375c

File tree

3 files changed

+150
-110
lines changed

3 files changed

+150
-110
lines changed

vulnerabilities/tests/test_api.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import os
1212
from urllib.parse import quote
1313

14+
from django.core.cache import cache
1415
from django.test import TestCase
1516
from django.test import TransactionTestCase
1617
from django.test.client import RequestFactory
@@ -452,10 +453,8 @@ def add_aliases(vuln, aliases):
452453

453454
class APIPerformanceTest(TestCase):
454455
def setUp(self):
455-
self.user = ApiUser.objects.create_api_user(username="e@mail.com", is_staff=True)
456-
self.auth = f"Token {self.user.auth_token.key}"
456+
cache.clear()
457457
self.csrf_client = APIClient(enforce_csrf_checks=True)
458-
self.csrf_client.credentials(HTTP_AUTHORIZATION=self.auth)
459458

460459
# This setup creates the following data:
461460
# vulnerabilities: vul1, vul2, vul3
@@ -503,7 +502,7 @@ def setUp(self):
503502
set_as_fixing(package=self.pkg_2_13_2, vulnerability=self.vul1)
504503

505504
def test_api_packages_all_num_queries(self):
506-
with self.assertNumQueries(4):
505+
with self.assertNumQueries(3):
507506
# There are 4 queries:
508507
# 1. SAVEPOINT
509508
# 2. Authenticating user
@@ -519,22 +518,22 @@ def test_api_packages_all_num_queries(self):
519518
]
520519

521520
def test_api_packages_single_num_queries(self):
522-
with self.assertNumQueries(8):
521+
with self.assertNumQueries(7):
523522
self.csrf_client.get(f"/api/packages/{self.pkg_2_14_0_rc1.id}", format="json")
524523

525524
def test_api_packages_single_with_purl_in_query_num_queries(self):
526-
with self.assertNumQueries(9):
525+
with self.assertNumQueries(8):
527526
self.csrf_client.get(f"/api/packages/?purl={self.pkg_2_14_0_rc1.purl}", format="json")
528527

529528
def test_api_packages_single_with_purl_no_version_in_query_num_queries(self):
530-
with self.assertNumQueries(64):
529+
with self.assertNumQueries(63):
531530
self.csrf_client.get(
532531
f"/api/packages/?purl=pkg:maven/com.fasterxml.jackson.core/jackson-databind",
533532
format="json",
534533
)
535534

536535
def test_api_packages_bulk_search(self):
537-
with self.assertNumQueries(45):
536+
with self.assertNumQueries(44):
538537
packages = [self.pkg_2_12_6, self.pkg_2_12_6_1, self.pkg_2_13_1]
539538
purls = [p.purl for p in packages]
540539

@@ -547,7 +546,7 @@ def test_api_packages_bulk_search(self):
547546
).json()
548547

549548
def test_api_packages_with_lookup(self):
550-
with self.assertNumQueries(14):
549+
with self.assertNumQueries(13):
551550
data = {"purl": self.pkg_2_12_6.purl}
552551

553552
resp = self.csrf_client.post(
@@ -557,7 +556,7 @@ def test_api_packages_with_lookup(self):
557556
).json()
558557

559558
def test_api_packages_bulk_lookup(self):
560-
with self.assertNumQueries(45):
559+
with self.assertNumQueries(44):
561560
packages = [self.pkg_2_12_6, self.pkg_2_12_6_1, self.pkg_2_13_1]
562561
purls = [p.purl for p in packages]
563562

@@ -572,10 +571,8 @@ def test_api_packages_bulk_lookup(self):
572571

573572
class APITestCasePackage(TestCase):
574573
def setUp(self):
575-
self.user = ApiUser.objects.create_api_user(username="e@mail.com", is_staff=True)
576-
self.auth = f"Token {self.user.auth_token.key}"
574+
cache.clear()
577575
self.csrf_client = APIClient(enforce_csrf_checks=True)
578-
self.csrf_client.credentials(HTTP_AUTHORIZATION=self.auth)
579576

580577
# This setup creates the following data:
581578
# vulnerabilities: vul1, vul2, vul3
@@ -766,7 +763,7 @@ def test_api_with_wrong_namespace_filter(self):
766763
self.assertEqual(response["count"], 0)
767764

768765
def test_api_with_all_vulnerable_packages(self):
769-
with self.assertNumQueries(4):
766+
with self.assertNumQueries(3):
770767
# There are 4 queries:
771768
# 1. SAVEPOINT
772769
# 2. Authenticating user

vulnerabilities/tests/test_api_v2.py

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,8 @@ def setUp(self):
6161
)
6262
self.reference2.vulnerabilities.add(self.vuln2)
6363

64-
self.user = ApiUser.objects.create_api_user(username="e@mail.com", is_staff=True)
65-
self.auth = f"Token {self.user.auth_token.key}"
64+
cache.clear()
6665
self.client = APIClient(enforce_csrf_checks=True)
67-
self.client.credentials(HTTP_AUTHORIZATION=self.auth)
6866

6967
def test_list_vulnerabilities(self):
7068
"""
@@ -73,7 +71,7 @@ def test_list_vulnerabilities(self):
7371
"""
7472
url = reverse("vulnerability-v2-list")
7573
response = self.client.get(url, format="json")
76-
with self.assertNumQueries(5):
74+
with self.assertNumQueries(4):
7775
response = self.client.get(url, format="json")
7876
self.assertEqual(response.status_code, status.HTTP_200_OK)
7977
self.assertIn("results", response.data)
@@ -88,7 +86,7 @@ def test_retrieve_vulnerability_detail(self):
8886
Test retrieving vulnerability details by vulnerability_id.
8987
"""
9088
url = reverse("vulnerability-v2-detail", kwargs={"vulnerability_id": "VCID-1234"})
91-
with self.assertNumQueries(8):
89+
with self.assertNumQueries(7):
9290
response = self.client.get(url, format="json")
9391
self.assertEqual(response.status_code, status.HTTP_200_OK)
9492
self.assertEqual(response.data["vulnerability_id"], "VCID-1234")
@@ -102,7 +100,7 @@ def test_filter_vulnerability_by_vulnerability_id(self):
102100
Test filtering vulnerabilities by vulnerability_id.
103101
"""
104102
url = reverse("vulnerability-v2-list")
105-
with self.assertNumQueries(4):
103+
with self.assertNumQueries(3):
106104
response = self.client.get(url, {"vulnerability_id": "VCID-1234"}, format="json")
107105
self.assertEqual(response.status_code, status.HTTP_200_OK)
108106
self.assertEqual(response.data["vulnerability_id"], "VCID-1234")
@@ -112,7 +110,7 @@ def test_filter_vulnerability_by_alias(self):
112110
Test filtering vulnerabilities by alias.
113111
"""
114112
url = reverse("vulnerability-v2-list")
115-
with self.assertNumQueries(5):
113+
with self.assertNumQueries(4):
116114
response = self.client.get(url, {"alias": "CVE-2021-5678"}, format="json")
117115
self.assertEqual(response.status_code, status.HTTP_200_OK)
118116
self.assertIn("results", response.data)
@@ -127,7 +125,7 @@ def test_filter_vulnerabilities_multiple_ids(self):
127125
Test filtering vulnerabilities by multiple vulnerability_ids.
128126
"""
129127
url = reverse("vulnerability-v2-list")
130-
with self.assertNumQueries(5):
128+
with self.assertNumQueries(4):
131129
response = self.client.get(
132130
url, {"vulnerability_id": ["VCID-1234", "VCID-5678"]}, format="json"
133131
)
@@ -139,7 +137,7 @@ def test_filter_vulnerabilities_multiple_aliases(self):
139137
Test filtering vulnerabilities by multiple aliases.
140138
"""
141139
url = reverse("vulnerability-v2-list")
142-
with self.assertNumQueries(5):
140+
with self.assertNumQueries(4):
143141
response = self.client.get(
144142
url, {"alias": ["CVE-2021-1234", "CVE-2021-5678"]}, format="json"
145143
)
@@ -152,7 +150,7 @@ def test_invalid_vulnerability_id(self):
152150
Should return 404 Not Found.
153151
"""
154152
url = reverse("vulnerability-v2-detail", kwargs={"vulnerability_id": "VCID-9999"})
155-
with self.assertNumQueries(5):
153+
with self.assertNumQueries(4):
156154
response = self.client.get(url, format="json")
157155
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
158156

@@ -210,18 +208,16 @@ def setUp(self):
210208
self.package1.affected_by_vulnerabilities.add(self.vuln1)
211209
self.package2.fixing_vulnerabilities.add(self.vuln2)
212210

213-
self.user = ApiUser.objects.create_api_user(username="e@mail.com", is_staff=True)
214-
self.auth = f"Token {self.user.auth_token.key}"
211+
cache.clear()
215212
self.client = APIClient(enforce_csrf_checks=True)
216-
self.client.credentials(HTTP_AUTHORIZATION=self.auth)
217213

218214
def test_list_packages(self):
219215
"""
220216
Test listing packages without filters.
221217
Should return a list of packages with their details and associated vulnerabilities.
222218
"""
223219
url = reverse("package-v2-list")
224-
with self.assertNumQueries(32):
220+
with self.assertNumQueries(31):
225221
response = self.client.get(url, format="json")
226222
self.assertEqual(response.status_code, status.HTTP_200_OK)
227223
self.assertIn("results", response.data)
@@ -243,7 +239,7 @@ def test_filter_packages_by_purl(self):
243239
Test filtering packages by one or more PURLs.
244240
"""
245241
url = reverse("package-v2-list")
246-
with self.assertNumQueries(20):
242+
with self.assertNumQueries(19):
247243
response = self.client.get(url, {"purl": "pkg:pypi/django@3.2"}, format="json")
248244
self.assertEqual(response.status_code, status.HTTP_200_OK)
249245
self.assertEqual(len(response.data["results"]["packages"]), 1)
@@ -254,7 +250,7 @@ def test_filter_packages_by_affected_vulnerability(self):
254250
Test filtering packages by affected_by_vulnerability.
255251
"""
256252
url = reverse("package-v2-list")
257-
with self.assertNumQueries(20):
253+
with self.assertNumQueries(19):
258254
response = self.client.get(
259255
url, {"affected_by_vulnerability": "VCID-1234"}, format="json"
260256
)
@@ -267,7 +263,7 @@ def test_filter_packages_by_fixing_vulnerability(self):
267263
Test filtering packages by fixing_vulnerability.
268264
"""
269265
url = reverse("package-v2-list")
270-
with self.assertNumQueries(18):
266+
with self.assertNumQueries(17):
271267
response = self.client.get(url, {"fixing_vulnerability": "VCID-5678"}, format="json")
272268
self.assertEqual(response.status_code, status.HTTP_200_OK)
273269
self.assertEqual(len(response.data["results"]["packages"]), 1)
@@ -356,7 +352,7 @@ def test_invalid_vulnerability_filter(self):
356352
Should return an empty list.
357353
"""
358354
url = reverse("package-v2-list")
359-
with self.assertNumQueries(4):
355+
with self.assertNumQueries(3):
360356
response = self.client.get(
361357
url, {"affected_by_vulnerability": "VCID-9999"}, format="json"
362358
)
@@ -369,7 +365,7 @@ def test_invalid_purl_filter(self):
369365
Should return an empty list.
370366
"""
371367
url = reverse("package-v2-list")
372-
with self.assertNumQueries(4):
368+
with self.assertNumQueries(3):
373369
response = self.client.get(
374370
url, {"purl": "pkg:nonexistent/package@1.0.0"}, format="json"
375371
)
@@ -421,7 +417,7 @@ def test_bulk_lookup_with_valid_purls(self):
421417
"""
422418
url = reverse("package-v2-bulk-lookup")
423419
data = {"purls": ["pkg:pypi/django@3.2", "pkg:npm/lodash@4.17.20"]}
424-
with self.assertNumQueries(28):
420+
with self.assertNumQueries(27):
425421
response = self.client.post(url, data, format="json")
426422
self.assertEqual(response.status_code, status.HTTP_200_OK)
427423
self.assertIn("packages", response.data)
@@ -446,7 +442,7 @@ def test_bulk_lookup_with_invalid_purls(self):
446442
"""
447443
url = reverse("package-v2-bulk-lookup")
448444
data = {"purls": ["pkg:pypi/nonexistent@1.0.0", "pkg:npm/unknown@0.0.1"]}
449-
with self.assertNumQueries(4):
445+
with self.assertNumQueries(3):
450446
response = self.client.post(url, data, format="json")
451447
self.assertEqual(response.status_code, status.HTTP_200_OK)
452448
# Since the packages don't exist, the response should be empty
@@ -460,7 +456,7 @@ def test_bulk_lookup_with_empty_purls(self):
460456
"""
461457
url = reverse("package-v2-bulk-lookup")
462458
data = {"purls": []}
463-
with self.assertNumQueries(3):
459+
with self.assertNumQueries(2):
464460
response = self.client.post(url, data, format="json")
465461
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
466462
self.assertIn("error", response.data)
@@ -474,7 +470,7 @@ def test_bulk_search_with_valid_purls(self):
474470
"""
475471
url = reverse("package-v2-bulk-search")
476472
data = {"purls": ["pkg:pypi/django@3.2", "pkg:npm/lodash@4.17.20"]}
477-
with self.assertNumQueries(28):
473+
with self.assertNumQueries(27):
478474
response = self.client.post(url, data, format="json")
479475
self.assertEqual(response.status_code, status.HTTP_200_OK)
480476
self.assertIn("packages", response.data)
@@ -502,7 +498,7 @@ def test_bulk_search_with_purl_only_true(self):
502498
"purls": ["pkg:pypi/django@3.2", "pkg:npm/lodash@4.17.20"],
503499
"purl_only": True,
504500
}
505-
with self.assertNumQueries(17):
501+
with self.assertNumQueries(16):
506502
response = self.client.post(url, data, format="json")
507503
self.assertEqual(response.status_code, status.HTTP_200_OK)
508504
# Since purl_only=True, response should be a list of PURLs
@@ -529,7 +525,7 @@ def test_bulk_search_with_plain_purl_true(self):
529525
"purls": ["pkg:pypi/django@3.2", "pkg:pypi/django@3.2?extension=tar.gz"],
530526
"plain_purl": True,
531527
}
532-
with self.assertNumQueries(16):
528+
with self.assertNumQueries(15):
533529
response = self.client.post(url, data, format="json")
534530
self.assertEqual(response.status_code, status.HTTP_200_OK)
535531
self.assertIn("packages", response.data)
@@ -550,7 +546,7 @@ def test_bulk_search_with_purl_only_and_plain_purl_true(self):
550546
"purl_only": True,
551547
"plain_purl": True,
552548
}
553-
with self.assertNumQueries(11):
549+
with self.assertNumQueries(10):
554550
response = self.client.post(url, data, format="json")
555551
self.assertEqual(response.status_code, status.HTTP_200_OK)
556552
# Response should be a list of plain PURLs
@@ -566,7 +562,7 @@ def test_bulk_search_with_invalid_purls(self):
566562
"""
567563
url = reverse("package-v2-bulk-search")
568564
data = {"purls": ["pkg:pypi/nonexistent@1.0.0", "pkg:npm/unknown@0.0.1"]}
569-
with self.assertNumQueries(4):
565+
with self.assertNumQueries(3):
570566
response = self.client.post(url, data, format="json")
571567
self.assertEqual(response.status_code, status.HTTP_200_OK)
572568
# Since the packages don't exist, the response should be empty
@@ -580,7 +576,7 @@ def test_bulk_search_with_empty_purls(self):
580576
"""
581577
url = reverse("package-v2-bulk-search")
582578
data = {"purls": []}
583-
with self.assertNumQueries(3):
579+
with self.assertNumQueries(2):
584580
response = self.client.post(url, data, format="json")
585581
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
586582
self.assertIn("error", response.data)
@@ -592,7 +588,7 @@ def test_all_vulnerable_packages(self):
592588
Test the 'all' endpoint that returns all vulnerable package URLs.
593589
"""
594590
url = reverse("package-v2-all")
595-
with self.assertNumQueries(4):
591+
with self.assertNumQueries(3):
596592
response = self.client.get(url, format="json")
597593
self.assertEqual(response.status_code, status.HTTP_200_OK)
598594
# Since package1 is vulnerable, it should be returned
@@ -606,7 +602,7 @@ def test_lookup_with_valid_purl(self):
606602
"""
607603
url = reverse("package-v2-lookup")
608604
data = {"purl": "pkg:pypi/django@3.2"}
609-
with self.assertNumQueries(13):
605+
with self.assertNumQueries(12):
610606
response = self.client.post(url, data, format="json")
611607
self.assertEqual(response.status_code, status.HTTP_200_OK)
612608
self.assertEqual(1, len(response.data))
@@ -635,7 +631,7 @@ def test_lookup_with_invalid_purl(self):
635631
"""
636632
url = reverse("package-v2-lookup")
637633
data = {"purl": "pkg:pypi/nonexistent@1.0.0"}
638-
with self.assertNumQueries(4):
634+
with self.assertNumQueries(3):
639635
response = self.client.post(url, data, format="json")
640636
self.assertEqual(response.status_code, status.HTTP_200_OK)
641637
# No packages or vulnerabilities should be returned
@@ -648,7 +644,7 @@ def test_lookup_with_missing_purl(self):
648644
"""
649645
url = reverse("package-v2-lookup")
650646
data = {}
651-
with self.assertNumQueries(3):
647+
with self.assertNumQueries(2):
652648
response = self.client.post(url, data, format="json")
653649
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
654650
self.assertIn("error", response.data)
@@ -662,7 +658,7 @@ def test_lookup_with_invalid_purl_format(self):
662658
"""
663659
url = reverse("package-v2-lookup")
664660
data = {"purl": "invalid_purl_format"}
665-
with self.assertNumQueries(4):
661+
with self.assertNumQueries(3):
666662
response = self.client.post(url, data, format="json")
667663
self.assertEqual(response.status_code, status.HTTP_200_OK)
668664
# No packages or vulnerabilities should be returned

0 commit comments

Comments
 (0)