Skip to content

Commit

Permalink
Add V2 API endpoints
Browse files Browse the repository at this point in the history
Reference: #1572
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
  • Loading branch information
TG1999 committed Oct 28, 2024
1 parent 590c91a commit d5baac8
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
109 changes: 109 additions & 0 deletions vulnerabilities/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,3 +690,112 @@ class AliasViewSet(VulnerabilityViewSet):
"""

filterset_class = AliasFilterSet

class WeaknessV2Serializer(serializers.ModelSerializer):
cwe_id = serializers.CharField()
name = serializers.CharField()
description = serializers.CharField()

class Meta:
model = Weakness
fields = ["cwe_id", "name", "description"]


class VulnerabilityReferenceV2Serializer(serializers.ModelSerializer):
url = serializers.CharField()
reference_type = serializers.CharField()
reference_id = serializers.CharField()

class Meta:
model = VulnerabilityReference
fields = ["url", "reference_type", "reference_id"]

class VulnerabilityV2Serializer(serializers.ModelSerializer):
aliases = serializers.SerializerMethodField()
severities = serializers.SerializerMethodField()
weaknesses = WeaknessV2Serializer(many=True)
references = VulnerabilityReferenceV2Serializer(many=True, source='vulnerabilityreference_set')

class Meta:
model = Vulnerability
fields = [
"vulnerability_id",
"aliases",
"summary",
"severities",
"weaknesses",
"references",
]

def get_aliases(self, obj):
return [alias.alias for alias in obj.aliases.all()]

def get_severities(self, obj):
#TODO: Need data model changes
return []


class VulnerabilityV2ViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Vulnerability.objects.all()
serializer_class = VulnerabilityV2Serializer

def list(self, request, *args, **kwargs):
queryset = self.get_queryset()
# Apply pagination
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
data = serializer.data
vulnerabilities = {item['vulnerability_id']: item for item in data}
# Use 'self.get_paginated_response' to include pagination data
return self.get_paginated_response({'vulnerabilities': vulnerabilities})

# If pagination is not applied
serializer = self.get_serializer(queryset, many=True)
data = serializer.data
vulnerabilities = {item['vulnerability_id']: item for item in data}
return Response({'vulnerabilities': vulnerabilities})


class PackageV2Serializer(serializers.ModelSerializer):
purl = serializers.CharField(source='package_url')
affected_by_vulnerabilities = serializers.SerializerMethodField()
fixing_vulnerabilities = serializers.SerializerMethodField()
next_non_vulnerable_version = serializers.CharField(read_only=True)
latest_non_vulnerable_version = serializers.CharField(read_only=True)

class Meta:
model = Package
fields = [
'purl',
'affected_by_vulnerabilities',
'fixing_vulnerabilities',
'next_non_vulnerable_version',
'latest_non_vulnerable_version',
]

def get_affected_by_vulnerabilities(self, obj):
return [vuln.vulnerability_id for vuln in obj.affected_by_vulnerabilities.all()]

def get_fixing_vulnerabilities(self, obj):
return [vuln.vulnerability_id for vuln in obj.fixing_vulnerabilities.all()]


class PackageV2ViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Package.objects.all()
serializer_class = PackageV2Serializer

def list(self, request, *args, **kwargs):
queryset = self.get_queryset().with_is_vulnerable()
# Apply pagination
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
data = serializer.data
# Use 'self.get_paginated_response' to include pagination data
return self.get_paginated_response({'purls': data})

# If pagination is not applied
serializer = self.get_serializer(queryset, many=True)
data = serializer.data
return Response({'purls': data})
7 changes: 7 additions & 0 deletions vulnerablecode/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
from vulnerabilities.api import CPEViewSet
from vulnerabilities.api import PackageViewSet
from vulnerabilities.api import VulnerabilityViewSet
from vulnerabilities.api import PackageV2ViewSet
from vulnerabilities.api import VulnerabilityV2ViewSet
from vulnerabilities.views import ApiUserCreateView
from vulnerabilities.views import HomePage
from vulnerabilities.views import PackageDetails
Expand All @@ -43,6 +45,10 @@ def __init__(self, *args, **kwargs):
api_router.register("cpes", CPEViewSet, basename="cpe")
api_router.register("aliases", AliasViewSet, basename="alias")

api_v2_router = OptionalSlashRouter()
api_v2_router.register("vulnerabilities", VulnerabilityV2ViewSet, basename="vulnerability-v2")
api_v2_router.register("packages", PackageV2ViewSet, basename="package-v2")

urlpatterns = [
path(
"robots.txt",
Expand Down Expand Up @@ -98,6 +104,7 @@ def __init__(self, *args, **kwargs):
TemplateView.as_view(template_name="tos.html"),
name="api_tos",
),
path('api/v2/', include(api_v2_router.urls)),
path(
"admin/",
admin.site.urls,
Expand Down

0 comments on commit d5baac8

Please sign in to comment.