aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2013-03-29 06:42:24 -0700
committerTom Christie2013-03-29 06:42:24 -0700
commita69262a1cd03667416d94080101f735039aa084f (patch)
tree40e849db9b542fd6743437b323610819e43c7b2b
parentff3ebd979dab9a358a4708ea1de0fd8ebf121157 (diff)
parentfa61b2b2f10bf07e3cb87ca947ce7f0ca51a2ede (diff)
downloaddjango-rest-framework-a69262a1cd03667416d94080101f735039aa084f.tar.bz2
Merge pull request #767 from tomchristie/fix-oauth2-token-only
Fix OAuth 2 token only
-rw-r--r--docs/api-guide/authentication.md2
-rw-r--r--rest_framework/authentication.py26
-rw-r--r--rest_framework/compat.py2
-rw-r--r--rest_framework/tests/authentication.py44
4 files changed, 23 insertions, 51 deletions
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index 541c6575..f1dd6f5f 100644
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -294,7 +294,7 @@ The only thing needed to make the `OAuth2Authentication` class work is to insert
The command line to test the authentication looks like:
- curl -H "Authorization: Bearer <your-access-token>" http://localhost:8000/api/?client_id=YOUR_CLIENT_ID\&client_secret=YOUR_CLIENT_SECRET
+ curl -H "Authorization: Bearer <your-access-token>" http://localhost:8000/api/
---
diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py
index 8f4ec536..145d4295 100644
--- a/rest_framework/authentication.py
+++ b/rest_framework/authentication.py
@@ -2,14 +2,16 @@
Provides a set of pluggable authentication policies.
"""
from __future__ import unicode_literals
+import base64
+from datetime import datetime
+
from django.contrib.auth import authenticate
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, oauth2_provider_forms, oauth2_provider_backends
+from rest_framework.compat import oauth2_provider, oauth2_provider_forms
from rest_framework.authtoken.models import Token
-import base64
def get_authorization_header(request):
@@ -315,21 +317,15 @@ class OAuth2Authentication(BaseAuthentication):
Authenticate the request, given the access token.
"""
- # Authenticate the client
- oauth2_client_form = oauth2_provider_forms.ClientAuthForm(request.REQUEST)
- if not oauth2_client_form.is_valid():
- raise exceptions.AuthenticationFailed('Client could not be validated')
- client = oauth2_client_form.cleaned_data.get('client')
-
- # Retrieve the `OAuth2AccessToken` instance from the access_token
- auth_backend = oauth2_provider_backends.AccessTokenBackend()
- token = auth_backend.authenticate(access_token, client)
- if token is None:
+ try:
+ token = oauth2_provider.models.AccessToken.objects.select_related('user')
+ # TODO: Change to timezone aware datetime when oauth2_provider add
+ # support to it.
+ token = token.get(token=access_token, expires__gt=datetime.now())
+ except oauth2_provider.models.AccessToken.DoesNotExist:
raise exceptions.AuthenticationFailed('Invalid token')
- user = token.user
-
- if not user.is_active:
+ if not token.user.is_active:
msg = 'User inactive or deleted: %s' % user.username
raise exceptions.AuthenticationFailed(msg)
diff --git a/rest_framework/compat.py b/rest_framework/compat.py
index f0bb9c08..6551723a 100644
--- a/rest_framework/compat.py
+++ b/rest_framework/compat.py
@@ -476,14 +476,12 @@ except ImportError:
# OAuth 2 support is optional
try:
import provider.oauth2 as oauth2_provider
- from provider.oauth2 import backends as oauth2_provider_backends
from provider.oauth2 import models as oauth2_provider_models
from provider.oauth2 import forms as oauth2_provider_forms
from provider import scope as oauth2_provider_scope
from provider import constants as oauth2_constants
except ImportError:
oauth2_provider = None
- oauth2_provider_backends = None
oauth2_provider_models = None
oauth2_provider_forms = None
oauth2_provider_scope = None
diff --git a/rest_framework/tests/authentication.py b/rest_framework/tests/authentication.py
index b663ca48..8e6d3e51 100644
--- a/rest_framework/tests/authentication.py
+++ b/rest_framework/tests/authentication.py
@@ -466,17 +466,13 @@ class OAuth2Tests(TestCase):
def _create_authorization_header(self, token=None):
return "Bearer {0}".format(token or self.access_token.token)
- def _client_credentials_params(self):
- return {'client_id': self.CLIENT_ID, 'client_secret': self.CLIENT_SECRET}
-
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
def test_get_form_with_wrong_authorization_header_token_type_failing(self):
"""Ensure that a wrong token type lead to the correct HTTP error status code"""
auth = "Wrong token-type-obsviously"
response = self.csrf_client.get('/oauth2-test/', {}, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 401)
- params = self._client_credentials_params()
- response = self.csrf_client.get('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.get('/oauth2-test/', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 401)
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
@@ -485,8 +481,7 @@ class OAuth2Tests(TestCase):
auth = "Bearer wrong token format"
response = self.csrf_client.get('/oauth2-test/', {}, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 401)
- params = self._client_credentials_params()
- response = self.csrf_client.get('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.get('/oauth2-test/', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 401)
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
@@ -495,33 +490,21 @@ class OAuth2Tests(TestCase):
auth = "Bearer wrong-token"
response = self.csrf_client.get('/oauth2-test/', {}, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 401)
- params = self._client_credentials_params()
- response = self.csrf_client.get('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
- self.assertEqual(response.status_code, 401)
-
- @unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
- def test_get_form_with_wrong_client_data_failing_auth(self):
- """Ensure GETing form over OAuth with incorrect client credentials fails"""
- auth = self._create_authorization_header()
- params = self._client_credentials_params()
- params['client_id'] += 'a'
- response = self.csrf_client.get('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.get('/oauth2-test/', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 401)
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
def test_get_form_passing_auth(self):
"""Ensure GETing form over OAuth with correct client credentials succeed"""
auth = self._create_authorization_header()
- params = self._client_credentials_params()
- response = self.csrf_client.get('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.get('/oauth2-test/', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 200)
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
def test_post_form_passing_auth(self):
"""Ensure POSTing form over OAuth with correct credentials passes and does not require CSRF"""
auth = self._create_authorization_header()
- params = self._client_credentials_params()
- response = self.csrf_client.post('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.post('/oauth2-test/', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 200)
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
@@ -529,16 +512,14 @@ class OAuth2Tests(TestCase):
"""Ensure POSTing when there is no OAuth access token in db fails"""
self.access_token.delete()
auth = self._create_authorization_header()
- params = self._client_credentials_params()
- response = self.csrf_client.post('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.post('/oauth2-test/', HTTP_AUTHORIZATION=auth)
self.assertIn(response.status_code, (status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN))
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
def test_post_form_with_refresh_token_failing_auth(self):
"""Ensure POSTing with refresh token instead of access token fails"""
auth = self._create_authorization_header(token=self.refresh_token.token)
- params = self._client_credentials_params()
- response = self.csrf_client.post('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.post('/oauth2-test/', HTTP_AUTHORIZATION=auth)
self.assertIn(response.status_code, (status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN))
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
@@ -547,8 +528,7 @@ class OAuth2Tests(TestCase):
self.access_token.expires = datetime.datetime.now() - datetime.timedelta(seconds=10) # 10 seconds late
self.access_token.save()
auth = self._create_authorization_header()
- params = self._client_credentials_params()
- response = self.csrf_client.post('/oauth2-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.post('/oauth2-test/', HTTP_AUTHORIZATION=auth)
self.assertIn(response.status_code, (status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN))
self.assertIn('Invalid token', response.content)
@@ -559,10 +539,9 @@ class OAuth2Tests(TestCase):
read_only_access_token.scope = oauth2_provider_scope.SCOPE_NAME_DICT['read']
read_only_access_token.save()
auth = self._create_authorization_header(token=read_only_access_token.token)
- params = self._client_credentials_params()
- response = self.csrf_client.get('/oauth2-with-scope-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.get('/oauth2-with-scope-test/', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 200)
- response = self.csrf_client.post('/oauth2-with-scope-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.post('/oauth2-with-scope-test/', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
@unittest.skipUnless(oauth2_provider, 'django-oauth2-provider not installed')
@@ -572,6 +551,5 @@ class OAuth2Tests(TestCase):
read_write_access_token.scope = oauth2_provider_scope.SCOPE_NAME_DICT['write']
read_write_access_token.save()
auth = self._create_authorization_header(token=read_write_access_token.token)
- params = self._client_credentials_params()
- response = self.csrf_client.post('/oauth2-with-scope-test/', params, HTTP_AUTHORIZATION=auth)
+ response = self.csrf_client.post('/oauth2-with-scope-test/', HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 200)