Skip to content

Commit b0f866b

Browse files
Maffoochclaude
andcommitted
remove: Credential Manager (announced 2.57, EOL in 2.59)
Per the 2.59 release notes, retires the Credential Manager feature in its entirety: UI, API, models, DB tables, and the system-settings toggle that gated it. Endpoints removed (now `404`): - /api/v2/credentials/ - /api/v2/credential_mappings/ UI removed: - All `/cred/*`, `/product/<id>/cred/*`, `/engagement/<id>/cred/*`, `/test/<id>/cred/*`, `/finding/<id>/cred/*` routes - "Credential Manager" sidebar entry and per-product Add/View Credentials shortcuts in the navbar - Credential sections from view_test, view_eng, and view_finding Code deleted: - The entire `dojo/cred/` module (views, urls, signals, queries) - All `*cred*.html` templates - `CredMappingForm`, `CredMappingFormProd`, `CredUserForm` in forms.py - `ApiCredentialsFilter` in filters.py - `CredentialsViewSet`, `CredentialsMappingViewSet`, `CredentialSerializer`, `CredentialMappingSerializer`, `UserHasCredentialPermission` - Selenium tests `tests/credential_test.py` and `tests/product_credential_test.py` - The four `Credential_*` permissions and `Permissions.get_credential_permissions()`, plus their entries in every role's permission set - The `Cred_Mapping` reverse-lookup blocks in test/finding/engagement views (and the `cred_form` plumbing in the import-scan flow) - `Cred_User` from audit-log and pghistory tracking lists, including the `Cred_UserEvent` history table Schema dropped via 0265_remove_credential_manager: - `system_settings.enable_credentials` (no longer gates anything) - `Cred_Mapping`, `Cred_User`, `Cred_UserEvent` models, with their pghistory triggers cleared first The 2.59 upgrade doc already documents the removal; nothing to update in `docs/`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 5deca76 commit b0f866b

44 files changed

Lines changed: 59 additions & 2879 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

dojo/api_v2/permissions.py

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from dojo.importers.auto_create_context import AutoCreateContextManager
2121
from dojo.location.models import Location
2222
from dojo.models import (
23-
Cred_Mapping,
2423
Development_Environment,
2524
Dojo_Group,
2625
Endpoint,
@@ -146,38 +145,6 @@ def has_object_permission(self, request, view, obj):
146145
)
147146

148147

149-
class UserHasCredentialPermission(permissions.BasePermission):
150-
def has_permission(self, request, view):
151-
if request.data.get("product") is not None:
152-
return check_post_permission(
153-
request, Cred_Mapping, "product", Permissions.Credential_Add,
154-
)
155-
if request.data.get("engagement") is not None:
156-
return check_post_permission(
157-
request, Cred_Mapping, "engagement", Permissions.Credential_Add,
158-
)
159-
if request.data.get("test") is not None:
160-
return check_post_permission(
161-
request, Cred_Mapping, "test", Permissions.Credential_Add,
162-
)
163-
if request.data.get("finding") is not None:
164-
return check_post_permission(
165-
request, Cred_Mapping, "finding", Permissions.Credential_Add,
166-
)
167-
return check_post_permission(
168-
request, Cred_Mapping, "product", Permissions.Credential_Add,
169-
)
170-
171-
def has_object_permission(self, request, view, obj):
172-
return check_object_permission(
173-
request,
174-
obj.product,
175-
Permissions.Credential_View,
176-
Permissions.Credential_Edit,
177-
Permissions.Credential_Delete,
178-
)
179-
180-
181148
class UserHasDojoGroupPermission(permissions.BasePermission):
182149
def has_permission(self, request, view):
183150
if request.method == "GET":

dojo/api_v2/serializers.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@
5555
Check_List,
5656
ChoiceAnswer,
5757
ChoiceQuestion,
58-
Cred_Mapping,
59-
Cred_User,
6058
Development_Environment,
6159
Dojo_Group,
6260
Dojo_Group_Member,
@@ -2154,18 +2152,6 @@ def update(self, instance, validated_data):
21542152
return super().update(instance, validated_data)
21552153

21562154

2157-
class CredentialSerializer(serializers.ModelSerializer):
2158-
class Meta:
2159-
model = Cred_User
2160-
exclude = ("password",)
2161-
2162-
2163-
class CredentialMappingSerializer(serializers.ModelSerializer):
2164-
class Meta:
2165-
model = Cred_Mapping
2166-
fields = "__all__"
2167-
2168-
21692155
class StubFindingSerializer(serializers.ModelSerializer):
21702156
class Meta:
21712157
model = Stub_Finding

dojo/api_v2/views.py

Lines changed: 0 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
from dojo.authorization.authorization import user_has_permission_or_403
5050
from dojo.authorization.roles_permissions import Permissions
5151
from dojo.celery_dispatch import dojo_dispatch_task
52-
from dojo.cred.queries import get_authorized_cred_mappings
5352
from dojo.endpoint.queries import (
5453
get_authorized_endpoint_status,
5554
get_authorized_endpoints,
@@ -59,7 +58,6 @@
5958
from dojo.engagement.services import close_engagement, reopen_engagement
6059
from dojo.filters import (
6160
ApiAppAnalysisFilter,
62-
ApiCredentialsFilter,
6361
ApiDojoMetaFilter,
6462
ApiEndpointFilter,
6563
ApiEngagementFilter,
@@ -96,8 +94,6 @@
9694
App_Analysis,
9795
BurpRawRequestResponse,
9896
Check_List,
99-
Cred_Mapping,
100-
Cred_User,
10197
Development_Environment,
10298
Dojo_Group,
10399
Dojo_Group_Member,
@@ -879,130 +875,6 @@ def get_queryset(self):
879875
return get_authorized_app_analysis(Permissions.Product_View)
880876

881877

882-
# Authorization: object-based
883-
@extend_schema_view(**schema_with_prefetch())
884-
class CredentialsViewSet(
885-
PrefetchDojoModelViewSet,
886-
DeprecationNoticeMixin,
887-
):
888-
deprecated = True
889-
end_of_life_date = datetime(2026, 6, 1)
890-
serializer_class = serializers.CredentialSerializer
891-
queryset = Cred_User.objects.all()
892-
filter_backends = (DjangoFilterBackend,)
893-
permission_classes = (permissions.IsSuperUser, DjangoModelPermissions)
894-
895-
def get_queryset(self):
896-
return Cred_User.objects.all().order_by("id")
897-
898-
@extend_schema(
899-
deprecated=True,
900-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
901-
)
902-
def list(self, request, *args, **kwargs):
903-
return super().list(request, *args, **kwargs)
904-
905-
@extend_schema(
906-
deprecated=True,
907-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
908-
)
909-
def retrieve(self, request, *args, **kwargs):
910-
return super().retrieve(request, *args, **kwargs)
911-
912-
@extend_schema(
913-
deprecated=True,
914-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
915-
)
916-
def create(self, request, *args, **kwargs):
917-
return super().create(request, *args, **kwargs)
918-
919-
@extend_schema(
920-
deprecated=True,
921-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
922-
)
923-
def update(self, request, *args, **kwargs):
924-
return super().update(request, *args, **kwargs)
925-
926-
@extend_schema(
927-
deprecated=True,
928-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
929-
)
930-
def partial_update(self, request, *args, **kwargs):
931-
return super().partial_update(request, *args, **kwargs)
932-
933-
@extend_schema(
934-
deprecated=True,
935-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
936-
)
937-
def destroy(self, request, *args, **kwargs):
938-
return super().destroy(request, *args, **kwargs)
939-
940-
941-
# Authorization: configuration
942-
# @extend_schema_view(**schema_with_prefetch())
943-
# Nested models with prefetch make the response schema too long for Swagger UI
944-
class CredentialsMappingViewSet(
945-
PrefetchDojoModelViewSet,
946-
DeprecationNoticeMixin,
947-
):
948-
deprecated = True
949-
end_of_life_date = datetime(2026, 6, 1)
950-
serializer_class = serializers.CredentialMappingSerializer
951-
queryset = Cred_Mapping.objects.none()
952-
filter_backends = (DjangoFilterBackend,)
953-
filterset_class = ApiCredentialsFilter
954-
955-
permission_classes = (
956-
IsAuthenticated,
957-
permissions.UserHasCredentialPermission,
958-
)
959-
960-
def get_queryset(self):
961-
return get_authorized_cred_mappings(Permissions.Credential_View)
962-
963-
@extend_schema(
964-
deprecated=True,
965-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
966-
)
967-
def list(self, request, *args, **kwargs):
968-
return super().list(request, *args, **kwargs)
969-
970-
@extend_schema(
971-
deprecated=True,
972-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
973-
)
974-
def retrieve(self, request, *args, **kwargs):
975-
return super().retrieve(request, *args, **kwargs)
976-
977-
@extend_schema(
978-
deprecated=True,
979-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
980-
)
981-
def create(self, request, *args, **kwargs):
982-
return super().create(request, *args, **kwargs)
983-
984-
@extend_schema(
985-
deprecated=True,
986-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
987-
)
988-
def update(self, request, *args, **kwargs):
989-
return super().update(request, *args, **kwargs)
990-
991-
@extend_schema(
992-
deprecated=True,
993-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
994-
)
995-
def partial_update(self, request, *args, **kwargs):
996-
return super().partial_update(request, *args, **kwargs)
997-
998-
@extend_schema(
999-
deprecated=True,
1000-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
1001-
)
1002-
def destroy(self, request, *args, **kwargs):
1003-
return super().destroy(request, *args, **kwargs)
1004-
1005-
1006878
# Authorization: configuration
1007879
class FindingTemplatesViewSet(
1008880
DojoModelViewSet,

dojo/apps.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ def ready(self):
7676
# Importing the signals file is good enough if using the receiver decorator
7777
import dojo.announcement.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady
7878
import dojo.benchmark.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady
79-
import dojo.cred.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady
8079

8180
# TODO: Delete this after the move to Locations
8281
import dojo.endpoint.signals # noqa: PLC0415, F401 raised: AppRegistryNotReady

dojo/auditlog/backfill.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ def get_excluded_fields(model_name):
2020
excluded_fields_map = {
2121
"Dojo_User": ["password"],
2222
"Product": ["updated"],
23-
"Cred_User": ["password"],
2423
"Notification_Webhooks": ["header_name", "header_value"],
2524
}
2625
return excluded_fields_map.get(model_name, [])
@@ -43,9 +42,6 @@ def get_table_names(model_name):
4342
elif model_name == "Finding_Template":
4443
table_name = "dojo_finding_template"
4544
event_table_name = "dojo_finding_templateevent"
46-
elif model_name == "Cred_User":
47-
table_name = "dojo_cred_user"
48-
event_table_name = "dojo_cred_userevent"
4945
elif model_name == "Notification_Webhooks":
5046
table_name = "dojo_notification_webhooks"
5147
event_table_name = "dojo_notification_webhooksevent"
@@ -366,7 +362,7 @@ def get_tracked_models():
366362
return [
367363
"Dojo_User", "Endpoint", "Engagement", "Finding", "Finding_Group",
368364
"Product_Type", "Product", "Test", "Risk_Acceptance",
369-
"Finding_Template", "Cred_User", "Notification_Webhooks",
365+
"Finding_Template", "Notification_Webhooks",
370366
"FindingReviewers", # M2M through table for Finding.reviewers
371367
"Location", "URL",
372368
# Tag through tables (tagulous auto-generated)

dojo/auditlog/services.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ def register_django_pghistory_models():
151151
from dojo.location.models import Location # noqa: PLC0415
152152
from dojo.models import ( # noqa: PLC0415
153153
App_Analysis,
154-
Cred_User,
155154
Dojo_User,
156155
# TODO: Delete this after the move to Locations
157156
Endpoint,
@@ -312,21 +311,6 @@ def register_django_pghistory_models():
312311
},
313312
)(Finding_Template)
314313

315-
pghistory.track(
316-
pghistory.InsertEvent(),
317-
pghistory.UpdateEvent(condition=pghistory.AnyChange(exclude_auto=True)),
318-
pghistory.DeleteEvent(),
319-
pghistory.ManualEvent(label="initial_backfill"),
320-
exclude=["password"],
321-
meta={
322-
"indexes": [
323-
models.Index(fields=["pgh_created_at"]),
324-
models.Index(fields=["pgh_label"]),
325-
models.Index(fields=["pgh_context_id"]),
326-
],
327-
},
328-
)(Cred_User)
329-
330314
pghistory.track(
331315
pghistory.InsertEvent(),
332316
pghistory.UpdateEvent(condition=pghistory.AnyChange(exclude_auto=True)),

dojo/authorization/authorization.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from dojo.location.models import AbstractLocation, Location
1111
from dojo.models import (
1212
App_Analysis,
13-
Cred_Mapping,
1413
Dojo_Group,
1514
Dojo_Group_Member,
1615
Dojo_User,
@@ -220,25 +219,6 @@ def user_has_permission(user: Dojo_User, obj: Model, permission: int) -> bool:
220219
user, obj.group, permission,
221220
)
222221
return user_has_permission(user, obj.group, permission)
223-
if (
224-
isinstance(obj, Cred_Mapping)
225-
and permission in Permissions.get_credential_permissions()
226-
):
227-
if obj.product:
228-
return user_has_permission(user, obj.product, permission)
229-
if obj.engagement:
230-
return user_has_permission(
231-
user, obj.engagement.product, permission,
232-
)
233-
if obj.test:
234-
return user_has_permission(
235-
user, obj.test.engagement.product, permission,
236-
)
237-
if obj.finding:
238-
return user_has_permission(
239-
user, obj.finding.test.engagement.product, permission,
240-
)
241-
return None
242222
msg = f"No authorization implemented for class {type(obj).__name__} and permission {permission}"
243223
raise NoAuthorizationImplementedError(msg)
244224

0 commit comments

Comments
 (0)