Skip to content

Commit 16d2b5f

Browse files
committed
Merge origin/dev into tailwind
Pulls in 15 upstream commits including: * dojo/sso/ consolidation (DefectDojo#14765) — SSO settings/urls/views/templates/ remote-user moved into a self-contained package. * dojo/notifications/ consolidation (DefectDojo#14767) — notification helper + templates moved into the package, with a new context_processors split. * dojo/github/ consolidation (DefectDojo#14766) — github_issue_link package renamed and reshaped under dojo/github/{models,services,ui,...}. * test_tag_inheritance.py extension (DefectDojo#14771). * Bulk-delete findings extension hook (DefectDojo#14740). * Planned-remediation-version column alignment fix (DefectDojo#14773). * Dependency bumps (datatables.net, gitpython, python-gitlab, pyopenssl, vulners, ruff, postcss). Conflict resolutions worth flagging: * dojo/forms.py — kept dev's reshuffled imports (GITHUB_* models now re-exported via dojo.github.ui.forms; Global_Role moved to dojo.models). Dropped the duplicate Global_Role import; the legacy authorization rewrite still imports from dojo.authorization.models for the rest. * dojo/settings/settings.dist.py — kept tailwind's UIPreferenceLoader chain and APP_DIRS=False, but added a shared _DOJO_EXTRA_TEMPLATE_DIRS list referenced by both TEMPLATES[0]["DIRS"] and the FilesystemLoader so that dojo/sso/settings.py:apply_sso_settings can append the SSO template dir at startup and have it resolved at render time. * dojo/templates/dojo/login.html — Tailwind tree, kept the inline Tailwind-styled SSO buttons rather than dev's {% include "dojo/sso_login_buttons.html" %} (which is Bootstrap-classic flavored and mounted by the SSO consolidation against the classic tree only). * unittests/test_remote_user.py — adopted dev's import path (dojo.sso.remote_user, dojo.models.Dojo_Group_Member). * dojo/api_v2/permissions.py — added a backward-compat shim re-exporting from dojo.authorization.api_permissions because the legacy authorization consolidation deleted the old module but dojo/notifications/api/views.py (new from dev) still imports from the old path. Verified: ruff clean on touched files; manage.py check passes; unittests.test_authorized_users_ui + unittests.authorization + unittests.test_user_ui_timestamps + unittests.test_rest_framework + unittests.test_remote_user all green (1144 tests, 542 skipped).
2 parents c404471 + 171d60b commit 16d2b5f

144 files changed

Lines changed: 2669 additions & 1909 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.

.dryrunsecurity.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ sensitiveCodepaths:
4141
- 'dojo/middleware.py'
4242
- 'dojo/models.py'
4343
- 'dojo/okta.py'
44-
- 'dojo/pipeline.py'
45-
- 'dojo/remote_user.py'
44+
- 'dojo/sso/pipeline.py'
45+
- 'dojo/sso/remote_user.py'
4646
- 'dojo/tasks.py'
4747
- 'dojo/urls.py'
4848
- 'dojo/utils.py'

Dockerfile.django-debian

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# Dockerfile.nginx to use the caching mechanism of Docker.
66

77
# Ref: https://devguide.python.org/#branchstatus
8-
FROM python:3.13.13-slim-trixie@sha256:9213d136547f0602c3337ff48291e937f9cc43060b3e123402cf2aaff1a08b75 AS base
8+
FROM python:3.13.13-slim-trixie@sha256:d2462a6bed37b4fc6cabecf5a2132ae70df772fe03c7393c4d98a0c2fb48aa2e AS base
99
FROM base AS build
1010
WORKDIR /app
1111
RUN \

Dockerfile.integration-tests-debian

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
# code: language=Dockerfile
33

4-
FROM openapitools/openapi-generator-cli:v7.21.0@sha256:ce308310f3c1f8761e65338b8ab87b651bf4862c6acb80de510f381fffc4510b AS openapitools
4+
FROM openapitools/openapi-generator-cli:v7.22.0@sha256:1f459499a7c794aa0ea769c3c9b0eb54806c5ad2f68510a0ebb9338d0a626ced AS openapitools
55
# currently only supports x64, no arm yet due to chrome and selenium dependencies
6-
FROM python:3.13.13-slim-trixie@sha256:9213d136547f0602c3337ff48291e937f9cc43060b3e123402cf2aaff1a08b75 AS build
6+
FROM python:3.13.13-slim-trixie@sha256:d2462a6bed37b4fc6cabecf5a2132ae70df772fe03c7393c4d98a0c2fb48aa2e AS build
77
WORKDIR /app
88
RUN \
99
apt-get -y update && \

components/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616
"chosen-bootstrap": "https://github.com/dbtek/chosen-bootstrap",
1717
"chosen-js": "^1.8.7",
1818
"clipboard": "^2.0.11",
19-
"datatables.net": "^2.3.7",
20-
"datatables.net-bs": "^2.3.7",
21-
"datatables.net-buttons": "^3.2.0",
19+
"datatables.net": "^2.3.8",
2220
"datatables.net-buttons-bs": "^3.2.6",
2321
"datatables.net-colreorder": "^2.1.2",
2422
"drmonty-datatables-plugins": "^1.0.0",

components/yarn.lock

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,14 @@ datatables.net-colreorder@^2.1.2:
485485
datatables.net "^2"
486486
jquery ">=1.7"
487487

488-
datatables.net@2.3.8, datatables.net@^2, datatables.net@^2.3.7:
488+
datatables.net@2.3.2:
489+
version "2.3.2"
490+
resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-2.3.2.tgz#6821f6288e6ad3cb6879c33e0e7e11d4091d330b"
491+
integrity sha512-31TzwIQM0+pr2ZOEOEH6dsHd/WSAl5GDDGPezOHPI3mM2NK4lcDyOoG8xXeWmSbVfbi852LNK5C84fpp4Q+qxg==
492+
dependencies:
493+
jquery ">=1.7"
494+
495+
datatables.net@^2, datatables.net@^2.3.8:
489496
version "2.3.8"
490497
resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-2.3.8.tgz#55a8dbe3bd2196951c498ab79bf44602a2bf3229"
491498
integrity sha512-uhViowhlDlheAuo5a8TrkQqADsjrtGeOyvrigvr4t0+K3MyAWqClORXWAYIcN9VLX6iIX0C8O9gwJNd01hITRg==

docs/package-lock.json

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

dojo/api_v2/permissions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""
2+
Backward-compat re-export for callers that still import permission classes
3+
from ``dojo.api_v2.permissions``. The canonical home is
4+
``dojo.authorization.api_permissions`` after the legacy authorization
5+
consolidation; this shim lets sub-package modules consolidated from
6+
upstream (``dojo/notifications/api/views.py``, etc.) keep their old import
7+
path.
8+
"""
9+
from dojo.authorization.api_permissions import * # noqa: F401,F403

dojo/api_v2/serializers.py

Lines changed: 3 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from rest_framework import serializers
2222
from rest_framework.exceptions import NotFound
2323
from rest_framework.exceptions import ValidationError as RestFrameworkValidationError
24-
from rest_framework.fields import DictField, MultipleChoiceField
24+
from rest_framework.fields import DictField
2525

2626
import dojo.finding.helper as finding_helper
2727
import dojo.risk_acceptance.helper as ra_helper
@@ -51,9 +51,7 @@
5151
from dojo.jira import services as jira_services
5252
from dojo.location.models import Location, LocationFindingReference
5353
from dojo.models import (
54-
DEFAULT_NOTIFICATION,
5554
IMPORT_ACTIONS,
56-
NOTIFICATION_CHOICES,
5755
SEVERITIES,
5856
SEVERITY_CHOICES,
5957
STATS_FIELDS,
@@ -88,8 +86,6 @@
8886
Note_Type,
8987
NoteHistory,
9088
Notes,
91-
Notification_Webhooks,
92-
Notifications,
9389
Product,
9490
Product_API_Scan_Configuration,
9591
Product_Type,
@@ -3056,110 +3052,7 @@ class FindingNoteSerializer(serializers.Serializer):
30563052
note_id = serializers.IntegerField()
30573053

30583054

3059-
class NotificationsSerializer(serializers.ModelSerializer):
3060-
product = serializers.PrimaryKeyRelatedField(
3061-
queryset=Product.objects.all(),
3062-
required=False,
3063-
default=None,
3064-
allow_null=True,
3065-
)
3066-
user = serializers.PrimaryKeyRelatedField(
3067-
queryset=Dojo_User.objects.all(),
3068-
required=False,
3069-
default=None,
3070-
allow_null=True,
3071-
)
3072-
product_type_added = MultipleChoiceField(
3073-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3074-
)
3075-
product_added = MultipleChoiceField(
3076-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3077-
)
3078-
engagement_added = MultipleChoiceField(
3079-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3080-
)
3081-
test_added = MultipleChoiceField(
3082-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3083-
)
3084-
scan_added = MultipleChoiceField(
3085-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3086-
)
3087-
jira_update = MultipleChoiceField(
3088-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3089-
)
3090-
upcoming_engagement = MultipleChoiceField(
3091-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3092-
)
3093-
stale_engagement = MultipleChoiceField(
3094-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3095-
)
3096-
auto_close_engagement = MultipleChoiceField(
3097-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3098-
)
3099-
close_engagement = MultipleChoiceField(
3100-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3101-
)
3102-
user_mentioned = MultipleChoiceField(
3103-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3104-
)
3105-
code_review = MultipleChoiceField(
3106-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3107-
)
3108-
review_requested = MultipleChoiceField(
3109-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3110-
)
3111-
other = MultipleChoiceField(
3112-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3113-
)
3114-
sla_breach = MultipleChoiceField(
3115-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3116-
)
3117-
sla_breach_combined = MultipleChoiceField(
3118-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3119-
)
3120-
risk_acceptance_expiration = MultipleChoiceField(
3121-
choices=NOTIFICATION_CHOICES, default=DEFAULT_NOTIFICATION,
3122-
)
3123-
template = serializers.BooleanField(default=False)
3124-
3125-
class Meta:
3126-
model = Notifications
3127-
fields = "__all__"
3128-
3129-
def validate(self, data):
3130-
user = None
3131-
product = None
3132-
template = False
3133-
3134-
if self.instance is not None:
3135-
user = self.instance.user
3136-
product = self.instance.product
3137-
3138-
if "user" in data:
3139-
user = data.get("user")
3140-
if "product" in data:
3141-
product = data.get("product")
3142-
if "template" in data:
3143-
template = data.get("template")
3144-
3145-
if (
3146-
template
3147-
and Notifications.objects.filter(template=True).count() > 0
3148-
):
3149-
msg = "Notification template already exists"
3150-
raise ValidationError(msg)
3151-
if (
3152-
self.instance is None
3153-
or user != self.instance.user
3154-
or product != self.instance.product
3155-
):
3156-
notifications = Notifications.objects.filter(
3157-
user=user, product=product, template=template,
3158-
).count()
3159-
if notifications > 0:
3160-
msg = "Notification for user and product already exists"
3161-
raise ValidationError(msg)
3162-
return data
3055+
from dojo.notifications.api.serializer import NotificationsSerializer # noqa: E402, F401 -- backward compat
31633056

31643057

31653058
class EngagementPresetsSerializer(serializers.ModelSerializer):
@@ -3336,7 +3229,4 @@ def create(self, validated_data):
33363229
raise
33373230

33383231

3339-
class NotificationWebhooksSerializer(serializers.ModelSerializer):
3340-
class Meta:
3341-
model = Notification_Webhooks
3342-
fields = "__all__"
3232+
from dojo.notifications.api.serializer import NotificationWebhooksSerializer # noqa: E402, F401 -- backward compat

dojo/api_v2/views.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,6 @@
125125
Note_Type,
126126
NoteHistory,
127127
Notes,
128-
Notification_Webhooks,
129-
Notifications,
130128
Product,
131129
Product_API_Scan_Configuration,
132130
Product_Type,
@@ -3407,21 +3405,6 @@ def queue_task_purge(self, request):
34073405
return Response({"purged": purged})
34083406

34093407

3410-
# Authorization: superuser
3411-
@extend_schema_view(**schema_with_prefetch())
3412-
class NotificationsViewSet(
3413-
PrefetchDojoModelViewSet,
3414-
):
3415-
serializer_class = serializers.NotificationsSerializer
3416-
queryset = Notifications.objects.none()
3417-
filter_backends = (DjangoFilterBackend,)
3418-
filterset_fields = ["id", "user", "product", "template"]
3419-
permission_classes = (permissions.IsSuperUser, DjangoModelPermissions)
3420-
3421-
def get_queryset(self):
3422-
return Notifications.objects.all().order_by("id")
3423-
3424-
34253408
@extend_schema_view(**schema_with_prefetch())
34263409
class EngagementPresetsViewset(
34273410
PrefetchDojoModelViewSet,
@@ -3684,13 +3667,3 @@ class AnnouncementViewSet(
36843667

36853668
def get_queryset(self):
36863669
return Announcement.objects.all().order_by("id")
3687-
3688-
3689-
class NotificationWebhooksViewSet(
3690-
PrefetchDojoModelViewSet,
3691-
):
3692-
serializer_class = serializers.NotificationWebhooksSerializer
3693-
queryset = Notification_Webhooks.objects.all()
3694-
filter_backends = (DjangoFilterBackend,)
3695-
filterset_fields = "__all__"
3696-
permission_classes = (permissions.IsSuperUser, DjangoModelPermissions) # TODO: add permission also for other users

dojo/apps.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ def ready(self):
8484
import dojo.file_uploads.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady
8585
import dojo.finding_group.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady
8686
import dojo.notes.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady
87+
import dojo.notifications.admin # noqa: PLC0415, F401 raised: AppRegistryNotReady
88+
import dojo.notifications.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady
8789
import dojo.product.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady
8890
import dojo.product_type.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady
8991
import dojo.risk_acceptance.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady

0 commit comments

Comments
 (0)