19
19
try :
20
20
from rest_framework import permissions
21
21
from rest_framework .views import APIView
22
+ from rest_framework .test import force_authenticate , APIRequestFactory
22
23
from ..ext .rest_framework import OAuth2Authentication , TokenHasScope , TokenHasReadWriteScope , TokenHasResourceScope
24
+ from ..ext .rest_framework import IsAuthenticatedOrTokenHasScope
23
25
24
26
class MockView (APIView ):
25
27
permission_classes = (permissions .IsAuthenticated ,)
@@ -37,6 +39,10 @@ class ScopedView(OAuth2View):
37
39
permission_classes = [permissions .IsAuthenticated , TokenHasScope ]
38
40
required_scopes = ['scope1' ]
39
41
42
+ class AuthenticatedOrScopedView (OAuth2View ):
43
+ permission_classes = [IsAuthenticatedOrTokenHasScope ]
44
+ required_scopes = ['scope1' ]
45
+
40
46
class ReadWriteScopedView (OAuth2View ):
41
47
permission_classes = [permissions .IsAuthenticated , TokenHasReadWriteScope ]
42
48
@@ -51,6 +57,7 @@ class ResourceScopedView(OAuth2View):
51
57
url (r'^oauth2-scoped-test/$' , ScopedView .as_view ()),
52
58
url (r'^oauth2-read-write-test/$' , ReadWriteScopedView .as_view ()),
53
59
url (r'^oauth2-resource-scoped-test/$' , ResourceScopedView .as_view ()),
60
+ url (r'^oauth2-authenticated-or-scoped-test/$' , AuthenticatedOrScopedView .as_view ()),
54
61
)
55
62
56
63
rest_framework_installed = True
@@ -105,6 +112,24 @@ def test_authentication_denied(self):
105
112
response = self .client .get ("/oauth2-test/" , HTTP_AUTHORIZATION = auth )
106
113
self .assertEqual (response .status_code , 401 )
107
114
115
+ @unittest .skipUnless (rest_framework_installed , 'djangorestframework not installed' )
116
+ def test_authentication_or_scope_denied (self ):
117
+ # user is not authenticated
118
+ # not a correct token
119
+ auth = self ._create_authorization_header ("fake-token" )
120
+ response = self .client .get ("/oauth2-authenticated-or-scoped-test/" , HTTP_AUTHORIZATION = auth )
121
+ self .assertEqual (response .status_code , 401 )
122
+ # token doesn't have correct scope
123
+ auth = self ._create_authorization_header (self .access_token .token )
124
+
125
+ factory = APIRequestFactory ()
126
+ request = factory .get ("/oauth2-authenticated-or-scoped-test/" )
127
+ request .auth = auth
128
+ force_authenticate (request , token = self .access_token )
129
+ response = AuthenticatedOrScopedView .as_view ()(request )
130
+ # authenticated but wrong scope, this is 403, not 401
131
+ self .assertEqual (response .status_code , 403 )
132
+
108
133
@unittest .skipUnless (rest_framework_installed , 'djangorestframework not installed' )
109
134
def test_scoped_permission_allow (self ):
110
135
self .access_token .scope = 'scope1'
@@ -114,6 +139,33 @@ def test_scoped_permission_allow(self):
114
139
response = self .client .get ("/oauth2-scoped-test/" , HTTP_AUTHORIZATION = auth )
115
140
self .assertEqual (response .status_code , 200 )
116
141
142
+ @unittest .skipUnless (rest_framework_installed , 'djangorestframework not installed' )
143
+ def test_authenticated_or_scoped_permission_allow (self ):
144
+ self .access_token .scope = 'scope1'
145
+ self .access_token .save ()
146
+ # correct token and correct scope
147
+ auth = self ._create_authorization_header (self .access_token .token )
148
+ response = self .client .get ("/oauth2-authenticated-or-scoped-test/" , HTTP_AUTHORIZATION = auth )
149
+ self .assertEqual (response .status_code , 200 )
150
+
151
+ auth = self ._create_authorization_header ("fake-token" )
152
+ # incorrect token but authenticated
153
+ factory = APIRequestFactory ()
154
+ request = factory .get ("/oauth2-authenticated-or-scoped-test/" )
155
+ request .auth = auth
156
+ force_authenticate (request , self .test_user )
157
+ response = AuthenticatedOrScopedView .as_view ()(request )
158
+ self .assertEqual (response .status_code , 200 )
159
+
160
+ # correct token but not authenticated
161
+ request = factory .get ("/oauth2-authenticated-or-scoped-test/" )
162
+ request .auth = auth
163
+ self .access_token .scope = 'scope1'
164
+ self .access_token .save ()
165
+ force_authenticate (request , token = self .access_token )
166
+ response = AuthenticatedOrScopedView .as_view ()(request )
167
+ self .assertEqual (response .status_code , 200 )
168
+
117
169
@unittest .skipUnless (rest_framework_installed , 'djangorestframework not installed' )
118
170
def test_scoped_permission_deny (self ):
119
171
self .access_token .scope = 'scope2'
0 commit comments