diff --git a/vulnerabilities/api.py b/vulnerabilities/api.py index e622d069a..9e66177fc 100644 --- a/vulnerabilities/api.py +++ b/vulnerabilities/api.py @@ -642,17 +642,13 @@ def filter_cpe(self, queryset, name, value): return self.queryset.filter(vulnerabilityreference__reference_id__startswith=cpe).distinct() -class CPEViewSet(viewsets.ReadOnlyModelViewSet): - """ - Lookup for vulnerabilities by CPE (https://nvd.nist.gov/products/cpe) - """ +class CPEViewSet(VulnerabilityViewSet): + """Lookup for vulnerabilities by CPE (https://nvd.nist.gov/products/cpe)""" queryset = Vulnerability.objects.filter( vulnerabilityreference__reference_id__startswith="cpe" ).distinct() - serializer_class = VulnerabilitySerializer - filter_backends = (filters.DjangoFilterBackend,) - throttle_classes = [StaffUserRateThrottle, AnonRateThrottle] + filterset_class = CPEFilterSet @action(detail=False, methods=["post"]) diff --git a/vulnerabilities/models.py b/vulnerabilities/models.py index 2fea8e200..47d57c37f 100644 --- a/vulnerabilities/models.py +++ b/vulnerabilities/models.py @@ -406,7 +406,7 @@ def __str__(self): @property def is_cpe(self): """ - Return Trueis this is a CPE reference. + Return True if this is a CPE reference. """ return self.reference_id.startswith("cpe") @@ -557,7 +557,7 @@ def for_cve(self, cve): def with_is_vulnerable(self): """ - Annotate Package with ``with_is_vulnerable`` boolean attribute. + Annotate Package with ``is_vulnerable`` boolean attribute. """ return self.annotate( is_vulnerable=Exists( diff --git a/vulnerabilities/tests/test_api.py b/vulnerabilities/tests/test_api.py index af05e8be5..7147e849e 100644 --- a/vulnerabilities/tests/test_api.py +++ b/vulnerabilities/tests/test_api.py @@ -705,6 +705,46 @@ def test_api_response(self): self.assertEqual(response["count"], 1) +class TestCPEApiWithPackageVulnerabilityRelation(TestCase): + def setUp(self): + self.user = ApiUser.objects.create_api_user(username="e@mail.com") + self.auth = f"Token {self.user.auth_token.key}" + self.csrf_client = APIClient(enforce_csrf_checks=True) + self.csrf_client.credentials(HTTP_AUTHORIZATION=self.auth) + self.vulnerability = Vulnerability.objects.create(summary="test") + self.affected_package, _ = Package.objects.get_or_create_from_purl( + purl="pkg:nginx/nginx@v3.4" + ) + self.fixed_package, _ = Package.objects.get_or_create_from_purl(purl="pkg:nginx/nginx@v4.0") + AffectedByPackageRelatedVulnerability.objects.create( + vulnerability=self.vulnerability, + created_by="test", + package=self.affected_package, + confidence=100, + ) + FixingPackageRelatedVulnerability.objects.create( + vulnerability=self.vulnerability, + created_by="test", + package=self.fixed_package, + confidence=100, + ) + for i in range(0, 10): + ref, _ = VulnerabilityReference.objects.get_or_create( + reference_id=f"cpe:/a:nginx:{i}", + url=f"https://nvd.nist.gov/vuln/search/results?adv_search=true&isCpeNameSearch=true&query=cpe:/a:nginx:{i}", + ) + VulnerabilityRelatedReference.objects.create( + reference=ref, vulnerability=self.vulnerability + ) + + def test_cpe_api(self): + response = self.csrf_client.get("/api/cpes/", format="json") + self.assertEqual(status.HTTP_200_OK, response.status_code) + + response_data = response.json() + self.assertEqual(1, response_data["count"]) + + class AliasApi(TestCase): def setUp(self): self.user = ApiUser.objects.create_api_user(username="e@mail.com") diff --git a/vulnerablecode/settings.py b/vulnerablecode/settings.py index 1ae664d82..0e545e0f2 100644 --- a/vulnerablecode/settings.py +++ b/vulnerablecode/settings.py @@ -349,3 +349,9 @@ }, }, } + +if DEBUG: + LOGGING["django"] = { + "handlers": ["console"], + "level": "ERROR", + }