Skip to content

Commit 2f8f682

Browse files
committed
Merge branch 'dev' into remove-credential-manager
2 parents f048aa8 + f50bb18 commit 2f8f682

25 files changed

Lines changed: 102 additions & 1394 deletions

dojo/api_v2/serializers.py

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@
8585
SLA_Configuration,
8686
Sonarqube_Issue,
8787
Sonarqube_Issue_Transition,
88-
Stub_Finding,
8988
System_Settings,
9089
Test,
9190
Test_Import,
@@ -2143,35 +2142,6 @@ def update(self, instance, validated_data):
21432142
return super().update(instance, validated_data)
21442143

21452144

2146-
class StubFindingSerializer(serializers.ModelSerializer):
2147-
class Meta:
2148-
model = Stub_Finding
2149-
fields = "__all__"
2150-
2151-
def validate_severity(self, value: str) -> str:
2152-
if value not in SEVERITIES:
2153-
msg = f"Severity must be one of the following: {SEVERITIES}"
2154-
raise serializers.ValidationError(msg)
2155-
return value
2156-
2157-
2158-
class StubFindingCreateSerializer(serializers.ModelSerializer):
2159-
test = serializers.PrimaryKeyRelatedField(queryset=Test.objects.all())
2160-
2161-
class Meta:
2162-
model = Stub_Finding
2163-
fields = "__all__"
2164-
extra_kwargs = {
2165-
"reporter": {"default": serializers.CurrentUserDefault()},
2166-
}
2167-
2168-
def validate_severity(self, value: str) -> str:
2169-
if value not in SEVERITIES:
2170-
msg = f"Severity must be one of the following: {SEVERITIES}"
2171-
raise serializers.ValidationError(msg)
2172-
return value
2173-
2174-
21752145
class ProductSerializer(serializers.ModelSerializer):
21762146
findings_count = serializers.SerializerMethodField()
21772147
findings_list = serializers.SerializerMethodField()

dojo/api_v2/views.py

Lines changed: 0 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
)
7474
from dojo.finding.queries import (
7575
get_authorized_findings,
76-
get_authorized_stub_findings,
7776
)
7877
from dojo.finding.views import (
7978
duplicate_cluster,
@@ -124,7 +123,6 @@
124123
SLA_Configuration,
125124
Sonarqube_Issue,
126125
Sonarqube_Issue_Transition,
127-
Stub_Finding,
128126
System_Settings,
129127
Test,
130128
Test_Import,
@@ -2085,77 +2083,6 @@ def partial_update(self, request, pk=None):
20852083
return Response(response, status=status.HTTP_405_METHOD_NOT_ALLOWED)
20862084

20872085

2088-
# Authorization: object-based
2089-
# @extend_schema_view(**schema_with_prefetch())
2090-
# Nested models with prefetch make the response schema too long for Swagger UI
2091-
class StubFindingsViewSet(
2092-
PrefetchDojoModelViewSet,
2093-
DeprecationNoticeMixin,
2094-
):
2095-
deprecated = True
2096-
end_of_life_date = datetime(2026, 6, 1)
2097-
serializer_class = serializers.StubFindingSerializer
2098-
queryset = Stub_Finding.objects.none()
2099-
filter_backends = (DjangoFilterBackend,)
2100-
filterset_fields = ["id", "title", "date", "severity", "description"]
2101-
permission_classes = (
2102-
IsAuthenticated,
2103-
permissions.UserHasFindingPermission,
2104-
)
2105-
2106-
def get_queryset(self):
2107-
return get_authorized_stub_findings(
2108-
Permissions.Finding_View,
2109-
).distinct()
2110-
2111-
def get_serializer_class(self):
2112-
if self.request and self.request.method == "POST":
2113-
return serializers.StubFindingCreateSerializer
2114-
return serializers.StubFindingSerializer
2115-
2116-
@extend_schema(
2117-
deprecated=True,
2118-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
2119-
)
2120-
def list(self, request, *args, **kwargs):
2121-
return super().list(request, *args, **kwargs)
2122-
2123-
@extend_schema(
2124-
deprecated=True,
2125-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
2126-
)
2127-
def retrieve(self, request, *args, **kwargs):
2128-
return super().retrieve(request, *args, **kwargs)
2129-
2130-
@extend_schema(
2131-
deprecated=True,
2132-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
2133-
)
2134-
def create(self, request, *args, **kwargs):
2135-
return super().create(request, *args, **kwargs)
2136-
2137-
@extend_schema(
2138-
deprecated=True,
2139-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
2140-
)
2141-
def update(self, request, *args, **kwargs):
2142-
return super().update(request, *args, **kwargs)
2143-
2144-
@extend_schema(
2145-
deprecated=True,
2146-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
2147-
)
2148-
def partial_update(self, request, *args, **kwargs):
2149-
return super().partial_update(request, *args, **kwargs)
2150-
2151-
@extend_schema(
2152-
deprecated=True,
2153-
description="This endpoint is deprecated and will be removed on 2026-06-01.",
2154-
)
2155-
def destroy(self, request, *args, **kwargs):
2156-
return super().destroy(request, *args, **kwargs)
2157-
2158-
21592086
# Authorization: authenticated, configuration
21602087
class DevelopmentEnvironmentViewSet(
21612088
DojoModelViewSet,

dojo/authorization/authorization.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
Product_Type_Group,
2727
Product_Type_Member,
2828
Risk_Acceptance,
29-
Stub_Finding,
3029
Test,
3130
)
3231
from dojo.request_cache import cache_for_request
@@ -134,9 +133,9 @@ def user_has_permission(user: Dojo_User, obj: Model, permission: int) -> bool:
134133
if obj.engagement is not None:
135134
return user_has_permission(user, obj.engagement.product, permission)
136135
return user_has_global_permission(user, permission)
137-
if ((
138-
isinstance(obj, Finding | Stub_Finding)
139-
) and permission in Permissions.get_finding_permissions()) or (
136+
if (
137+
isinstance(obj, Finding) and permission in Permissions.get_finding_permissions()
138+
) or (
140139
isinstance(obj, Finding_Group)
141140
and permission in Permissions.get_finding_group_permissions()
142141
):
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""Remove the Stub Findings feature.
2+
3+
Drops the ``Stub_Finding`` model. Stub Findings was deprecated in 2.57.0 and
4+
is end-of-life in 2.59. The model has no inbound foreign keys, so the
5+
deletion is self-contained.
6+
7+
Note: rebase the filename and the ``dependencies`` tuple to point at
8+
whatever the latest migration is at merge time if another migration has
9+
landed first.
10+
"""
11+
12+
from django.db import migrations
13+
14+
15+
class Migration(migrations.Migration):
16+
17+
dependencies = [
18+
("dojo", "0264_alter_url_identity_hash_alter_urlevent_identity_hash"),
19+
]
20+
21+
operations = [
22+
migrations.DeleteModel(
23+
name="Stub_Finding",
24+
),
25+
]

dojo/db_migrations/0265_remove_credential_manager.py renamed to dojo/db_migrations/0266_remove_credential_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
class Migration(migrations.Migration):
1414

1515
dependencies = [
16-
("dojo", "0264_alter_url_identity_hash_alter_urlevent_identity_hash"),
16+
("dojo", "0265_remove_stub_finding"),
1717
]
1818

1919
operations = [

dojo/finding/queries.py

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
Product_Member,
1818
Product_Type_Group,
1919
Product_Type_Member,
20-
Stub_Finding,
2120
Test_Import_Finding_Action,
2221
Vulnerability_Id,
2322
)
@@ -112,48 +111,6 @@ def get_authorized_findings_for_queryset(permission, queryset, user=None):
112111
)
113112

114113

115-
# Cached: all parameters are hashable, no dynamic queryset filtering
116-
@cache_for_request
117-
def get_authorized_stub_findings(permission):
118-
user = get_current_user()
119-
120-
if user is None:
121-
return Stub_Finding.objects.none()
122-
123-
if user.is_superuser:
124-
return Stub_Finding.objects.all().order_by("id")
125-
126-
if user_has_global_permission(user, permission):
127-
return Stub_Finding.objects.all().order_by("id")
128-
129-
roles = get_roles_for_permission(permission)
130-
131-
# Get authorized product/product_type IDs via subqueries
132-
authorized_product_type_roles = Product_Type_Member.objects.filter(
133-
user=user, role__in=roles,
134-
).values("product_type_id")
135-
136-
authorized_product_roles = Product_Member.objects.filter(
137-
user=user, role__in=roles,
138-
).values("product_id")
139-
140-
authorized_product_type_groups = Product_Type_Group.objects.filter(
141-
group__users=user, role__in=roles,
142-
).values("product_type_id")
143-
144-
authorized_product_groups = Product_Group.objects.filter(
145-
group__users=user, role__in=roles,
146-
).values("product_id")
147-
148-
# Filter using IN with Subquery - no annotations needed
149-
return Stub_Finding.objects.filter(
150-
Q(test__engagement__product__prod_type_id__in=Subquery(authorized_product_type_roles))
151-
| Q(test__engagement__product_id__in=Subquery(authorized_product_roles))
152-
| Q(test__engagement__product__prod_type_id__in=Subquery(authorized_product_type_groups))
153-
| Q(test__engagement__product_id__in=Subquery(authorized_product_groups)),
154-
).order_by("id")
155-
156-
157114
# Cached: all parameters are hashable, no dynamic queryset filtering
158115
@cache_for_request
159116
def get_authorized_vulnerability_ids(permission, user=None):

dojo/finding/urls.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,6 @@
164164
views.set_finding_as_original, name="set_finding_as_original"),
165165
re_path(r"^finding/(?P<fid>\d+)/remediation_date$", views.remediation_date,
166166
name="remediation_date"),
167-
# stub findings
168-
re_path(r"^stub_finding/(?P<tid>\d+)/add$",
169-
views.add_stub_finding, name="add_stub_finding"),
170-
re_path(r"^stub_finding/(?P<fid>\d+)/promote$",
171-
views.promote_to_finding, name="promote_to_finding"),
172-
re_path(r"^stub_finding/(?P<fid>\d+)/delete$",
173-
views.delete_stub_finding, name="delete_stub_finding"),
174167

175168
# template findings
176169

0 commit comments

Comments
 (0)