Skip to content

Commit 9adc251

Browse files
dogboatmtesauroMaffoochvalentijnscholten
authored
prefetching locations when building dedupe candidate scope queryset (#14483)
* when building dedupe candidate scope queryset, prefetch locations differently from endpoints when using v3 * add test for build_candidate_scope_queryset when locations are enabled * Update unittests/test_deduplication_logic.py Co-authored-by: valentijnscholten <valentijnscholten@gmail.com> --------- Co-authored-by: Matt Tesauro <mtesauro@gmail.com> Co-authored-by: Cody Maffucci <46459665+Maffooch@users.noreply.github.com> Co-authored-by: valentijnscholten <valentijnscholten@gmail.com>
1 parent 0e925a1 commit 9adc251

2 files changed

Lines changed: 44 additions & 18 deletions

File tree

dojo/finding/deduplication.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -292,22 +292,26 @@ def build_candidate_scope_queryset(test, mode="deduplication", service=None):
292292
)
293293
queryset = Finding.objects.filter(scope_q)
294294

295-
# Base prefetches for both modes
296-
prefetch_list = ["endpoints", "vulnerability_id_set", "found_by"]
297-
298-
# Additional prefetches for reimport mode: fetch only non-special endpoint statuses with their
299-
# endpoint joined in, so endpoint_manager can read status_finding_non_special directly without
300-
# any extra DB queries
301-
if mode == "reimport":
302-
prefetch_list.append(
303-
Prefetch(
304-
"status_finding",
305-
queryset=Endpoint_Status.objects.exclude(
306-
Q(false_positive=True) | Q(out_of_scope=True) | Q(risk_accepted=True),
307-
).select_related("endpoint"),
308-
to_attr="status_finding_non_special",
309-
),
310-
)
295+
if settings.V3_FEATURE_LOCATIONS:
296+
prefetch_list = ["locations__location__url", "vulnerability_id_set", "found_by"]
297+
else:
298+
# TODO: Delete this after the move to Locations
299+
# Base prefetches for both modes
300+
prefetch_list = ["endpoints", "vulnerability_id_set", "found_by"]
301+
302+
# Additional prefetches for reimport mode: fetch only non-special endpoint statuses with their
303+
# endpoint joined in, so endpoint_manager can read status_finding_non_special directly without
304+
# any extra DB queries
305+
if mode == "reimport":
306+
prefetch_list.append(
307+
Prefetch(
308+
"status_finding",
309+
queryset=Endpoint_Status.objects.exclude(
310+
Q(false_positive=True) | Q(out_of_scope=True) | Q(risk_accepted=True),
311+
).select_related("endpoint"),
312+
to_attr="status_finding_non_special",
313+
),
314+
)
311315

312316
return (
313317
queryset

unittests/test_deduplication_logic.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from django.core import serializers
1010
from django.utils import timezone
1111

12-
from dojo.finding.deduplication import set_duplicate
12+
from dojo.finding.deduplication import build_candidate_scope_queryset, set_duplicate
1313
from dojo.importers.default_importer import DefaultImporter
1414
from dojo.models import (
1515
Development_Environment,
@@ -27,7 +27,12 @@
2727
)
2828
from dojo.url.models import URL
2929

30-
from .dojo_test_case import DojoTestCase, get_unit_tests_scans_path, versioned_fixtures
30+
from .dojo_test_case import (
31+
DojoTestCase,
32+
get_unit_tests_scans_path,
33+
skip_unless_v3,
34+
versioned_fixtures,
35+
)
3136

3237
logger = logging.getLogger(__name__)
3338
deduplicationLogger = logging.getLogger("dojo.specific-loggers.deduplication")
@@ -1892,3 +1897,20 @@ def enable_dedupe(self, *, enable=True):
18921897
system_settings = System_Settings.objects.get()
18931898
system_settings.enable_deduplication = enable
18941899
system_settings.save()
1900+
1901+
1902+
@versioned_fixtures
1903+
class TestDedupeRelatedMethods(DojoTestCase):
1904+
fixtures = ["dojo_testdata.json"]
1905+
1906+
@skip_unless_v3
1907+
def test_build_candidate_scope_queryset_does_not_crash_when_locations_enabled_but_endpoint_exists(self):
1908+
# Create an Endpoint and associate it with a Finding
1909+
with Endpoint.allow_endpoint_init():
1910+
endpoint = Endpoint.objects.create(host="test-host.com")
1911+
test = Test.objects.get(id=3)
1912+
finding = Finding.objects.filter(test=test).first()
1913+
finding.endpoints.add(endpoint)
1914+
# This used to explode when it tried to prefetch Endpoints when they are disabled, now fixed
1915+
finding = build_candidate_scope_queryset(test).filter(id=finding.id).first()
1916+
self.assertTrue(finding)

0 commit comments

Comments
 (0)