|
17 | 17 | )
|
18 | 18 | from rest_framework.authtoken.models import Token
|
19 | 19 | from rest_framework.compat import patterns, url, include
|
20 |
| -from rest_framework.compat import oauth2_provider, oauth2_provider_models |
| 20 | +from rest_framework.compat import oauth2_provider, oauth2_provider_models, oauth2_provider_scope |
21 | 21 | from rest_framework.compat import oauth, oauth_provider
|
22 | 22 | from rest_framework.tests.utils import RequestFactory
|
23 | 23 | from rest_framework.views import APIView
|
@@ -47,13 +47,17 @@ def put(self, request):
|
47 | 47 | (r'^basic/$', MockView.as_view(authentication_classes=[BasicAuthentication])),
|
48 | 48 | (r'^token/$', MockView.as_view(authentication_classes=[TokenAuthentication])),
|
49 | 49 | (r'^auth-token/$', 'rest_framework.authtoken.views.obtain_auth_token'),
|
50 |
| - (r'^oauth/$', MockView.as_view(authentication_classes=[OAuthAuthentication])) |
| 50 | + (r'^oauth/$', MockView.as_view(authentication_classes=[OAuthAuthentication])), |
| 51 | + (r'^oauth-with-scope/$', MockView.as_view(authentication_classes=[OAuthAuthentication], |
| 52 | + permission_classes=[permissions.TokenHasReadWriteScope])) |
51 | 53 | )
|
52 | 54 |
|
53 | 55 | if oauth2_provider is not None:
|
54 | 56 | urlpatterns += patterns('',
|
55 | 57 | url(r'^oauth2/', include('provider.oauth2.urls', namespace='oauth2')),
|
56 | 58 | url(r'^oauth2-test/$', MockView.as_view(authentication_classes=[OAuth2Authentication])),
|
| 59 | + url(r'^oauth2-with-scope-test/$', MockView.as_view(authentication_classes=[OAuth2Authentication], |
| 60 | + permission_classes=[permissions.TokenHasReadWriteScope])), |
57 | 61 | )
|
58 | 62 |
|
59 | 63 |
|
@@ -389,6 +393,39 @@ def test_post_hmac_sha1_signature_passes(self):
|
389 | 393 | response = self.csrf_client.post('/oauth/', HTTP_AUTHORIZATION=auth)
|
390 | 394 | self.assertEqual(response.status_code, 200)
|
391 | 395 |
|
| 396 | + @unittest.skipUnless(oauth_provider, 'django-oauth-plus not installed') |
| 397 | + @unittest.skipUnless(oauth, 'oauth2 not installed') |
| 398 | + def test_get_form_with_readonly_resource_passing_auth(self): |
| 399 | + """Ensure POSTing with a readonly resource instead of a write scope fails""" |
| 400 | + read_only_access_token = self.token |
| 401 | + read_only_access_token.resource.is_readonly = True |
| 402 | + read_only_access_token.resource.save() |
| 403 | + params = self._create_authorization_url_parameters() |
| 404 | + response = self.csrf_client.get('/oauth-with-scope/', params) |
| 405 | + self.assertEqual(response.status_code, 200) |
| 406 | + |
| 407 | + @unittest.skipUnless(oauth_provider, 'django-oauth-plus not installed') |
| 408 | + @unittest.skipUnless(oauth, 'oauth2 not installed') |
| 409 | + def test_post_form_with_readonly_resource_failing_auth(self): |
| 410 | + """Ensure POSTing with a readonly resource instead of a write scope fails""" |
| 411 | + read_only_access_token = self.token |
| 412 | + read_only_access_token.resource.is_readonly = True |
| 413 | + read_only_access_token.resource.save() |
| 414 | + params = self._create_authorization_url_parameters() |
| 415 | + response = self.csrf_client.post('/oauth-with-scope/', params) |
| 416 | + self.assertIn(response.status_code, (status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN)) |
| 417 | + |
| 418 | + @unittest.skipUnless(oauth_provider, 'django-oauth-plus not installed') |
| 419 | + @unittest.skipUnless(oauth, 'oauth2 not installed') |
| 420 | + def test_post_form_with_write_resource_passing_auth(self): |
| 421 | + """Ensure POSTing with a write resource succeed""" |
| 422 | + read_write_access_token = self.token |
| 423 | + read_write_access_token.resource.is_readonly = False |
| 424 | + read_write_access_token.resource.save() |
| 425 | + params = self._create_authorization_url_parameters() |
| 426 | + response = self.csrf_client.post('/oauth-with-scope/', params) |
| 427 | + self.assertEqual(response.status_code, 200) |
| 428 | + |
392 | 429 |
|
393 | 430 | class OAuth2Tests(TestCase):
|
394 | 431 | """OAuth 2.0 authentication"""
|
@@ -514,3 +551,27 @@ def test_post_form_with_expired_access_token_failing_auth(self):
|
514 | 551 | response = self.csrf_client.post('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
|
515 | 552 | self.assertIn(response.status_code, (status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN))
|
516 | 553 | self.assertIn('Invalid token', response.content)
|
| 554 | + |
| 555 | + @unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed') |
| 556 | + def test_post_form_with_invalid_scope_failing_auth(self): |
| 557 | + """Ensure POSTing with a readonly scope instead of a write scope fails""" |
| 558 | + read_only_access_token = self.access_token |
| 559 | + read_only_access_token.scope = oauth2_provider_scope.SCOPE_NAME_DICT['read'] |
| 560 | + read_only_access_token.save() |
| 561 | + auth = self._create_authorization_header(token=read_only_access_token.token) |
| 562 | + params = self._client_credentials_params() |
| 563 | + response = self.csrf_client.get('/oauth2-with-scope-test/', params, HTTP_AUTHORIZATION=auth) |
| 564 | + self.assertEqual(response.status_code, 200) |
| 565 | + response = self.csrf_client.post('/oauth2-with-scope-test/', params, HTTP_AUTHORIZATION=auth) |
| 566 | + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) |
| 567 | + |
| 568 | + @unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed') |
| 569 | + def test_post_form_with_valid_scope_passing_auth(self): |
| 570 | + """Ensure POSTing with a write scope succeed""" |
| 571 | + read_write_access_token = self.access_token |
| 572 | + read_write_access_token.scope = oauth2_provider_scope.SCOPE_NAME_DICT['write'] |
| 573 | + read_write_access_token.save() |
| 574 | + auth = self._create_authorization_header(token=read_write_access_token.token) |
| 575 | + params = self._client_credentials_params() |
| 576 | + response = self.csrf_client.post('/oauth2-with-scope-test/', params, HTTP_AUTHORIZATION=auth) |
| 577 | + self.assertEqual(response.status_code, 200) |
0 commit comments