You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
When using a somewhat complex permission classes statement that uses boolean operations as shown below, the iteration over the list of permission_classes misses the oauth2 permission classes under the booleans:
#: permissions are any one of, each requiring demo-djt-sla-* scope:#: 1. Authenticated Columbia user: auth-columbia scope plus required user claims.#: 2. Authenticated DOT user: scopes as above plus DOT required user claims.#: 3. Client Credentials (backend-to-backend): auth-none. No auth user. Claims don't exist.permission_classes= [
TokenMatchesOASRequirements& (
(IsAuthenticated&ColumbiaGroupClaimPermission&ColumbiaSubClaimPermission)
| (IsAuthenticated&DOTGroupClaimPermission&DOTSubClaimPermission)
# | (IsAuthenticated & DOTSubClaimPermission)| (~IsAuthenticated)
)
]
The end result is that the security requirements object is not added to the OAS schema document.
This is because DjangoOAuthToolkitScheme.get_security_requirement() only looks across the list of permission_classes and does not descend the possible ANDs and ORs via op1 and op2:
forpermissioninauto_schema.view.get_permissions():
ifisinstance(permission, TokenMatchesOASRequirements):
alt_scopes=permission.get_required_alternate_scopes(request, view)
alt_scopes=alt_scopes.get(auto_schema.method, [])
return [{self.name: group} forgroupinalt_scopes]
ifisinstance(permission, IsAuthenticatedOrTokenHasScope):
return {self.name: TokenHasScope().get_scopes(request, view)}
ifisinstance(permission, TokenHasScope):
# catch-all for subclasses of TokenHasScope like TokenHasReadWriteScopereturn {self.name: permission.get_scopes(request, view)}
Perhaps a better approach would be to recursively descend all the permission_classes resulting in a flattened list and see if any of the scope-related classes is present or just look for presence of the required_alternate_scopes or the required_scopes view attributes?
I've done a temporary hack of tacking this on to the end of the above logic:
# bail if none of the above and use view.required_alternate_scopes based on the view.action# this is basically the same as above.ifgetattr(view,"required_alternate_scopes") isNone:
return {self.name: []}
return [{self.name: a} forainview.required_alternate_scopes[auto_schema.method]]
Tracing this in a debugger shows that the only permission_class in the list is the top-level <rest_framework.permissions.AND> with op1 = <oauth2_provider.contrib.rest_framework.permissions.TokenMatchesOASRequirements> and op2 = <rest_framework.permissions.OR> and so on.
Expected behavior
I expect that the security requirements object be added to the schema resulting in, for example:
Describe the bug
When using a somewhat complex permission classes statement that uses boolean operations as shown below, the iteration over the list of
permission_classes
misses the oauth2 permission classes under the booleans:The end result is that the security requirements object is not added to the OAS schema document.
This is because
DjangoOAuthToolkitScheme.get_security_requirement()
only looks across the list of permission_classes and does not descend the possible ANDs and ORs via op1 and op2:Perhaps a better approach would be to recursively descend all the permission_classes resulting in a flattened list and see if any of the scope-related classes is present or just look for presence of the
required_alternate_scopes
or therequired_scopes
view attributes?I've done a temporary hack of tacking this on to the end of the above logic:
To Reproduce
Clone the sample code at https://github.com/columbia-it/django-jsonapi-training/tree/spectacular
Tracing this in a debugger shows that the only
permission_class
in the list is the top-level<rest_framework.permissions.AND>
withop1 = <oauth2_provider.contrib.rest_framework.permissions.TokenMatchesOASRequirements>
andop2 = <rest_framework.permissions.OR>
and so on.Expected behavior
I expect that the security requirements object be added to the schema resulting in, for example:
The text was updated successfully, but these errors were encountered: