Skip to content

Commit d8d0e05

Browse files
committed
Add v2 API file
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent 68eff50 commit d8d0e05

3 files changed

Lines changed: 185 additions & 174 deletions

File tree

vulnerabilities/api.py

Lines changed: 0 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -690,175 +690,3 @@ class AliasViewSet(VulnerabilityViewSet):
690690
"""
691691

692692
filterset_class = AliasFilterSet
693-
694-
695-
class WeaknessV2Serializer(serializers.ModelSerializer):
696-
cwe_id = serializers.CharField()
697-
name = serializers.CharField()
698-
description = serializers.CharField()
699-
700-
class Meta:
701-
model = Weakness
702-
fields = ["cwe_id", "name", "description"]
703-
704-
705-
class VulnerabilityReferenceV2Serializer(serializers.ModelSerializer):
706-
url = serializers.CharField()
707-
reference_type = serializers.CharField()
708-
reference_id = serializers.CharField()
709-
710-
class Meta:
711-
model = VulnerabilityReference
712-
fields = ["url", "reference_type", "reference_id"]
713-
714-
715-
class VulnerabilityV2Serializer(BaseResourceSerializer):
716-
aliases = serializers.SerializerMethodField()
717-
weaknesses = WeaknessV2Serializer(many=True)
718-
references = VulnerabilityReferenceV2Serializer(many=True, source="vulnerabilityreference_set")
719-
severities = VulnerabilitySeveritySerializer(many=True)
720-
721-
class Meta:
722-
model = Vulnerability
723-
fields = [
724-
"vulnerability_id",
725-
"aliases",
726-
"summary",
727-
"severities",
728-
"weaknesses",
729-
"references",
730-
]
731-
732-
def get_aliases(self, obj):
733-
return [alias.alias for alias in obj.aliases.all()]
734-
735-
def get_severities(self, obj):
736-
return obj.severities
737-
738-
739-
class VulnerabilityListSerializer(serializers.ModelSerializer):
740-
url = serializers.SerializerMethodField()
741-
742-
class Meta:
743-
model = Vulnerability
744-
fields = ["vulnerability_id", "url"]
745-
746-
def get_url(self, obj):
747-
request = self.context.get("request")
748-
return reverse(
749-
"vulnerability-v2-detail",
750-
kwargs={"vulnerability_id": obj.vulnerability_id},
751-
request=request,
752-
)
753-
754-
755-
class VulnerabilityV2ViewSet(viewsets.ReadOnlyModelViewSet):
756-
queryset = Vulnerability.objects.all()
757-
serializer_class = VulnerabilityV2Serializer
758-
lookup_field = "vulnerability_id"
759-
760-
def get_queryset(self):
761-
queryset = super().get_queryset()
762-
vulnerability_ids = self.request.query_params.getlist("vulnerability_id")
763-
aliases = self.request.query_params.getlist("alias")
764-
765-
if vulnerability_ids:
766-
queryset = queryset.filter(vulnerability_id__in=vulnerability_ids)
767-
768-
if aliases:
769-
queryset = queryset.filter(aliases__alias__in=aliases).distinct()
770-
771-
return queryset
772-
773-
def get_serializer_class(self):
774-
if self.action == "list":
775-
return VulnerabilityListSerializer
776-
return super().get_serializer_class()
777-
778-
def list(self, request, *args, **kwargs):
779-
queryset = self.get_queryset()
780-
vulnerability_ids = request.query_params.getlist("vulnerability_id")
781-
782-
# If exactly one vulnerability_id is provided, return the serialized data
783-
if len(vulnerability_ids) == 1:
784-
try:
785-
vulnerability = queryset.get(vulnerability_id=vulnerability_ids[0])
786-
serializer = self.get_serializer(vulnerability)
787-
return Response(serializer.data)
788-
except Vulnerability.DoesNotExist:
789-
return Response({"detail": "Not found."}, status=404)
790-
791-
# Otherwise, return a dictionary of vulnerabilities keyed by vulnerability_id
792-
page = self.paginate_queryset(queryset)
793-
if page is not None:
794-
serializer = self.get_serializer(page, many=True)
795-
data = serializer.data
796-
vulnerabilities = {item["vulnerability_id"]: item for item in data}
797-
return self.get_paginated_response({"vulnerabilities": vulnerabilities})
798-
799-
serializer = self.get_serializer(queryset, many=True)
800-
data = serializer.data
801-
vulnerabilities = {item["vulnerability_id"]: item for item in data}
802-
return Response({"vulnerabilities": vulnerabilities})
803-
804-
805-
class PackageV2Serializer(serializers.ModelSerializer):
806-
purl = serializers.CharField(source="package_url")
807-
affected_by_vulnerabilities = serializers.SerializerMethodField()
808-
fixing_vulnerabilities = serializers.SerializerMethodField()
809-
next_non_vulnerable_version = serializers.CharField(read_only=True)
810-
latest_non_vulnerable_version = serializers.CharField(read_only=True)
811-
812-
class Meta:
813-
model = Package
814-
fields = [
815-
"purl",
816-
"affected_by_vulnerabilities",
817-
"fixing_vulnerabilities",
818-
"next_non_vulnerable_version",
819-
"latest_non_vulnerable_version",
820-
]
821-
822-
def get_affected_by_vulnerabilities(self, obj):
823-
return [vuln.vulnerability_id for vuln in obj.affected_by_vulnerabilities.all()]
824-
825-
def get_fixing_vulnerabilities(self, obj):
826-
return [vuln.vulnerability_id for vuln in obj.fixing_vulnerabilities.all()]
827-
828-
829-
class PackageV2ViewSet(viewsets.ReadOnlyModelViewSet):
830-
queryset = Package.objects.all()
831-
serializer_class = PackageV2Serializer
832-
833-
def get_queryset(self):
834-
queryset = super().get_queryset()
835-
package_purls = self.request.query_params.getlist("purl")
836-
affected_by_vulnerability = self.request.query_params.get("affected_by_vulnerability")
837-
fixing_vulnerability = self.request.query_params.get("fixing_vulnerability")
838-
839-
if package_purls:
840-
queryset = queryset.filter(package_url__in=package_purls)
841-
if affected_by_vulnerability:
842-
queryset = queryset.filter(
843-
affected_by_vulnerabilities__vulnerability_id=affected_by_vulnerability
844-
)
845-
if fixing_vulnerability:
846-
queryset = queryset.filter(
847-
fixing_vulnerabilities__vulnerability_id=fixing_vulnerability
848-
)
849-
return queryset.with_is_vulnerable()
850-
851-
def list(self, request, *args, **kwargs):
852-
queryset = self.get_queryset()
853-
# Apply pagination
854-
page = self.paginate_queryset(queryset)
855-
if page is not None:
856-
serializer = self.get_serializer(page, many=True)
857-
data = serializer.data
858-
# Use 'self.get_paginated_response' to include pagination data
859-
return self.get_paginated_response({"purls": data})
860-
861-
# If pagination is not applied
862-
serializer = self.get_serializer(queryset, many=True)
863-
data = serializer.data
864-
return Response({"purls": data})

vulnerabilities/v2_api.py

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
from rest_framework import serializers
2+
from rest_framework import viewsets
3+
from rest_framework.response import Response
4+
from rest_framework.reverse import reverse
5+
6+
from vulnerabilities.models import Package
7+
from vulnerabilities.models import Vulnerability
8+
from vulnerabilities.models import VulnerabilityReference
9+
from vulnerabilities.models import Weakness
10+
from vulnerabilities.models import VulnerabilitySeverity
11+
12+
from vulnerabilities.api import VulnerabilitySeveritySerializer
13+
14+
class WeaknessV2Serializer(serializers.ModelSerializer):
15+
cwe_id = serializers.CharField()
16+
name = serializers.CharField()
17+
description = serializers.CharField()
18+
19+
class Meta:
20+
model = Weakness
21+
fields = ["cwe_id", "name", "description"]
22+
23+
24+
class VulnerabilityReferenceV2Serializer(serializers.ModelSerializer):
25+
url = serializers.CharField()
26+
reference_type = serializers.CharField()
27+
reference_id = serializers.CharField()
28+
29+
class Meta:
30+
model = VulnerabilityReference
31+
fields = ["url", "reference_type", "reference_id"]
32+
33+
34+
class VulnerabilityV2Serializer(serializers.ModelSerializer):
35+
aliases = serializers.SerializerMethodField()
36+
weaknesses = WeaknessV2Serializer(many=True)
37+
references = VulnerabilityReferenceV2Serializer(many=True, source="vulnerabilityreference_set")
38+
severities = VulnerabilitySeveritySerializer(many=True)
39+
40+
class Meta:
41+
model = Vulnerability
42+
fields = [
43+
"vulnerability_id",
44+
"aliases",
45+
"summary",
46+
"severities",
47+
"weaknesses",
48+
"references",
49+
]
50+
51+
def get_aliases(self, obj):
52+
return [alias.alias for alias in obj.aliases.all()]
53+
54+
def get_severities(self, obj):
55+
return obj.severities
56+
57+
58+
class VulnerabilityListSerializer(serializers.ModelSerializer):
59+
url = serializers.SerializerMethodField()
60+
61+
class Meta:
62+
model = Vulnerability
63+
fields = ["vulnerability_id", "url"]
64+
65+
def get_url(self, obj):
66+
request = self.context.get("request")
67+
return reverse(
68+
"vulnerability-v2-detail",
69+
kwargs={"vulnerability_id": obj.vulnerability_id},
70+
request=request,
71+
)
72+
73+
74+
class VulnerabilityV2ViewSet(viewsets.ReadOnlyModelViewSet):
75+
queryset = Vulnerability.objects.all()
76+
serializer_class = VulnerabilityV2Serializer
77+
lookup_field = "vulnerability_id"
78+
79+
def get_queryset(self):
80+
queryset = super().get_queryset()
81+
vulnerability_ids = self.request.query_params.getlist("vulnerability_id")
82+
aliases = self.request.query_params.getlist("alias")
83+
84+
if vulnerability_ids:
85+
queryset = queryset.filter(vulnerability_id__in=vulnerability_ids)
86+
87+
if aliases:
88+
queryset = queryset.filter(aliases__alias__in=aliases).distinct()
89+
90+
return queryset
91+
92+
def get_serializer_class(self):
93+
if self.action == "list":
94+
return VulnerabilityListSerializer
95+
return super().get_serializer_class()
96+
97+
def list(self, request, *args, **kwargs):
98+
queryset = self.get_queryset()
99+
vulnerability_ids = request.query_params.getlist("vulnerability_id")
100+
101+
# If exactly one vulnerability_id is provided, return the serialized data
102+
if len(vulnerability_ids) == 1:
103+
try:
104+
vulnerability = queryset.get(vulnerability_id=vulnerability_ids[0])
105+
serializer = self.get_serializer(vulnerability)
106+
return Response(serializer.data)
107+
except Vulnerability.DoesNotExist:
108+
return Response({"detail": "Not found."}, status=404)
109+
110+
# Otherwise, return a dictionary of vulnerabilities keyed by vulnerability_id
111+
page = self.paginate_queryset(queryset)
112+
if page is not None:
113+
serializer = self.get_serializer(page, many=True)
114+
data = serializer.data
115+
vulnerabilities = {item["vulnerability_id"]: item for item in data}
116+
return self.get_paginated_response({"vulnerabilities": vulnerabilities})
117+
118+
serializer = self.get_serializer(queryset, many=True)
119+
data = serializer.data
120+
vulnerabilities = {item["vulnerability_id"]: item for item in data}
121+
return Response({"vulnerabilities": vulnerabilities})
122+
123+
124+
class PackageV2Serializer(serializers.ModelSerializer):
125+
purl = serializers.CharField(source="package_url")
126+
affected_by_vulnerabilities = serializers.SerializerMethodField()
127+
fixing_vulnerabilities = serializers.SerializerMethodField()
128+
next_non_vulnerable_version = serializers.CharField(read_only=True)
129+
latest_non_vulnerable_version = serializers.CharField(read_only=True)
130+
131+
class Meta:
132+
model = Package
133+
fields = [
134+
"purl",
135+
"affected_by_vulnerabilities",
136+
"fixing_vulnerabilities",
137+
"next_non_vulnerable_version",
138+
"latest_non_vulnerable_version",
139+
]
140+
141+
def get_affected_by_vulnerabilities(self, obj):
142+
return [vuln.vulnerability_id for vuln in obj.affected_by_vulnerabilities.all()]
143+
144+
def get_fixing_vulnerabilities(self, obj):
145+
return [vuln.vulnerability_id for vuln in obj.fixing_vulnerabilities.all()]
146+
147+
148+
class PackageV2ViewSet(viewsets.ReadOnlyModelViewSet):
149+
queryset = Package.objects.all()
150+
serializer_class = PackageV2Serializer
151+
152+
def get_queryset(self):
153+
queryset = super().get_queryset()
154+
package_purls = self.request.query_params.getlist("purl")
155+
affected_by_vulnerability = self.request.query_params.get("affected_by_vulnerability")
156+
fixing_vulnerability = self.request.query_params.get("fixing_vulnerability")
157+
158+
if package_purls:
159+
queryset = queryset.filter(package_url__in=package_purls)
160+
if affected_by_vulnerability:
161+
queryset = queryset.filter(
162+
affected_by_vulnerabilities__vulnerability_id=affected_by_vulnerability
163+
)
164+
if fixing_vulnerability:
165+
queryset = queryset.filter(
166+
fixing_vulnerabilities__vulnerability_id=fixing_vulnerability
167+
)
168+
return queryset.with_is_vulnerable()
169+
170+
def list(self, request, *args, **kwargs):
171+
queryset = self.get_queryset()
172+
# Apply pagination
173+
page = self.paginate_queryset(queryset)
174+
if page is not None:
175+
serializer = self.get_serializer(page, many=True)
176+
data = serializer.data
177+
# Use 'self.get_paginated_response' to include pagination data
178+
return self.get_paginated_response({"purls": data})
179+
180+
# If pagination is not applied
181+
serializer = self.get_serializer(queryset, many=True)
182+
data = serializer.data
183+
return Response({"purls": data})

vulnerablecode/urls.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
from vulnerabilities.api import AliasViewSet
2020
from vulnerabilities.api import CPEViewSet
21-
from vulnerabilities.api import PackageV2ViewSet
21+
from vulnerabilities.v2_api import PackageV2ViewSet
2222
from vulnerabilities.api import PackageViewSet
23-
from vulnerabilities.api import VulnerabilityV2ViewSet
23+
from vulnerabilities.v2_api import VulnerabilityV2ViewSet
2424
from vulnerabilities.api import VulnerabilityViewSet
2525
from vulnerabilities.views import ApiUserCreateView
2626
from vulnerabilities.views import HomePage

0 commit comments

Comments
 (0)