Skip to content

Commit 89a111b

Browse files
Maffoochclaude
andcommitted
fix(api): don't scope serializer querysets by AnonymousUser during schema generation
The Finding and import serializers scope their endpoint/location PrimaryKeyRelatedField querysets to request.user. During OpenAPI schema generation drf-spectacular instantiates serializers with an AnonymousUser request, which is truthy, so the `if user` branch called get_authorized_*(user=AnonymousUser); filtering a PK field by the AnonymousUser instance raised "Field 'id' expected a number but got AnonymousUser". drf-spectacular then ignored the affected views, producing an operationId collision and a KeyError in the prefetch postprocessing hook. Treat an unauthenticated user as no user so the field falls back to an empty queryset, matching pre-existing behavior for anonymous/schema-time contexts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 26d4032 commit 89a111b

2 files changed

Lines changed: 12 additions & 0 deletions

File tree

dojo/api_v2/serializers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,12 @@ def __init__(self, *args, **kwargs):
518518
super().__init__(*args, **kwargs)
519519
# Scope endpoint_to_add to the locations/endpoints the requesting user is authorized for.
520520
user = getattr(self.context.get("request"), "user", None)
521+
# An unauthenticated user (e.g. AnonymousUser during OpenAPI schema
522+
# generation, where the request has no real user) is truthy but cannot
523+
# be authorization-scoped; treat it as no user so the field falls back to
524+
# an empty queryset instead of raising on the AnonymousUser instance.
525+
if user is not None and not user.is_authenticated:
526+
user = None
521527
if not settings.V3_FEATURE_LOCATIONS:
522528
# TODO: why do we allow only existing endpoints?
523529
self.fields["endpoint_to_add"] = serializers.PrimaryKeyRelatedField(

dojo/finding/api/serializer.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,12 @@ def __init__(self, *args, **kwargs):
354354
# Scope the endpoints field to the references the requesting user is authorized
355355
# for, mirroring the scoping the finding UI form already applies.
356356
user = getattr(self.context.get("request"), "user", None)
357+
# An unauthenticated user (e.g. AnonymousUser during OpenAPI schema
358+
# generation, where the request has no real user) is truthy but cannot
359+
# be authorization-scoped; treat it as no user so the field falls back to
360+
# an empty queryset instead of raising on the AnonymousUser instance.
361+
if user is not None and not user.is_authenticated:
362+
user = None
357363
if not settings.V3_FEATURE_LOCATIONS:
358364
self.fields["endpoints"] = serializers.PrimaryKeyRelatedField(
359365
many=True, required=False,

0 commit comments

Comments
 (0)