diff options
| -rw-r--r-- | rest_framework/authentication.py | 7 | ||||
| -rw-r--r-- | rest_framework/compat.py | 15 | ||||
| -rw-r--r-- | rest_framework/tests/test_authentication.py | 20 | 
3 files changed, 29 insertions, 13 deletions
| diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index bca542eb..e491ce5f 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -9,7 +9,7 @@ from django.core.exceptions import ImproperlyConfigured  from rest_framework import exceptions, HTTP_HEADER_ENCODING  from rest_framework.compat import CsrfViewMiddleware  from rest_framework.compat import oauth, oauth_provider, oauth_provider_store -from rest_framework.compat import oauth2_provider, provider_now +from rest_framework.compat import oauth2_provider, provider_now, check_nonce  from rest_framework.authtoken.models import Token @@ -281,8 +281,9 @@ class OAuthAuthentication(BaseAuthentication):          """          Checks nonce of request, and return True if valid.          """ -        return oauth_provider_store.check_nonce(request, oauth_request, -            oauth_request['oauth_nonce'], oauth_request['oauth_timestamp']) +        oauth_nonce = oauth_request['oauth_nonce'] +        oauth_timestamp = oauth_request['oauth_timestamp'] +        return check_nonce(request, oauth_request, oauth_nonce, oauth_timestamp)  class OAuth2Authentication(BaseAuthentication): diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 05bd99e0..88211bec 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -7,6 +7,7 @@ versions of django/python, and compatibility wrappers around optional packages.  from __future__ import unicode_literals  import django +import inspect  from django.core.exceptions import ImproperlyConfigured  from django.conf import settings @@ -536,9 +537,23 @@ except ImportError:  try:      import oauth_provider      from oauth_provider.store import store as oauth_provider_store + +    # check_nonce's calling signature in django-oauth-plus changes sometime +    # between versions 2.0 and 2.2.1 +    def check_nonce(request, oauth_request, oauth_nonce, oauth_timestamp): +        check_nonce_args = inspect.getargspec(oauth_provider_store.check_nonce).args +        if 'timestamp' in check_nonce_args: +            return oauth_provider_store.check_nonce( +                request, oauth_request, oauth_nonce, oauth_timestamp +            ) +        return oauth_provider_store.check_nonce( +            request, oauth_request, oauth_nonce +        ) +  except (ImportError, ImproperlyConfigured):      oauth_provider = None      oauth_provider_store = None +    check_nonce = None  # OAuth 2 support is optional  try: diff --git a/rest_framework/tests/test_authentication.py b/rest_framework/tests/test_authentication.py index fe11423d..f072b81b 100644 --- a/rest_framework/tests/test_authentication.py +++ b/rest_framework/tests/test_authentication.py @@ -249,7 +249,7 @@ class OAuthTests(TestCase):      def setUp(self):          # these imports are here because oauth is optional and hiding them in try..except block or compat          # could obscure problems if something breaks -        from oauth_provider.models import Consumer, Resource +        from oauth_provider.models import Consumer, Scope          from oauth_provider.models import Token as OAuthToken          from oauth_provider import consts @@ -269,8 +269,8 @@ class OAuthTests(TestCase):          self.consumer = Consumer.objects.create(key=self.CONSUMER_KEY, secret=self.CONSUMER_SECRET,              name='example', user=self.user, status=self.consts.ACCEPTED) -        self.resource = Resource.objects.create(name="resource name", url="api/") -        self.token = OAuthToken.objects.create(user=self.user, consumer=self.consumer, resource=self.resource, +        self.scope = Scope.objects.create(name="resource name", url="api/") +        self.token = OAuthToken.objects.create(user=self.user, consumer=self.consumer, scope=self.scope,              token_type=OAuthToken.ACCESS, key=self.TOKEN_KEY, secret=self.TOKEN_SECRET, is_approved=True          ) @@ -398,10 +398,10 @@ class OAuthTests(TestCase):      @unittest.skipUnless(oauth_provider, 'django-oauth-plus not installed')      @unittest.skipUnless(oauth, 'oauth2 not installed')      def test_get_form_with_readonly_resource_passing_auth(self): -        """Ensure POSTing with a readonly resource instead of a write scope fails""" +        """Ensure POSTing with a readonly scope instead of a write scope fails"""          read_only_access_token = self.token -        read_only_access_token.resource.is_readonly = True -        read_only_access_token.resource.save() +        read_only_access_token.scope.is_readonly = True +        read_only_access_token.scope.save()          params = self._create_authorization_url_parameters()          response = self.csrf_client.get('/oauth-with-scope/', params)          self.assertEqual(response.status_code, 200) @@ -411,8 +411,8 @@ class OAuthTests(TestCase):      def test_post_form_with_readonly_resource_failing_auth(self):          """Ensure POSTing with a readonly resource instead of a write scope fails"""          read_only_access_token = self.token -        read_only_access_token.resource.is_readonly = True -        read_only_access_token.resource.save() +        read_only_access_token.scope.is_readonly = True +        read_only_access_token.scope.save()          params = self._create_authorization_url_parameters()          response = self.csrf_client.post('/oauth-with-scope/', params)          self.assertIn(response.status_code, (status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN)) @@ -422,8 +422,8 @@ class OAuthTests(TestCase):      def test_post_form_with_write_resource_passing_auth(self):          """Ensure POSTing with a write resource succeed"""          read_write_access_token = self.token -        read_write_access_token.resource.is_readonly = False -        read_write_access_token.resource.save() +        read_write_access_token.scope.is_readonly = False +        read_write_access_token.scope.save()          params = self._create_authorization_url_parameters()          auth = self._create_authorization_header()          response = self.csrf_client.post('/oauth-with-scope/', params, HTTP_AUTHORIZATION=auth) | 
