Skip to content

Commit

Permalink
Verified Status Toggle: Add Granularity
Browse files Browse the repository at this point in the history
  • Loading branch information
Maffooch committed Jan 10, 2025
1 parent 600eccc commit cef1c09
Show file tree
Hide file tree
Showing 52 changed files with 29,375 additions and 25,419 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 5.1.4 on 2025-01-10 16:01

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dojo', '0218_system_settings_enforce_verified_status_and_more'),
]

operations = [
migrations.AddField(
model_name='system_settings',
name='enforce_verified_status_jira',
field=models.BooleanField(default=True, help_text='When enabled, findings must have a verified status to be pushed to jira.', verbose_name='Enforce Verified Status - Jira'),
),
migrations.AddField(
model_name='system_settings',
name='enforce_verified_status_metrics',
field=models.BooleanField(default=True, help_text='When enabled, findings must have a verified status to be counted in metric calculations, be included in reports, and filters.', verbose_name='Enforce Verified Status - Metrics'),
),
migrations.AddField(
model_name='system_settings',
name='enforce_verified_status_product_grading',
field=models.BooleanField(default=True, help_text="When enabled, findings must have a verified status to be considered as part of a product's grading.", verbose_name='Enforce Verified Status - Product Grading'),
),
migrations.AlterField(
model_name='system_settings',
name='enforce_verified_status',
field=models.BooleanField(default=True, help_text='When enabled, features such as product grading, jira integration, metrics, and reports will only interact with verified findings. This setting will override individually scoped verified toggles.', verbose_name='Enforce Verified Status - Globally'),
),
]
10 changes: 9 additions & 1 deletion dojo/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3076,7 +3076,15 @@ def clean(self):
elif self.cleaned_data.get("push_to_jira", None):
active = self.finding_form["active"].value()
verified = self.finding_form["verified"].value()
if not active or (not verified and get_system_setting("enforce_verified_status", True)):
print("\n\nJIRAFindingForm(clean)")

Check failure on line 3079 in dojo/forms.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (T201)

dojo/forms.py:3079:13: T201 `print` found
print(f"active: {active} - {type(active)}")

Check failure on line 3080 in dojo/forms.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (T201)

dojo/forms.py:3080:13: T201 `print` found
print(f"verified: {verified} - {type(verified)}")

Check failure on line 3081 in dojo/forms.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (T201)

dojo/forms.py:3081:13: T201 `print` found
print(f'get_system_setting("enforce_verified_status", True): {get_system_setting("enforce_verified_status", True)} - {type(get_system_setting("enforce_verified_status", True))}')

Check failure on line 3082 in dojo/forms.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (T201)

dojo/forms.py:3082:13: T201 `print` found
print(f'get_system_setting("enforce_verified_status_jira", True): {get_system_setting("enforce_verified_status_jira", True)} - {type(get_system_setting("enforce_verified_status_jira", True))}')

Check failure on line 3083 in dojo/forms.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (T201)

dojo/forms.py:3083:13: T201 `print` found
print(f'(get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True)): {(get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True))} - {type((get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True)))}')

Check failure on line 3084 in dojo/forms.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (T201)

dojo/forms.py:3084:13: T201 `print` found

Check failure on line 3084 in dojo/forms.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (UP034)

dojo/forms.py:3084:260: UP034 Avoid extraneous parentheses
print(f'not active or (not verified and (get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True))): {not active or (not verified and (get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True)))} - {type(not active or (not verified and (get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True))))}')

Check failure on line 3085 in dojo/forms.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (T201)

dojo/forms.py:3085:13: T201 `print` found
print("\n\n")

Check failure on line 3086 in dojo/forms.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (T201)

dojo/forms.py:3086:13: T201 `print` found
if not active or (not verified and (get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True))):
logger.debug("Findings must be active and verified to be pushed to JIRA")
error_message = "Findings must be active and verified to be pushed to JIRA"
self.add_error("push_to_jira", ValidationError(error_message, code="not_active_or_verified"))
Expand Down
6 changes: 4 additions & 2 deletions dojo/jira_link/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def can_be_pushed_to_jira(obj, form=None):

logger.debug("can_be_pushed_to_jira: %s, %s, %s", active, verified, severity)

isenforced = get_system_setting("enforce_verified_status", True)
isenforced = get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True)

if not active or (not verified and isenforced):
logger.debug("Findings must be active and verified, if enforced by system settings, to be pushed to JIRA")
Expand Down Expand Up @@ -1116,7 +1116,9 @@ def get_issuetype_fields(
except JIRAError as e:
e.text = f"Jira API call 'createmeta' failed with status: {e.status_code} and message: {e.text}"
raise

print("\n\n")

Check failure on line 1119 in dojo/jira_link/helper.py

View workflow job for this annotation

GitHub Actions / ruff-linting

Ruff (T201)

dojo/jira_link/helper.py:1119:13: T201 `print` found
print(meta)
print("\n\n")
project = None
try:
project = meta["projects"][0]
Expand Down
2 changes: 1 addition & 1 deletion dojo/management/commands/jira_async_updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Command(BaseCommand):
def handle(self, *args, **options):

findings = Finding.objects.exclude(jira_issue__isnull=True)
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True):
findings = findings.filter(verified=True, active=True)
else:
findings = findings.filter(active=True)
Expand Down
2 changes: 1 addition & 1 deletion dojo/management/commands/push_to_jira_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Command(BaseCommand):
def handle(self, *args, **options):

findings = Finding.objects.exclude(jira_issue__isnull=True)
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_jira", True):
findings = findings.filter(verified=True, active=True)
else:
findings = findings.filter(active=True)
Expand Down
2 changes: 1 addition & 1 deletion dojo/metrics/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def finding_queries(
weekly_counts = query_counts_for_period(MetricsPeriod.WEEK, weeks_between)

top_ten = get_authorized_products(Permissions.Product_View)
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
top_ten = top_ten.filter(engagement__test__finding__verified=True)

top_ten = top_ten.filter(engagement__test__finding__false_p=False,
Expand Down
8 changes: 4 additions & 4 deletions dojo/metrics/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ def simple_metrics(request):
date__year=now.year,
)

if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
total = total.filter(verified=True)

total = total.distinct()
Expand Down Expand Up @@ -308,7 +308,7 @@ def product_type_counts(request):
then=Value(1)),
output_field=IntegerField())))["total"]

if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
overall_in_pt = Finding.objects.filter(date__lt=end_date,
verified=True,
false_p=False,
Expand Down Expand Up @@ -509,7 +509,7 @@ def product_tag_counts(request):
then=Value(1)),
output_field=IntegerField())))["total"]

if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
overall_in_pt = Finding.objects.filter(date__lt=end_date,
verified=True,
false_p=False,
Expand Down Expand Up @@ -685,7 +685,7 @@ def view_engineer(request, eid):
raise PermissionDenied
now = timezone.now()

if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
findings = Finding.objects.filter(reporter=user, verified=True)
else:
findings = Finding.objects.filter(reporter=user)
Expand Down
38 changes: 30 additions & 8 deletions dojo/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,32 @@ class System_Settings(models.Model):

enforce_verified_status = models.BooleanField(
default=True,
verbose_name=_("Enforce Verified Status"),
help_text=_("When enabled, features such as product grading, jira "
"integration, metrics, and reports will only interact "
"with verified findings.",
verbose_name=_("Enforce Verified Status - Globally"),
help_text=_(
"When enabled, features such as product grading, jira "
"integration, metrics, and reports will only interact "
"with verified findings. This setting will override "
"individually scoped verified toggles.",
),
)
enforce_verified_status_jira = models.BooleanField(
default=True,
verbose_name=_("Enforce Verified Status - Jira"),
help_text=_("When enabled, findings must have a verified status to be pushed to jira."),
)
enforce_verified_status_product_grading = models.BooleanField(
default=True,
verbose_name=_("Enforce Verified Status - Product Grading"),
help_text=_(
"When enabled, findings must have a verified status to be considered as part of a product's grading.",
),
)
enforce_verified_status_metrics = models.BooleanField(
default=True,
verbose_name=_("Enforce Verified Status - Metrics"),
help_text=_(
"When enabled, findings must have a verified status to be counted in metric calculations, "
"be included in reports, and filters.",
),
)

Expand Down Expand Up @@ -1236,7 +1258,7 @@ def open_findings(self, start_date=None, end_date=None):
date__range=[start_date,
end_date])

if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
findings = findings.filter(verified=True)

critical = findings.filter(severity="Critical").count()
Expand Down Expand Up @@ -1553,7 +1575,7 @@ def unaccepted_open_findings(self):
from dojo.utils import get_system_setting

findings = Finding.objects.filter(risk_accepted=False, active=True, duplicate=False, test__engagement=self)
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
findings = findings.filter(verified=True)

return findings
Expand Down Expand Up @@ -2123,7 +2145,7 @@ def copy(self, engagement=None):
def unaccepted_open_findings(self):
from dojo.utils import get_system_setting
findings = Finding.objects.filter(risk_accepted=False, active=True, duplicate=False, test=self)
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
findings = findings.filter(verified=True)

return findings
Expand Down Expand Up @@ -2752,7 +2774,7 @@ def delete(self, *args, **kwargs):
def unaccepted_open_findings(cls):
from dojo.utils import get_system_setting
results = cls.objects.filter(active=True, duplicate=False, risk_accepted=False)
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
results = results.filter(verified=True)

return results
Expand Down
6 changes: 3 additions & 3 deletions dojo/reports/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def get_endpoints(self, request: HttpRequest):
finding__duplicate=False,
finding__out_of_scope=False,
)
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
endpoints = endpoints.filter(finding__active=True)

endpoints = endpoints.distinct()
Expand Down Expand Up @@ -194,7 +194,7 @@ def report_endpoints(request):
finding__duplicate=False,
finding__out_of_scope=False,
)
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
endpoints = endpoints.filter(finding__active=True)

endpoints = endpoints.distinct()
Expand Down Expand Up @@ -271,7 +271,7 @@ def product_endpoint_report(request, pid):
finding__duplicate=False,
finding__out_of_scope=False)

if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
endpoint_ids = endpoints.filter(finding__active=True).values_list("id", flat=True)

endpoint_ids = endpoints.values_list("id", flat=True)
Expand Down
2 changes: 1 addition & 1 deletion dojo/reports/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ def report_widget_factory(json_data=None, request=None, user=None, finding_notes
finding__duplicate=False,
finding__out_of_scope=False,
)
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
endpoints = endpoints.filter(finding__verified=True)

endpoints = endpoints.distinct()
Expand Down
4 changes: 2 additions & 2 deletions dojo/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ def opened_in_period(start_date, end_date, **kwargs):
end_date.month,
end_date.day,
tzinfo=timezone.get_current_timezone())
if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_metrics", True):
opened_in_period = Finding.objects.filter(
date__range=[start_date, end_date],
**kwargs,
Expand Down Expand Up @@ -1584,7 +1584,7 @@ def calculate_grade(product, *args, **kwargs):
false_p=False,
test__engagement__product=product)

if get_system_setting("enforce_verified_status", True):
if get_system_setting("enforce_verified_status", True) or get_system_setting("enforce_verified_status_product_grading", True):
findings = findings.filter(verified=True)

severity_values = findings.values("severity").annotate(
Expand Down
28 changes: 25 additions & 3 deletions unittests/test_jira_import_and_pushing_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def __init__(self, *args, **kwargs):
DojoVCRAPITestCase.__init__(self, *args, **kwargs)

def assert_cassette_played(self):
if True: # set to True when committing. set to False when recording new test cassettes
if False: # set to True when committing. set to False when recording new test cassettes
self.assertTrue(self.cassette.all_played)

def _get_vcr(self, **kwargs):
Expand Down Expand Up @@ -619,7 +619,28 @@ def test_import_with_push_to_jira_update_tags(self):
self.assert_cassette_played()

@toggle_system_setting_boolean("enforce_verified_status", True) # noqa: FBT003
def test_import_with_push_to_jira_not_verified_with_enforced_verified(self):
@toggle_system_setting_boolean("enforce_verified_status_jira", True) # noqa: FBT003
def test_import_with_push_to_jira_not_verified_enforced_verified_globally_true_enforced_verified_jira_true(self):
import0 = self.import_scan_with_params(self.zap_sample5_filename, push_to_jira=True, verified=False)
test_id = import0["test"]
# This scan file has two active findings, so we should not push either of them
self.assert_jira_issue_count_in_test(test_id, 0)
# by asserting full cassette is played we know all calls to JIRA have been made as expected
self.assert_cassette_played()

@toggle_system_setting_boolean("enforce_verified_status", True) # noqa: FBT003
@toggle_system_setting_boolean("enforce_verified_status_jira", False) # noqa: FBT003
def test_import_with_push_to_jira_not_verified_enforced_verified_globally_true_enforced_verified_jira_false(self):
import0 = self.import_scan_with_params(self.zap_sample5_filename, push_to_jira=True, verified=False)
test_id = import0["test"]
# This scan file has two active findings, so we should not push either of them
self.assert_jira_issue_count_in_test(test_id, 0)
# by asserting full cassette is played we know all calls to JIRA have been made as expected
self.assert_cassette_played()

@toggle_system_setting_boolean("enforce_verified_status", False) # noqa: FBT003
@toggle_system_setting_boolean("enforce_verified_status_jira", True) # noqa: FBT003
def test_import_with_push_to_jira_not_verified_enforced_verified_globally_false_enforced_verified_jira_true(self):
import0 = self.import_scan_with_params(self.zap_sample5_filename, push_to_jira=True, verified=False)
test_id = import0["test"]
# This scan file has two active findings, so we should not push either of them
Expand All @@ -628,7 +649,8 @@ def test_import_with_push_to_jira_not_verified_with_enforced_verified(self):
self.assert_cassette_played()

@toggle_system_setting_boolean("enforce_verified_status", False) # noqa: FBT003
def test_import_with_push_to_jira_not_verified_without_enforced_verified(self):
@toggle_system_setting_boolean("enforce_verified_status_jira", False) # noqa: FBT003
def test_import_with_push_to_jira_not_verified_enforced_verified_globally_false_enforced_verified_jira_false(self):
import0 = self.import_scan_with_params(self.zap_sample5_filename, push_to_jira=True, verified=False)
test_id = import0["test"]
# This scan file has two active findings, so we should not push both of them
Expand Down
Loading

0 comments on commit cef1c09

Please sign in to comment.