Skip to content

Commit 49ff7cf

Browse files
committed
enhance VulnerabilityAnalysisSerializer with new fields
Signed-off-by: tdruez <tdruez@aboutcode.org>
1 parent 1c10771 commit 49ff7cf

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

vulnerabilities/api.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from django.db.models import Prefetch
1111

12+
import django_filters
1213
from rest_framework import serializers
1314
from rest_framework import viewsets
1415

@@ -134,6 +135,9 @@ def get_queryset(self):
134135

135136
class VulnerabilityAnalysisSerializer(DataspacedSerializer, serializers.ModelSerializer):
136137
advisory_uid = serializers.ReadOnlyField(source="vulnerability.advisory_uid")
138+
applied_by_preset = serializers.ReadOnlyField(source="applied_by_preset.name", allow_null=True)
139+
created_by = serializers.StringRelatedField()
140+
last_modified_by = serializers.StringRelatedField()
137141

138142
class Meta:
139143
model = VulnerabilityAnalysis
@@ -148,6 +152,9 @@ class Meta:
148152
"responses",
149153
"detail",
150154
"is_reachable",
155+
"applied_by_preset",
156+
"created_by",
157+
"last_modified_by",
151158
"first_issued",
152159
"last_updated",
153160
)
@@ -170,6 +177,9 @@ class Meta:
170177
class VulnerabilityAnalysisFilterSet(DataspacedAPIFilterSet):
171178
uuid = MultipleUUIDFilter()
172179
last_updated = LastModifiedDateFilter()
180+
applied_by_preset__isnull = django_filters.BooleanFilter(
181+
field_name="applied_by_preset", lookup_expr="isnull"
182+
)
173183

174184
class Meta:
175185
model = VulnerabilityAnalysis
@@ -203,5 +213,8 @@ def get_queryset(self):
203213
.select_related(
204214
"vulnerability",
205215
"product_package",
216+
"applied_by_preset",
217+
"created_by",
218+
"last_modified_by",
206219
)
207220
)

vulnerabilities/tests/test_api.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
from vulnerabilities.models import VulnerabilityAnalysis
2121
from vulnerabilities.tests import make_vulnerability
2222
from vulnerabilities.tests import make_vulnerability_analysis
23+
from vulnerabilities.triage.engine import apply_preset_for_vulnerabilities
24+
from vulnerabilities.triage.models import AnalysisPreset
25+
from vulnerabilities.triage.tests import make_analysis_preset
2326

2427

2528
class VulnerabilitiesAPITestCase(MaxQueryMixin, TestCase):
@@ -154,6 +157,49 @@ def test_api_vulnerability_analysis_detail_endpoint(self):
154157
self.assertEqual(str(analysis1.uuid), response.data["uuid"])
155158
self.assertTrue(response.data["is_reachable"])
156159

160+
def test_api_vulnerability_analysis_detail_endpoint_applied_by_preset_and_authors(self):
161+
self.client.login(username="super_user", password="secret")
162+
163+
human_analysis = make_vulnerability_analysis(
164+
self.product_package1,
165+
self.vulnerability1,
166+
created_by=self.super_user,
167+
last_modified_by=self.super_user,
168+
)
169+
detail_url = reverse("api_v2:vulnerabilityanalysis-detail", args=[human_analysis.uuid])
170+
response = self.client.get(detail_url)
171+
self.assertIsNone(response.data["applied_by_preset"])
172+
self.assertEqual(self.super_user.username, response.data["created_by"])
173+
self.assertEqual(self.super_user.username, response.data["last_modified_by"])
174+
175+
preset = make_analysis_preset(self.dataspace, state=AnalysisPreset.State.NOT_AFFECTED)
176+
apply_preset_for_vulnerabilities(preset, self.product1, [self.vulnerability2.pk])
177+
auto_analysis = VulnerabilityAnalysis.objects.get(vulnerability=self.vulnerability2)
178+
detail_url = reverse("api_v2:vulnerabilityanalysis-detail", args=[auto_analysis.uuid])
179+
180+
response = self.client.get(detail_url)
181+
self.assertEqual(preset.name, response.data["applied_by_preset"])
182+
self.assertIsNone(response.data["created_by"])
183+
self.assertIsNone(response.data["last_modified_by"])
184+
185+
def test_api_vulnerability_analysis_list_endpoint_filters_applied_by_preset(self):
186+
self.client.login(username="super_user", password="secret")
187+
make_vulnerability_analysis(self.product_package1, self.vulnerability1)
188+
preset = make_analysis_preset(self.dataspace, state=AnalysisPreset.State.NOT_AFFECTED)
189+
apply_preset_for_vulnerabilities(preset, self.product1, [self.vulnerability2.pk])
190+
191+
data = {"applied_by_preset__isnull": "true"}
192+
response = self.client.get(self.analysis_list_url, data)
193+
self.assertEqual(1, response.data["count"])
194+
self.assertContains(response, self.vulnerability1.advisory_id)
195+
self.assertNotContains(response, self.vulnerability2.advisory_id)
196+
197+
data = {"applied_by_preset__isnull": "false"}
198+
response = self.client.get(self.analysis_list_url, data)
199+
self.assertEqual(1, response.data["count"])
200+
self.assertNotContains(response, self.vulnerability1.advisory_id)
201+
self.assertContains(response, self.vulnerability2.advisory_id)
202+
157203
def test_api_vulnerability_analysis_endpoint_create(self):
158204
self.client.login(username="super_user", password="secret")
159205
response = self.client.post(self.analysis_list_url)

0 commit comments

Comments
 (0)