Skip to content

Commit

Permalink
Trim api response and add documentation for the bulk endpoints
Browse files Browse the repository at this point in the history
Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
  • Loading branch information
sbs2001 committed Jan 17, 2021
1 parent 8df1bf2 commit 9ab1c2f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 40 deletions.
54 changes: 40 additions & 14 deletions vulnerabilities/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
# Visit https://github.com/nexB/vulnerablecode/ for support and download.

from urllib.parse import unquote
from typing import List

from django.db.models import Q
from django.urls import reverse
Expand All @@ -31,11 +32,17 @@
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from drf_spectacular.utils import extend_schema, inline_serializer
from drf_spectacular.types import OpenApiTypes

from vulnerabilities.models import Package
from vulnerabilities.models import Vulnerability
from vulnerabilities.models import VulnerabilityReference

# This serializer is used for the bulk apis, to prevent wrong auto documentation
# TODO: Fix the swagger documentation for bulk apis
placeholder_serializer = inline_serializer(name="Placeholder", fields={})


class VulnerabilityReferenceSerializer(serializers.ModelSerializer):
class Meta:
Expand Down Expand Up @@ -63,45 +70,52 @@ class Meta:
fields = ["url", "vulnerability_id"]


class VulnerabilitySerializer(serializers.HyperlinkedModelSerializer):
references = VulnerabilityReferenceSerializer(many=True, source="vulnerabilityreference_set")
class MinimalVulnerabilitySerializer(serializers.HyperlinkedModelSerializer):

resolved_packages = HyperLinkedPackageSerializer(
many=True, source="resolved_to", read_only=True
)
unresolved_packages = HyperLinkedPackageSerializer(
many=True, source="vulnerable_to", read_only=True
)

class Meta:
model = Vulnerability
fields = ["url", "unresolved_packages", "resolved_packages"]


class VulnerabilitySerializer(MinimalVulnerabilitySerializer):
references = VulnerabilityReferenceSerializer(many=True, source="vulnerabilityreference_set")

class Meta:
model = Vulnerability
fields = "__all__"


class PackageSerializer(serializers.HyperlinkedModelSerializer):
class MinimalPackageSerializer(serializers.HyperlinkedModelSerializer):
unresolved_vulnerabilities = HyperLinkedVulnerabilitySerializer(
many=True, source="vulnerable_to", read_only=True
)
resolved_vulnerabilities = HyperLinkedVulnerabilitySerializer(
many=True, source="resolved_to", read_only=True
)
purl = serializers.CharField(source="package_url")

class Meta:
model = Package
fields = [
"url",
"type",
"namespace",
"name",
"version",
"qualifiers",
"subpath",
"purl",
"resolved_vulnerabilities",
"unresolved_vulnerabilities",
]


class PackageSerializer(MinimalPackageSerializer):
purl = serializers.CharField(source="package_url")

class Meta:
model = Package
exclude = ["vulnerabilities"]


class PackageFilterSet(filters.FilterSet):
purl = filters.CharFilter(method="filter_purl")

Expand Down Expand Up @@ -129,8 +143,13 @@ class PackageViewSet(viewsets.ReadOnlyModelViewSet):
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = PackageFilterSet

# TODO: Fix the swagger documentation for this endpoint
@extend_schema(request=placeholder_serializer, responses=placeholder_serializer)
@action(detail=False, methods=["post"])
def bulk_search(self, request):
"""
See https://github.com/nexB/vulnerablecode/pull/303#issuecomment-761801639 for docs
"""
filter_list = Q()
response = {}
if not isinstance(request.data.get("packages"), list):
Expand All @@ -152,7 +171,7 @@ def bulk_search(self, request):
response[purl] = {}
res = Package.objects.filter(filter_list)
for p in res:
response[p.package_url] = PackageSerializer(p, context={"request": request}).data
response[p.package_url] = MinimalPackageSerializer(p, context={"request": request}).data

return Response(response)

Expand All @@ -172,8 +191,13 @@ class VulnerabilityViewSet(viewsets.ReadOnlyModelViewSet):
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = VulnerabilityFilterSet

# TODO: Fix the swagger documentation for this endpoint
@extend_schema(request=placeholder_serializer, responses=placeholder_serializer)
@action(detail=False, methods=["post"])
def bulk_search(self, request):
"""
See https://github.com/nexB/vulnerablecode/pull/303#issuecomment-761801619 for docs
"""
filter_list = []
response = {}
if not isinstance(request.data.get("vulnerabilities"), list):
Expand All @@ -190,5 +214,7 @@ def bulk_search(self, request):
response[cve_id] = {}
res = Vulnerability.objects.filter(cve_id__in=filter_list)
for vuln in res:
response[vuln.cve_id] = VulnerabilitySerializer(vuln, context={"request": request}).data
response[vuln.cve_id] = MinimalVulnerabilitySerializer(
vuln, context={"request": request}
).data
return Response(response)
29 changes: 3 additions & 26 deletions vulnerabilities/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,6 @@ def test_bulk_vulnerabilities_api(self):
request_body = {"vulnerabilities": ["CVE-2009-1382", "CVE-2014-8242", "RANDOM-CVE"]}
expected_response = {
"CVE-2009-1382": {
"url": "http://testserver/api/vulnerabilities/2/",
"references": [],
"resolved_packages": [
OrderedDict(
[
Expand All @@ -217,13 +215,9 @@ def test_bulk_vulnerabilities_api(self):
),
],
"unresolved_packages": [],
"cve_id": "CVE-2009-1382",
"summary": "",
"cvss": None,
"url": "http://testserver/api/vulnerabilities/2/",
},
"CVE-2014-8242": {
"url": "http://testserver/api/vulnerabilities/1/",
"references": [],
"resolved_packages": [],
"unresolved_packages": [
OrderedDict(
Expand All @@ -233,12 +227,11 @@ def test_bulk_vulnerabilities_api(self):
]
)
],
"cve_id": "CVE-2014-8242",
"summary": "",
"cvss": None,
"url": "http://testserver/api/vulnerabilities/1/",
},
"RANDOM-CVE": {},
}

response = self.client.post(
"/api/vulnerabilities/bulk_search/", data=request_body, content_type="application/json"
).data
Expand All @@ -256,14 +249,6 @@ def test_bulk_packages_api(self):
).data
expected_response = {
"pkg:deb/debian/librsync@0.9.7-10?distro=jessie": {
"url": "http://testserver/api/packages/1/",
"type": "deb",
"namespace": "debian",
"name": "librsync",
"version": "0.9.7-10",
"qualifiers": {"distro": "jessie"},
"subpath": "",
"purl": "pkg:deb/debian/librsync@0.9.7-10?distro=jessie",
"resolved_vulnerabilities": [],
"unresolved_vulnerabilities": [
OrderedDict(
Expand All @@ -275,14 +260,6 @@ def test_bulk_packages_api(self):
],
},
"pkg:deb/debian/mimetex@1.50-1.1?distro=jessie": {
"url": "http://testserver/api/packages/3/",
"type": "deb",
"namespace": "debian",
"name": "mimetex",
"version": "1.50-1.1",
"qualifiers": {"distro": "jessie"},
"subpath": "",
"purl": "pkg:deb/debian/mimetex@1.50-1.1?distro=jessie",
"resolved_vulnerabilities": [
OrderedDict(
[
Expand Down

0 comments on commit 9ab1c2f

Please sign in to comment.