Skip to content

Commit 3ec6b4c

Browse files
authored
Merge branch 'dev' into master-into-dev/2.45.1-2.46.0-dev
2 parents 31baf30 + a045f44 commit 3ec6b4c

230 files changed

Lines changed: 1248 additions & 1167 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
title: 'Upgrading to DefectDojo Version 2.46.x'
3+
toc_hide: true
4+
weight: -20250407
5+
description: Import Payload Changes
6+
---
7+
8+
### Import / Reimport Statistics Delta
9+
10+
Following a successful import or reimport, a JSON blob for `statistics` is generated to provide the differential of finding activity.
11+
There was a section in the `delta` JSON blob that referred to a key labeled `left untouched`. This value does not comply with REST
12+
norms, and has been renamed to `untouched`. Here is a before and after to make it clear:
13+
14+
Before:
15+
16+
"statistics": {
17+
"before": {},
18+
"delta": {
19+
"created": {},
20+
"closed": {},
21+
"reactivated": {},
22+
"left untouched": {}
23+
},
24+
"after": {}
25+
}
26+
27+
After:
28+
29+
"statistics": {
30+
"before": {},
31+
"delta": {
32+
"created": {},
33+
"closed": {},
34+
"reactivated": {},
35+
"untouched": {}
36+
},
37+
"after": {}
38+
}
39+
40+
---
41+
42+
Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.46.0) for the contents of the release.

docs/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
},
2222
"devDependencies": {
2323
"prettier": "3.5.3",
24-
"vite": "6.2.5"
24+
"vite": "6.2.6"
2525
},
2626
"engines": {
2727
"node": "22.14.0"
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Generated by Django 5.0.8 on 2024-09-12 18:22
2+
3+
from django.db import migrations, models
4+
5+
6+
original_untouched_value = "left untouched"
7+
updated_untouched_value = "untouched"
8+
9+
10+
def convert_space_to_underscore(apps, schema_editor):
11+
test_import_finding_action = apps.get_model("dojo", "Test_Import_Finding_Action")
12+
for test_import_action in test_import_finding_action.objects.filter(
13+
action=original_untouched_value
14+
):
15+
test_import_action.action = updated_untouched_value
16+
test_import_action.save()
17+
18+
19+
def convert_underscore_to_space(apps, schema_editor):
20+
test_import_finding_action = apps.get_model("dojo", "Test_Import_Finding_Action")
21+
for test_import_action in test_import_finding_action.objects.filter(
22+
action=updated_untouched_value
23+
):
24+
test_import_action.action = original_untouched_value
25+
test_import_action.save()
26+
27+
28+
class Migration(migrations.Migration):
29+
dependencies = [
30+
("dojo", "0225_alter_product_revenue"),
31+
]
32+
33+
operations = [
34+
migrations.AlterField(
35+
model_name='test_import_finding_action',
36+
name='action',
37+
field=models.CharField(blank=True, choices=[('N', 'created'), ('C', 'closed'), ('R', 'reactivated'), ('U', 'untouched')], max_length=100, null=True),
38+
),
39+
migrations.RunPython(
40+
convert_space_to_underscore, reverse_code=convert_underscore_to_space
41+
),
42+
]

dojo/models.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
(IMPORT_CREATED_FINDING, "created"),
6868
(IMPORT_CLOSED_FINDING, "closed"),
6969
(IMPORT_REACTIVATED_FINDING, "reactivated"),
70-
(IMPORT_UNTOUCHED_FINDING, "left untouched"),
70+
(IMPORT_UNTOUCHED_FINDING, "untouched"),
7171
]
7272

7373

@@ -1053,7 +1053,7 @@ def save(self, *args, **kwargs):
10531053
super(Product, product).save()
10541054
# launch the async task to update all finding sla expiration dates
10551055
from dojo.sla_config.helpers import update_sla_expiration_dates_sla_config_async
1056-
update_sla_expiration_dates_sla_config_async(self, tuple(severities), products)
1056+
update_sla_expiration_dates_sla_config_async(self, products, tuple(severities))
10571057

10581058
def clean(self):
10591059
sla_days = [self.critical, self.high, self.medium, self.low]
@@ -1214,7 +1214,7 @@ def save(self, *args, **kwargs):
12141214
sla_config.async_updating = True
12151215
super(SLA_Configuration, sla_config).save()
12161216
# launch the async task to update all finding sla expiration dates
1217-
from dojo.product.helpers import update_sla_expiration_dates_product_async
1217+
from dojo.sla_config.helpers import update_sla_expiration_dates_product_async
12181218
update_sla_expiration_dates_product_async(self, sla_config)
12191219

12201220
def get_absolute_url(self):
@@ -2679,6 +2679,7 @@ def __str__(self):
26792679

26802680
def save(self, dedupe_option=True, rules_option=True, product_grading_option=True, # noqa: FBT002
26812681
issue_updater_option=True, push_to_jira=False, user=None, *args, **kwargs): # noqa: FBT002 - this is bit hard to fix nice have this universally fixed
2682+
logger.debug("Start saving finding of id " + str(self.id) + " dedupe_option:" + str(dedupe_option) + " (self.pk is %s)", "None" if self.pk is None else "not None")
26822683

26832684
from dojo.finding import helper as finding_helper
26842685

@@ -3043,7 +3044,7 @@ def get_sla_start_date(self):
30433044
return self.date
30443045

30453046
def get_sla_period(self):
3046-
sla_configuration = SLA_Configuration.objects.filter(id=self.test.engagement.product.sla_configuration_id).first()
3047+
sla_configuration = self.test.engagement.product.sla_configuration
30473048
sla_period = getattr(sla_configuration, self.severity.lower(), None)
30483049
enforce_period = getattr(sla_configuration, str("enforce_" + self.severity.lower()), None)
30493050
return sla_period, enforce_period
@@ -3140,6 +3141,7 @@ def has_finding_group(self):
31403141
return self.finding_group is not None
31413142

31423143
def save_no_options(self, *args, **kwargs):
3144+
logger.debug("save_no_options")
31433145
return self.save(dedupe_option=False, rules_option=False, product_grading_option=False,
31443146
issue_updater_option=False, push_to_jira=False, user=None, *args, **kwargs)
31453147

dojo/product/helpers.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,11 @@
33

44
from dojo.celery import app
55
from dojo.decorators import dojo_async_task
6-
from dojo.models import Endpoint, Engagement, Finding, Product, SLA_Configuration, Test
6+
from dojo.models import Endpoint, Engagement, Finding, Product, Test
77

88
logger = logging.getLogger(__name__)
99

1010

11-
@dojo_async_task
12-
@app.task
13-
def update_sla_expiration_dates_product_async(product, sla_config, *args, **kwargs):
14-
update_sla_expiration_dates_product_sync(product, sla_config)
15-
16-
17-
def update_sla_expiration_dates_product_sync(product, sla_config):
18-
logger.info(f"Updating finding SLA expiration dates within product {product}")
19-
# update each finding that is within the SLA configuration that was saved
20-
for f in Finding.objects.filter(test__engagement__product=product):
21-
f.save()
22-
# reset the async updating flag to false for the sla config assigned to this product
23-
if sla_config:
24-
sla_config.async_updating = False
25-
super(SLA_Configuration, sla_config).save()
26-
# set the async updating flag to false for the sla config assigned to this product
27-
product.async_updating = False
28-
super(Product, product).save()
29-
30-
3111
@dojo_async_task
3212
@app.task
3313
def propagate_tags_on_product(product_id, *args, **kwargs):

dojo/sla_config/helpers.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,50 @@
33
from dojo.celery import app
44
from dojo.decorators import dojo_async_task
55
from dojo.models import Finding, Product, SLA_Configuration
6+
from dojo.utils import calculate_grade, mass_model_updater
67

78
logger = logging.getLogger(__name__)
89

910

1011
@dojo_async_task
1112
@app.task
12-
def update_sla_expiration_dates_sla_config_async(sla_config, severities, products, *args, **kwargs):
13-
update_sla_expiration_dates_sla_config_sync(sla_config, severities, products)
13+
def update_sla_expiration_dates_sla_config_async(sla_config, products, severities, *args, **kwargs):
14+
update_sla_expiration_dates_sla_config_sync(sla_config, products, severities)
1415

1516

16-
def update_sla_expiration_dates_sla_config_sync(sla_config, severities, products):
17+
@dojo_async_task
18+
@app.task
19+
def update_sla_expiration_dates_product_async(product, sla_config, *args, **kwargs):
20+
update_sla_expiration_dates_sla_config_sync(sla_config, [product])
21+
22+
23+
def update_sla_expiration_dates_sla_config_sync(sla_config, products, severities=None):
1724
logger.info(f"Updating finding SLA expiration dates within the {sla_config} SLA configuration")
1825
# update each finding that is within the SLA configuration that was saved
19-
for f in Finding.objects.filter(test__engagement__product__sla_configuration_id=sla_config.id, severity__in=severities):
20-
f.save()
26+
findings = Finding.objects.filter(test__engagement__product__sla_configuration_id=sla_config.id)
27+
if products:
28+
findings = findings.filter(test__engagement__product__in=products)
29+
if severities:
30+
findings = findings.filter(severity__in=severities)
31+
32+
findings = findings.prefetch_related(
33+
"test",
34+
"test__engagement",
35+
"test__engagement__product",
36+
"test__engagement__product__sla_configuration",
37+
)
38+
39+
findings = findings.order_by("id").only("id", "sla_start_date", "date", "severity", "test")
40+
41+
mass_model_updater(Finding, findings, lambda f: f.set_sla_expiration_date(), fields=["sla_expiration_date"])
42+
2143
# reset the async updating flag to false for all products using this sla config
2244
for product in products:
2345
product.async_updating = False
2446
super(Product, product).save()
47+
calculate_grade(product)
48+
2549
# reset the async updating flag to false for this sla config
2650
sla_config.async_updating = False
2751
super(SLA_Configuration, sla_config).save()
52+
logger.info(f"DONE Updating finding SLA expiration dates within the {sla_config} SLA configuration")

dojo/templates/base.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
{% endblock %}
2626

2727
<!-- jQuery -->
28-
<script src="{% static "jquery/dist/jquery.js" %}"></script>
28+
<script src="{% static "jquery/dist/jquery.min.js" %}"></script>
2929
<!-- jQuery UI -->
3030
<script src="{% static "jquery-ui/dist/jquery-ui.min.js" %}"></script>
3131
<!-- Bootstrap Core JavaScript -->
@@ -74,9 +74,9 @@
7474
<link href="{% static "startbootstrap-sb-admin-2/dist/css/sb-admin-2.css" %}" rel="stylesheet">
7575

7676
<!-- Custom Fonts -->
77-
<link href="{% static 'fontawesomefree/css/fontawesome.css' %}" rel="stylesheet" type="text/css">
78-
<link href="{% static 'fontawesomefree/css/brands.css' %}" rel="stylesheet" type="text/css">
79-
<link href="{% static 'fontawesomefree/css/solid.css' %}" rel="stylesheet" type="text/css">
77+
<link href="{% static 'fontawesomefree/css/fontawesome.min.css' %}" rel="stylesheet" type="text/css">
78+
<link href="{% static 'fontawesomefree/css/brands.min.css' %}" rel="stylesheet" type="text/css">
79+
<link href="{% static 'fontawesomefree/css/solid.min.css' %}" rel="stylesheet" type="text/css">
8080

8181
{% block add_css %}
8282
{% endblock %}

dojo/tools/blackduck/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def ingest_findings(self, normalized_findings, test):
4646
references = self.format_reference(i)
4747

4848
dupe_key = hashlib.md5(
49-
f"{title} | {i.vuln_source}".encode(),
49+
f"{title} | {i.vuln_source}".encode(), usedforsecurity=False,
5050
).hexdigest()
5151

5252
if dupe_key in dupes:

dojo/tools/bugcrowd/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def get_findings(self, filename, test):
139139
finding.description = ""
140140

141141
key = hashlib.md5(
142-
(finding.title + "|" + finding.description).encode("utf-8"),
142+
(finding.title + "|" + finding.description).encode("utf-8"), usedforsecurity=False,
143143
).hexdigest()
144144

145145
if key not in dupes:

0 commit comments

Comments
 (0)