Skip to content

Commit a029347

Browse files
committed
Move fixed_packages to vulnerabilities in packages endpoint #809
Reference: #809 Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent 6899c27 commit a029347

2 files changed

Lines changed: 75 additions & 52 deletions

File tree

vulnerabilities/api.py

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,15 @@ class VulnSerializerRefsAndSummary(serializers.HyperlinkedModelSerializer):
5757
Used for nesting inside package focused APIs.
5858
"""
5959

60+
fixed_packages = MinimalPackageSerializer(
61+
many=True, source="filtered_fixed_packages", read_only=True
62+
)
63+
6064
references = VulnerabilityReferenceSerializer(many=True, source="vulnerabilityreference_set")
6165

6266
class Meta:
6367
model = Vulnerability
64-
fields = ["url", "vulnerability_id", "summary", "references"]
68+
fields = ["url", "vulnerability_id", "summary", "references", "fixed_packages"]
6569

6670

6771
class MinimalVulnerabilitySerializer(serializers.HyperlinkedModelSerializer):
@@ -74,21 +78,6 @@ class Meta:
7478
fields = ["url", "vulnerability_id"]
7579

7680

77-
class PackageSerializerFixedVulns(serializers.HyperlinkedModelSerializer):
78-
"""
79-
Used for nesting inside vulnerability focused APIs.
80-
"""
81-
82-
purl = serializers.CharField(source="package_url")
83-
fixing_vulnerabilities = MinimalVulnerabilitySerializer(
84-
many=True, source="resolved_to", read_only=True
85-
)
86-
87-
class Meta:
88-
model = Package
89-
fields = ["url", "purl", "fixing_vulnerabilities"]
90-
91-
9281
class AliasSerializer(serializers.HyperlinkedModelSerializer):
9382
"""
9483
Used for nesting inside package focused APIs.
@@ -129,13 +118,52 @@ def to_representation(self, instance):
129118
return data
130119

131120
purl = serializers.CharField(source="package_url")
132-
affected_by_vulnerabilities = VulnSerializerRefsAndSummary(
133-
many=True, source="vulnerable_to", read_only=True
134-
)
135-
fixing_vulnerabilities = VulnSerializerRefsAndSummary(
136-
many=True, source="resolved_to", read_only=True
137-
)
138-
fixed_packages = PackageSerializerFixedVulns(many=True, read_only=True)
121+
122+
affected_by_vulnerabilities = serializers.SerializerMethodField("get_affected_vulnerabilities")
123+
124+
fixing_vulnerabilities = serializers.SerializerMethodField("get_fixed_vulnerabilities")
125+
126+
def get_fixed_packages(self, package):
127+
return Package.objects.filter(
128+
name=package.name,
129+
namespace=package.namespace,
130+
type=package.type,
131+
qualifiers=package.qualifiers,
132+
subpath=package.subpath,
133+
packagerelatedvulnerability__fix=True,
134+
).distinct()
135+
136+
def get_affected_vulnerabilities(self, package):
137+
fixed_packages = self.get_fixed_packages(package=package)
138+
qs = package.vulnerabilities.filter(packagerelatedvulnerability__fix=False)
139+
qs = qs.prefetch_related(
140+
Prefetch(
141+
"packages",
142+
queryset=fixed_packages,
143+
to_attr="filtered_fixed_packages",
144+
)
145+
)
146+
return VulnSerializerRefsAndSummary(
147+
instance=qs,
148+
many=True,
149+
context={"request": self.context["request"]},
150+
).data
151+
152+
def get_fixed_vulnerabilities(self, package):
153+
fixed_packages = self.get_fixed_packages(package=package)
154+
qs = package.vulnerabilities.filter(packagerelatedvulnerability__fix=True)
155+
qs = qs.prefetch_related(
156+
Prefetch(
157+
"packages",
158+
queryset=fixed_packages,
159+
to_attr="filtered_fixed_packages",
160+
)
161+
)
162+
return VulnSerializerRefsAndSummary(
163+
instance=qs,
164+
many=True,
165+
context={"request": self.context["request"]},
166+
).data
139167

140168
class Meta:
141169
model = Package
@@ -149,7 +177,6 @@ class Meta:
149177
"qualifiers",
150178
"subpath",
151179
"affected_by_vulnerabilities",
152-
"fixed_packages",
153180
"fixing_vulnerabilities",
154181
]
155182

vulnerabilities/tests/test_fix_api.py

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
# See https://aboutcode.org for more information about nexB OSS projects.
88
#
99

10+
from collections import OrderedDict
11+
1012
from django.test import TestCase
1113
from django.utils.http import int_to_base36
1214
from rest_framework import status
@@ -138,30 +140,24 @@ def test_api_with_single_vulnerability_and_fixed_package(self):
138140
"namespace": "nginx",
139141
"name": "test",
140142
"version": "11",
141-
"unresolved_vulnerabilities": [],
142143
"qualifiers": {},
143144
"subpath": "",
144-
"fixed_packages": [
145-
{
146-
"url": f"http://testserver/api/packages/{self.package.id}",
147-
"purl": "pkg:generic/nginx/test@11",
148-
"fixing_vulnerabilities": [
149-
{
150-
"url": f"http://testserver/api/vulnerabilities/{self.vuln.id}",
151-
"vulnerability_id": f"VULCOID-{int_to_base36(self.vuln.id).upper()}",
152-
}
153-
],
154-
}
155-
],
156145
"affected_by_vulnerabilities": [],
157146
"fixing_vulnerabilities": [
158147
{
159148
"url": f"http://testserver/api/vulnerabilities/{self.vuln.id}",
160149
"vulnerability_id": f"VULCOID-{int_to_base36(self.vuln.id).upper()}",
161150
"summary": "test-vuln",
162151
"references": [],
163-
}
152+
"fixed_packages": [
153+
{
154+
"url": f"http://testserver/api/packages/{self.package.id}",
155+
"purl": "pkg:generic/nginx/test@11",
156+
}
157+
],
158+
},
164159
],
160+
"unresolved_vulnerabilities": [],
165161
}
166162

167163
def test_api_with_single_vulnerability_and_vulnerable_package(self):
@@ -173,37 +169,37 @@ def test_api_with_single_vulnerability_and_vulnerable_package(self):
173169
"namespace": "nginx",
174170
"name": "test",
175171
"version": "9",
176-
"unresolved_vulnerabilities": [
172+
"qualifiers": {},
173+
"subpath": "",
174+
"affected_by_vulnerabilities": [
177175
{
178176
"url": f"http://testserver/api/vulnerabilities/{self.vuln.id}",
179177
"vulnerability_id": f"VULCOID-{int_to_base36(self.vuln.id).upper()}",
180178
"summary": "test-vuln",
181179
"references": [],
182-
}
183-
],
184-
"qualifiers": {},
185-
"subpath": "",
186-
"fixed_packages": [
187-
{
188-
"url": f"http://testserver/api/packages/{self.package.id}",
189-
"purl": "pkg:generic/nginx/test@11",
190-
"fixing_vulnerabilities": [
180+
"fixed_packages": [
191181
{
192-
"url": f"http://testserver/api/vulnerabilities/{self.vuln.id}",
193-
"vulnerability_id": f"VULCOID-{int_to_base36(self.vuln.id).upper()}",
182+
"url": f"http://testserver/api/packages/{self.package.id}",
183+
"purl": "pkg:generic/nginx/test@11",
194184
}
195185
],
196186
}
197187
],
198-
"affected_by_vulnerabilities": [
188+
"fixing_vulnerabilities": [],
189+
"unresolved_vulnerabilities": [
199190
{
200191
"url": f"http://testserver/api/vulnerabilities/{self.vuln.id}",
201192
"vulnerability_id": f"VULCOID-{int_to_base36(self.vuln.id).upper()}",
202193
"summary": "test-vuln",
203194
"references": [],
195+
"fixed_packages": [
196+
{
197+
"url": f"http://testserver/api/packages/{self.package.id}",
198+
"purl": "pkg:generic/nginx/test@11",
199+
}
200+
],
204201
}
205202
],
206-
"fixing_vulnerabilities": [],
207203
}
208204

209205

0 commit comments

Comments
 (0)