Skip to content

Commit bca4ad0

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 2670b03 commit bca4ad0

2 files changed

Lines changed: 73 additions & 52 deletions

File tree

vulnerabilities/api.py

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

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

6165
class Meta:
6266
model = Vulnerability
63-
fields = ["url", "vulnerability_id", "summary", "references"]
67+
fields = ["url", "vulnerability_id", "summary", "references", "fixed_packages"]
6468

6569

6670
class MinimalVulnerabilitySerializer(serializers.HyperlinkedModelSerializer):
@@ -73,21 +77,6 @@ class Meta:
7377
fields = ["url", "vulnerability_id"]
7478

7579

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

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

139167
class Meta:
140168
model = Package
@@ -148,7 +176,6 @@ class Meta:
148176
"qualifiers",
149177
"subpath",
150178
"affected_by_vulnerabilities",
151-
"fixed_packages",
152179
"fixing_vulnerabilities",
153180
]
154181

vulnerabilities/tests/test_fix_api.py

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -138,30 +138,24 @@ def test_api_with_single_vulnerability_and_fixed_package(self):
138138
"namespace": "nginx",
139139
"name": "test",
140140
"version": "11",
141-
"unresolved_vulnerabilities": [],
142141
"qualifiers": {},
143142
"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-
],
156143
"affected_by_vulnerabilities": [],
157144
"fixing_vulnerabilities": [
158145
{
159146
"url": f"http://testserver/api/vulnerabilities/{self.vuln.id}",
160147
"vulnerability_id": f"VULCOID-{int_to_base36(self.vuln.id).upper()}",
161148
"summary": "test-vuln",
162149
"references": [],
163-
}
150+
"fixed_packages": [
151+
{
152+
"url": f"http://testserver/api/packages/{self.package.id}",
153+
"purl": "pkg:generic/nginx/test@11",
154+
}
155+
],
156+
},
164157
],
158+
"unresolved_vulnerabilities": [],
165159
}
166160

167161
def test_api_with_single_vulnerability_and_vulnerable_package(self):
@@ -173,37 +167,37 @@ def test_api_with_single_vulnerability_and_vulnerable_package(self):
173167
"namespace": "nginx",
174168
"name": "test",
175169
"version": "9",
176-
"unresolved_vulnerabilities": [
170+
"qualifiers": {},
171+
"subpath": "",
172+
"affected_by_vulnerabilities": [
177173
{
178174
"url": f"http://testserver/api/vulnerabilities/{self.vuln.id}",
179175
"vulnerability_id": f"VULCOID-{int_to_base36(self.vuln.id).upper()}",
180176
"summary": "test-vuln",
181177
"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": [
178+
"fixed_packages": [
191179
{
192-
"url": f"http://testserver/api/vulnerabilities/{self.vuln.id}",
193-
"vulnerability_id": f"VULCOID-{int_to_base36(self.vuln.id).upper()}",
180+
"url": f"http://testserver/api/packages/{self.package.id}",
181+
"purl": "pkg:generic/nginx/test@11",
194182
}
195183
],
196184
}
197185
],
198-
"affected_by_vulnerabilities": [
186+
"fixing_vulnerabilities": [],
187+
"unresolved_vulnerabilities": [
199188
{
200189
"url": f"http://testserver/api/vulnerabilities/{self.vuln.id}",
201190
"vulnerability_id": f"VULCOID-{int_to_base36(self.vuln.id).upper()}",
202191
"summary": "test-vuln",
203192
"references": [],
193+
"fixed_packages": [
194+
{
195+
"url": f"http://testserver/api/packages/{self.package.id}",
196+
"purl": "pkg:generic/nginx/test@11",
197+
}
198+
],
204199
}
205200
],
206-
"fixing_vulnerabilities": [],
207201
}
208202

209203

0 commit comments

Comments
 (0)