Skip to content

Commit

Permalink
properly parse TokenMatchesOASRequirements (oauth toolkit) #469
Browse files Browse the repository at this point in the history
  • Loading branch information
tfranzel committed Jul 30, 2021
1 parent 8697fc6 commit c04c585
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
5 changes: 4 additions & 1 deletion drf_spectacular/contrib/django_oauth_toolkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ def get_security_requirement(self, auto_schema):

for permission in auto_schema.view.get_permissions():
if isinstance(permission, TokenMatchesOASRequirements):
return {self.name: permission.get_required_alternate_scopes(request, view)}
# OpenAPI has no scope grouping so we simply flatten the list of alternatives
alt_scopes = permission.get_required_alternate_scopes(request, view)
alt_scopes = alt_scopes.get(auto_schema.method, [])
return {self.name: [alt for group in alt_scopes for alt in group]}
if isinstance(permission, IsAuthenticatedOrTokenHasScope):
return {self.name: TokenHasScope().get_scopes(request, view)}
if isinstance(permission, TokenHasScope):
Expand Down
14 changes: 13 additions & 1 deletion tests/contrib/test_oauth_toolkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
try:
from oauth2_provider.contrib.rest_framework import (
IsAuthenticatedOrTokenHasScope, OAuth2Authentication, TokenHasReadWriteScope,
TokenHasResourceScope,
TokenHasResourceScope, TokenMatchesOASRequirements,
)
except ImportError:
IsAuthenticatedOrTokenHasScope = None
OAuth2Authentication = None
TokenHasReadWriteScope = None
TokenHasResourceScope = None
TokenMatchesOASRequirements = None


class XSerializer(serializers.Serializer):
Expand Down Expand Up @@ -45,6 +46,16 @@ class IsAuthenticatedOrTokenHasScopeViewset(mixins.ListModelMixin, viewsets.Gene
required_scopes = ['extra_scope']


class OASRequirementsViewset(mixins.CreateModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
serializer_class = XSerializer
authentication_classes = [OAuth2Authentication]
permission_classes = [TokenMatchesOASRequirements]
required_alternate_scopes = {
'GET': [['read']],
'POST': [['create1', 'scope2'], ['alt-scope3'], ['alt-scope4', 'alt-scope5']],
}


class TestScopesBackend(BaseScopes):

def get_all_scopes(self):
Expand Down Expand Up @@ -77,6 +88,7 @@ def test_oauth2_toolkit(no_warnings):
router.register('TokenHasReadWriteScope', TokenHasReadWriteScopeViewset, basename="x1")
router.register('TokenHasResourceScope', TokenHasResourceScopeViewset, basename="x2")
router.register('IsAuthenticatedOrTokenHasScope', IsAuthenticatedOrTokenHasScopeViewset, basename="x3")
router.register('OASRequirements', OASRequirementsViewset, basename="x4")

urlpatterns = [
*router.urls,
Expand Down
49 changes: 49 additions & 0 deletions tests/contrib/test_oauth_toolkit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,55 @@ paths:
items:
$ref: '#/components/schemas/X'
description: ''
/OASRequirements/:
get:
operationId: OASRequirements_list
description: ''
tags:
- OASRequirements
security:
- oauth2:
- read
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/X'
description: ''
post:
operationId: OASRequirements_create
description: ''
tags:
- OASRequirements
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/X'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/X'
multipart/form-data:
schema:
$ref: '#/components/schemas/X'
required: true
security:
- oauth2:
- create1
- scope2
- alt-scope3
- alt-scope4
- alt-scope5
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/X'
description: ''
/TokenHasReadWriteScope/:
get:
operationId: TokenHasReadWriteScope_list
Expand Down

0 comments on commit c04c585

Please sign in to comment.