From f618ae0ad4c1cc4a65be1f6dac50108368b18690 Mon Sep 17 00:00:00 2001 From: kiblik <5609770+kiblik@users.noreply.github.com> Date: Fri, 15 Aug 2025 18:32:11 +0200 Subject: [PATCH] feat(settings): Drop time_zone --- docs/content/en/open_source/upgrading/2.50.md | 8 +++++-- .../0241_remove_system_settings_time_zone.py | 15 ++++++++++++ dojo/filters.py | 23 +++++++------------ dojo/fixtures/defect_dojo_sample_data.json | 1 - dojo/fixtures/dojo_testdata.json | 1 - dojo/fixtures/system_settings.json | 1 - dojo/models.py | 4 ---- 7 files changed, 29 insertions(+), 24 deletions(-) create mode 100644 dojo/db_migrations/0241_remove_system_settings_time_zone.py diff --git a/docs/content/en/open_source/upgrading/2.50.md b/docs/content/en/open_source/upgrading/2.50.md index e4a0255a343..289f833a03f 100644 --- a/docs/content/en/open_source/upgrading/2.50.md +++ b/docs/content/en/open_source/upgrading/2.50.md @@ -2,6 +2,10 @@ title: 'Upgrading to DefectDojo Version 2.50.x' toc_hide: true weight: -20250804 -description: No special instructions. +description: Dropped support for time_zone in System settings. --- -There are no special instructions for upgrading to 2.50.x. Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.50.0) for the contents of the release. + +To simplify the management of the DefectDojo application, it is not necessary to set the time zone in two places (environmental variables and system settings). From now on, environmental variable is supported. +Please check that the environmental variable `DD_TIME_ZONE` is set based on your satisfaction. Any [TZ identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) is a valid value. Default value is `UTC`. + +There are other instructions for upgrading to 2.50.x. Check the [Release Notes](https://github.com/DefectDojo/django-DefectDojo/releases/tag/2.50.0) for the contents of the release. diff --git a/dojo/db_migrations/0241_remove_system_settings_time_zone.py b/dojo/db_migrations/0241_remove_system_settings_time_zone.py new file mode 100644 index 00000000000..4e92e12f0c9 --- /dev/null +++ b/dojo/db_migrations/0241_remove_system_settings_time_zone.py @@ -0,0 +1,15 @@ +# Generated by Django 5.1.11 on 2025-08-15 16:30 +from django.db import migrations + +class Migration(migrations.Migration): + + dependencies = [ + ('dojo', '0240_jira_instance_password_help_text_fix'), + ] + + operations = [ + migrations.RemoveField( + model_name='system_settings', + name='time_zone', + ), + ] diff --git a/dojo/filters.py b/dojo/filters.py index 8344c3fff6e..4b22d11560f 100644 --- a/dojo/filters.py +++ b/dojo/filters.py @@ -2,7 +2,6 @@ import decimal import logging import warnings -import zoneinfo from datetime import datetime, timedelta import six @@ -14,7 +13,7 @@ from django.contrib.contenttypes.models import ContentType from django.db.models import Count, JSONField, Q from django.forms import HiddenInput -from django.utils import timezone +from django.utils.timezone import now, tzinfo from django.utils.translation import gettext_lazy as _ from django_filters import ( BooleanFilter, @@ -97,8 +96,6 @@ logger = logging.getLogger(__name__) -local_tz = zoneinfo.ZoneInfo(get_system_setting("time_zone")) - BOOLEAN_CHOICES = (("false", "No"), ("true", "Yes")) EARLIEST_FINDING = None @@ -124,10 +121,6 @@ def vulnerability_id_filter(queryset, name, value): return queryset.filter(id__in=ids) -def now(): - return datetime.today().replace(tzinfo=local_tz) - - class NumberInFilter(filters.BaseInFilter, filters.NumberFilter): pass @@ -200,7 +193,7 @@ def filter(self, qs, value): earliest_finding = get_earliest_finding(qs) if earliest_finding is not None: start_date = datetime.combine( - earliest_finding.date, datetime.min.time()).replace(tzinfo=local_tz) + earliest_finding.date, datetime.min.time()).replace(tzinfo=tzinfo()) self.start_date = _truncate(start_date - timedelta(days=1)) self.end_date = _truncate(now() + timedelta(days=1)) try: @@ -216,7 +209,7 @@ def any(self, qs, name): def sla_satisfied(self, qs, name): # return findings that have an sla expiration date after today or no sla expiration date - return qs.filter(Q(sla_expiration_date__isnull=True) | Q(sla_expiration_date__gt=timezone.now().date())) + return qs.filter(Q(sla_expiration_date__isnull=True) | Q(sla_expiration_date__gt=now().date())) def sla_violated(self, qs, name): # return active findings that have an sla expiration date before today @@ -229,7 +222,7 @@ def sla_violated(self, qs, name): risk_accepted=False, is_mitigated=False, mitigated=None, - ) & Q(sla_expiration_date__lt=timezone.now().date()), + ) & Q(sla_expiration_date__lt=now().date()), ) options = { @@ -824,14 +817,14 @@ def any(self, qs, name): earliest_finding = get_earliest_finding(qs) if earliest_finding is not None: start_date = datetime.combine( - earliest_finding.date, datetime.min.time()).replace(tzinfo=local_tz) + earliest_finding.date, datetime.min.time()).replace(tzinfo=tzinfo()) self.start_date = _truncate(start_date - timedelta(days=1)) self.end_date = _truncate(now() + timedelta(days=1)) return qs.all() return None def current_month(self, qs, name): - self.start_date = datetime(now().year, now().month, 1, 0, 0, 0).replace(tzinfo=local_tz) + self.start_date = datetime(now().year, now().month, 1, 0, 0, 0).replace(tzinfo=tzinfo()) self.end_date = now() return qs.filter(**{ f"{name}__year": self.start_date.year, @@ -839,7 +832,7 @@ def current_month(self, qs, name): }) def current_year(self, qs, name): - self.start_date = datetime(now().year, 1, 1, 0, 0, 0).replace(tzinfo=local_tz) + self.start_date = datetime(now().year, 1, 1, 0, 0, 0).replace(tzinfo=tzinfo()) self.end_date = now() return qs.filter(**{ f"{name}__year": now().year, @@ -890,7 +883,7 @@ def filter(self, qs, value): earliest_finding = get_earliest_finding(qs) if earliest_finding is not None: start_date = datetime.combine( - earliest_finding.date, datetime.min.time()).replace(tzinfo=local_tz) + earliest_finding.date, datetime.min.time()).replace(tzinfo=tzinfo()) self.start_date = _truncate(start_date - timedelta(days=1)) self.end_date = _truncate(now() + timedelta(days=1)) try: diff --git a/dojo/fixtures/defect_dojo_sample_data.json b/dojo/fixtures/defect_dojo_sample_data.json index 676cd272850..4dd8181df5f 100644 --- a/dojo/fixtures/defect_dojo_sample_data.json +++ b/dojo/fixtures/defect_dojo_sample_data.json @@ -813,7 +813,6 @@ "retroactive_false_positive_history": false, "url_prefix": "", "team_name": "", - "time_zone": "UTC", "enable_product_grade": true, "product_grade": "def grade_product(crit, high, med, low):\r\n health=100\r\n if crit > 0:\r\n health = 40\r\n health = health - ((crit - 1) * 5)\r\n if high > 0:\r\n if health == 100:\r\n health = 60\r\n health = health - ((high - 1) * 3)\r\n if med > 0:\r\n if health == 100:\r\n health = 80\r\n health = health - ((med - 1) * 2)\r\n if low > 0:\r\n if health == 100:\r\n health = 95\r\n health = health - low\r\n\r\n if health < 5:\r\n health = 5\r\n\r\n return health", "product_grade_a": 90, diff --git a/dojo/fixtures/dojo_testdata.json b/dojo/fixtures/dojo_testdata.json index 92d3ec0bb20..805682f4761 100644 --- a/dojo/fixtures/dojo_testdata.json +++ b/dojo/fixtures/dojo_testdata.json @@ -236,7 +236,6 @@ "max_dupes": 1, "slack_username": "", "enable_msteams_notifications": false, - "time_zone": "UTC", "enable_deduplication": true, "delete_duplicates": false, "slack_channel": "", diff --git a/dojo/fixtures/system_settings.json b/dojo/fixtures/system_settings.json index 16f02a827a8..37033d658f0 100644 --- a/dojo/fixtures/system_settings.json +++ b/dojo/fixtures/system_settings.json @@ -6,7 +6,6 @@ "enable_deduplication": false, "enable_jira": false, "url_prefix": "", - "time_zone": "UTC", "product_grade": "def grade_product(crit, high, med, low):\r\n health=100\r\n if crit > 0:\r\n health = 40\r\n health = health - ((crit - 1) * 5)\r\n if high > 0:\r\n if health == 100:\r\n health = 60\r\n health = health - ((high - 1) * 3)\r\n if med > 0:\r\n if health == 100:\r\n health = 80\r\n health = health - ((med - 1) * 2)\r\n if low > 0:\r\n if health == 100:\r\n health = 95\r\n health = health - low\r\n\r\n if health < 5:\r\n health = 5\r\n\r\n return health", "product_grade_a": 90, "product_grade_b": 80, diff --git a/dojo/models.py b/dojo/models.py index 6d19633e281..1dab58d20ed 100644 --- a/dojo/models.py +++ b/dojo/models.py @@ -4,7 +4,6 @@ import logging import re import warnings -import zoneinfo from contextlib import suppress from datetime import datetime, timedelta from decimal import Decimal @@ -437,9 +436,6 @@ class System_Settings(models.Model): url_prefix = models.CharField(max_length=300, default="", blank=True, help_text=_("URL prefix if DefectDojo is installed in it's own virtual subdirectory.")) team_name = models.CharField(max_length=100, default="", blank=True) - time_zone = models.CharField(max_length=50, - choices=[(tz, tz) for tz in zoneinfo.available_timezones()], - default="UTC", blank=False) enable_product_grade = models.BooleanField(default=False, verbose_name=_("Enable Product Grading"), help_text=_("Displays a grade letter next to a product to show the overall health.")) product_grade = models.CharField(max_length=800, blank=True) product_grade_a = models.IntegerField(default=90,