Skip to content

Commit 849e605

Browse files
committed
Add v2 API file
Signed-off-by: Tushar Goel <[email protected]>
1 parent 9165710 commit 849e605

File tree

3 files changed

+185
-174
lines changed

3 files changed

+185
-174
lines changed

vulnerabilities/api.py

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

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