Skip to content

Commit 56642f9

Browse files
Fix: Apply tags to findings/endpoints when TRACK_IMPORT_HISTORY is disabled (#13969)
Fixes #13312 When TRACK_IMPORT_HISTORY is disabled, tags were not being applied to findings and endpoints during import because the tag application logic was inside update_import_history() which returned early. Refactored to: - Extract tag application into dedicated apply_import_tags() method - Call apply_import_tags() from importers after update_import_history() - Remove tag application logic from update_import_history() This ensures tags are applied regardless of TRACK_IMPORT_HISTORY setting while maintaining separation of concerns.
1 parent 0c4bf3f commit 56642f9

3 files changed

Lines changed: 79 additions & 31 deletions

File tree

dojo/importers/base_importer.py

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import base64
22
import logging
33
import time
4+
from collections.abc import Iterable
45

56
from celery import chord, group
67
from django.conf import settings
@@ -335,6 +336,71 @@ def update_test_tags(self):
335336
if self.tags is not None and len(self.tags) > 0:
336337
self.test.tags.set(self.tags)
337338

339+
def apply_import_tags(
340+
self,
341+
new_findings: Iterable[Finding] | None = None,
342+
closed_findings: Iterable[Finding] | None = None,
343+
reactivated_findings: Iterable[Finding] | None = None,
344+
untouched_findings: Iterable[Finding] | None = None,
345+
) -> None:
346+
"""Apply tags to findings and endpoints from an import operation."""
347+
# Normalize None values to empty lists and convert sets/other iterables to lists
348+
if untouched_findings is None:
349+
untouched_findings = []
350+
elif not isinstance(untouched_findings, list):
351+
untouched_findings = list(untouched_findings)
352+
353+
if reactivated_findings is None:
354+
reactivated_findings = []
355+
elif not isinstance(reactivated_findings, list):
356+
reactivated_findings = list(reactivated_findings)
357+
358+
if closed_findings is None:
359+
closed_findings = []
360+
elif not isinstance(closed_findings, list):
361+
closed_findings = list(closed_findings)
362+
363+
if new_findings is None:
364+
new_findings = []
365+
elif not isinstance(new_findings, list):
366+
new_findings = list(new_findings)
367+
368+
# Collect all affected findings
369+
findings_to_tag = new_findings + closed_findings + reactivated_findings + untouched_findings
370+
371+
if not findings_to_tag:
372+
return
373+
374+
# Add any tags to the findings imported if necessary
375+
if self.apply_tags_to_findings and self.tags:
376+
findings_qs = Finding.objects.filter(id__in=[f.id for f in findings_to_tag])
377+
try:
378+
bulk_add_tags_to_instances(
379+
tag_or_tags=self.tags,
380+
instances=findings_qs,
381+
tag_field_name="tags",
382+
)
383+
except IntegrityError:
384+
# Fallback to safe per-instance tagging if concurrent deletes occur
385+
for finding in findings_to_tag:
386+
for tag in self.tags:
387+
self.add_tags_safe(finding, tag)
388+
389+
# Add any tags to any endpoints of the findings imported if necessary
390+
if self.apply_tags_to_endpoints and self.tags:
391+
endpoints_qs = Endpoint.objects.filter(finding__in=findings_to_tag).distinct()
392+
try:
393+
bulk_add_tags_to_instances(
394+
tag_or_tags=self.tags,
395+
instances=endpoints_qs,
396+
tag_field_name="tags",
397+
)
398+
except IntegrityError:
399+
for finding in findings_to_tag:
400+
for endpoint in finding.endpoints.all():
401+
for tag in self.tags:
402+
self.add_tags_safe(endpoint, tag)
403+
338404
def update_import_history(
339405
self,
340406
new_findings: list[Finding] | None = None,
@@ -355,6 +421,7 @@ def update_import_history(
355421
closed_findings = []
356422
if new_findings is None:
357423
new_findings = []
424+
358425
# Log the current state of what has occurred in case there could be
359426
# deviation from what is displayed in the view
360427
logger.debug(
@@ -430,37 +497,6 @@ def update_import_history(
430497
for record in import_history_records:
431498
self.create_import_history_record_safe(record)
432499

433-
# Add any tags to the findings imported if necessary
434-
if self.apply_tags_to_findings and self.tags:
435-
findings_qs = test_import.findings_affected.all()
436-
try:
437-
bulk_add_tags_to_instances(
438-
tag_or_tags=self.tags,
439-
instances=findings_qs,
440-
tag_field_name="tags",
441-
)
442-
except IntegrityError:
443-
# Fallback to safe per-instance tagging if concurrent deletes occur
444-
for finding in findings_qs:
445-
for tag in self.tags:
446-
self.add_tags_safe(finding, tag)
447-
448-
# Add any tags to any endpoints of the findings imported if necessary
449-
if self.apply_tags_to_endpoints and self.tags:
450-
# Collect all endpoints linked to the affected findings
451-
endpoints_qs = Endpoint.objects.filter(finding__in=test_import.findings_affected.all()).distinct()
452-
try:
453-
bulk_add_tags_to_instances(
454-
tag_or_tags=self.tags,
455-
instances=endpoints_qs,
456-
tag_field_name="tags",
457-
)
458-
except IntegrityError:
459-
for finding in test_import.findings_affected.all():
460-
for endpoint in finding.endpoints.all():
461-
for tag in self.tags:
462-
self.add_tags_safe(endpoint, tag)
463-
464500
return test_import
465501

466502
def create_import_history_record_safe(

dojo/importers/default_importer.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ def process_scan(
129129
new_findings=new_findings,
130130
closed_findings=closed_findings,
131131
)
132+
# Apply tags to findings and endpoints
133+
self.apply_import_tags(
134+
new_findings=new_findings,
135+
closed_findings=closed_findings,
136+
)
132137
# Send out some notifications to the user
133138
logger.debug("IMPORT_SCAN: Generating notifications")
134139
create_notification(

dojo/importers/default_reimporter.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ def process_scan(
132132
reactivated_findings=reactivated_findings,
133133
untouched_findings=untouched_findings,
134134
)
135+
# Apply tags to findings and endpoints
136+
self.apply_import_tags(
137+
new_findings=new_findings,
138+
closed_findings=closed_findings,
139+
reactivated_findings=reactivated_findings,
140+
untouched_findings=untouched_findings,
141+
)
135142
# Send out som notifications to the user
136143
logger.debug("REIMPORT_SCAN: Generating notifications")
137144
updated_count = (

0 commit comments

Comments
 (0)