Skip to content

Commit 92cd890

Browse files
Maffoochclaude
andcommitted
Use ID-based comparisons and add engagement_name check to import
- Switch permission checks to use ID comparisons (product_id, engagement_id) where resolved objects are available, with name fallback for unresolved cases - Add engagement_name validation to UserHasImportPermission (was missing) - Fix ruff string quoting in auto_create_context.py Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 985e0b8 commit 92cd890

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

dojo/api_v2/permissions.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,12 @@ def has_permission(self, request, view):
473473
# Raise an explicit drf exception here
474474
raise ValidationError(e)
475475
if engagement := converted_dict.get("engagement"):
476-
# Validate the resolved engagement's parent chain matches any provided names
477-
if (product_name := converted_dict.get("product_name")) and engagement.product.name != product_name:
478-
msg = f'The resolved engagement is associated with product "{engagement.product.name}", not with product "{product_name}"'
476+
# Validate the resolved engagement's parent chain matches any provided identifiers
477+
if (product := converted_dict.get("product")) and engagement.product_id != product.id:
478+
msg = f'The resolved engagement is associated with product "{engagement.product.name}", not with product "{converted_dict.get("product_name")}"'
479+
raise ValidationError(msg)
480+
if (engagement_name := converted_dict.get("engagement_name")) and engagement.name != engagement_name:
481+
msg = f'The resolved engagement is named "{engagement.name}", not "{engagement_name}"'
479482
raise ValidationError(msg)
480483
return user_has_permission(
481484
request.user, engagement, Permissions.Import_Scan_Result,
@@ -777,11 +780,18 @@ def has_permission(self, request, view):
777780
raise ValidationError(e)
778781

779782
if test := converted_dict.get("test"):
780-
# Validate the resolved test's parent chain matches any provided names
781-
if (product_name := converted_dict.get("product_name")) and test.engagement.product.name != product_name:
783+
# Validate the resolved test's parent chain matches any provided identifiers
784+
if (product := converted_dict.get("product")) and test.engagement.product_id != product.id:
785+
msg = f'The resolved test is associated with product "{test.engagement.product.name}", not with product "{converted_dict.get("product_name")}"'
786+
raise ValidationError(msg)
787+
if (engagement := converted_dict.get("engagement")) and test.engagement_id != engagement.id:
788+
msg = f'The resolved test is associated with engagement "{test.engagement.name}", not with engagement "{converted_dict.get("engagement_name")}"'
789+
raise ValidationError(msg)
790+
# Also validate by name when the objects were not resolved (e.g. names that match no existing record)
791+
if not converted_dict.get("product") and (product_name := converted_dict.get("product_name")) and test.engagement.product.name != product_name:
782792
msg = f'The resolved test is associated with product "{test.engagement.product.name}", not with product "{product_name}"'
783793
raise ValidationError(msg)
784-
if (engagement_name := converted_dict.get("engagement_name")) and test.engagement.name != engagement_name:
794+
if not converted_dict.get("engagement") and (engagement_name := converted_dict.get("engagement_name")) and test.engagement.name != engagement_name:
785795
msg = f'The resolved test is associated with engagement "{test.engagement.name}", not with engagement "{engagement_name}"'
786796
raise ValidationError(msg)
787797
return user_has_permission(

dojo/importers/auto_create_context.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def get_target_engagement_if_exists(
182182
if engagement := get_object_or_none(Engagement, pk=engagement_id):
183183
logger.debug("Using existing engagement by id: %s", engagement_id)
184184
if product is not None and engagement.product_id != product.id:
185-
msg = f"Engagement \"{engagement_id}\" does not belong to product \"{product}\""
185+
msg = f'Engagement "{engagement_id}" does not belong to product "{product}"'
186186
raise ValueError(msg)
187187
return engagement
188188
# if there's no product, then for sure there's no engagement either
@@ -207,7 +207,7 @@ def get_target_test_if_exists(
207207
if test := get_object_or_none(Test, pk=test_id):
208208
logger.debug("Using existing Test by id: %s", test_id)
209209
if engagement is not None and test.engagement_id != engagement.id:
210-
msg = f"Test \"{test_id}\" does not belong to engagement \"{engagement}\""
210+
msg = f'Test "{test_id}" does not belong to engagement "{engagement}"'
211211
raise ValueError(msg)
212212
return test
213213
# If the engagement is not supplied, we cannot do anything

0 commit comments

Comments
 (0)