Skip to content

Commit b413437

Browse files
sla: parse finding.date implicitly (#12301)
* sla: parse finding.date implicitly * add comment * move import * add unit test
1 parent 84383b2 commit b413437

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

dojo/models.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from pathlib import Path
1111
from uuid import uuid4
1212

13+
import dateutil
1314
import hyperlink
1415
import tagulous.admin
1516
from auditlog.registry import auditlog
@@ -2682,6 +2683,9 @@ def save(self, dedupe_option=True, rules_option=True, product_grading_option=Tru
26822683

26832684
from dojo.finding import helper as finding_helper
26842685

2686+
# if not isinstance(self.date, (datetime, date)):
2687+
# raise ValidationError(_("The 'date' field must be a valid date or datetime object."))
2688+
26852689
if not user:
26862690
from dojo.utils import get_current_user
26872691
user = get_current_user()
@@ -3053,9 +3057,14 @@ def set_sla_expiration_date(self):
30533057
if not system_settings.enable_finding_sla:
30543058
return
30553059

3060+
# some parsers provide date as a `str` instead of a `date` in which case we need to parse it #12299 on GitHub
3061+
sla_start_date = self.get_sla_start_date()
3062+
if sla_start_date and isinstance(sla_start_date, str):
3063+
sla_start_date = dateutil.parser.parse(sla_start_date).date()
3064+
30563065
sla_period, enforce_period = self.get_sla_period()
30573066
if sla_period is not None and enforce_period:
3058-
self.sla_expiration_date = self.get_sla_start_date() + relativedelta(days=sla_period)
3067+
self.sla_expiration_date = sla_start_date + relativedelta(days=sla_period)
30593068
else:
30603069
self.sla_expiration_date = None
30613070

unittests/test_sla_calculations.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22
from unittest.mock import patch
33

4+
import django
45
from dateutil.relativedelta import relativedelta
56
from django.utils import timezone
67

@@ -153,3 +154,29 @@ def test_mitigated_outside_sla(self):
153154
self.assertTrue("Out of SLA" in finding_sla(finding))
154155
self.assertTrue("15 days past" in finding_sla(finding))
155156
self.assertTrue(">15<" in finding_sla(finding))
157+
158+
# test implicit parsing of finding.date (GitHub #12299)
159+
def test_finding_date_formats(self):
160+
with self.subTest(i=0):
161+
# date set to now shouldn't result in an error
162+
finding = Finding(test=Test.objects.get(id=89), title="Test Finding 1", severity="High")
163+
finding.date = timezone.now()
164+
finding.save()
165+
166+
with self.subTest(i=1):
167+
# date set to simple date string shouldn't result in an error
168+
finding = Finding(test=Test.objects.get(id=89), title="Test Finding 2", severity="High")
169+
finding.date = "2025-04-23"
170+
finding.save()
171+
172+
with self.subTest(i=2):
173+
# date set to ISO date string shouldn't result in an error
174+
finding = Finding(test=Test.objects.get(id=89), title="Test Finding 3", severity="High")
175+
finding.date = "2025-04-23T12:00:00Z"[:10]
176+
finding.save()
177+
178+
with self.subTest(i=3) and self.assertRaises(django.core.exceptions.ValidationError):
179+
# date set to ISO datetime string will result in a Django Error, not an error in our code
180+
finding = Finding(test=Test.objects.get(id=89), title="Test Finding 3", severity="High")
181+
finding.date = "2025-04-23T12:00:00+02:00"
182+
finding.save()

0 commit comments

Comments
 (0)