aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/authentication.py
diff options
context:
space:
mode:
Diffstat (limited to 'rest_framework/authentication.py')
-rw-r--r--rest_framework/authentication.py104
1 files changed, 43 insertions, 61 deletions
diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py
index b507c5e1..24a8e336 100644
--- a/rest_framework/authentication.py
+++ b/rest_framework/authentication.py
@@ -3,12 +3,10 @@ Provides a set of pluggable authentication policies.
"""
from __future__ import unicode_literals
from django.contrib.auth import authenticate
-from django.utils.encoding import DjangoUnicodeDecodeError
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
-from rest_framework.compat import oauth_provider
+from rest_framework.compat import oauth, oauth_provider, oauth_provider_store
from rest_framework.authtoken.models import Token
import base64
@@ -61,11 +59,7 @@ class BasicAuthentication(BaseAuthentication):
except (TypeError, UnicodeDecodeError):
raise exceptions.AuthenticationFailed('Invalid basic header')
- try:
- userid, password = auth_parts[0], auth_parts[2]
- except DjangoUnicodeDecodeError:
- raise exceptions.AuthenticationFailed('Invalid basic header')
-
+ userid, password = auth_parts[0], auth_parts[2]
return self.authenticate_credentials(userid, password)
def authenticate_credentials(self, userid, password):
@@ -159,10 +153,12 @@ class TokenAuthentication(BaseAuthentication):
class OAuthAuthentication(BaseAuthentication):
- """rest_framework OAuth authentication backend using
- django-oath-plus and oauth2"""
+ """
+ OAuth 1.0a authentication backend using `django-oauth-plus` and `oauth2`.
+
+ Note: The `oauth2` package actually provides oauth1.0a support. Urg.
+ """
www_authenticate_realm = 'api'
- require_active = True
def __init__(self, **kwargs):
super(OAuthAuthentication, self).__init__(**kwargs)
@@ -173,50 +169,47 @@ class OAuthAuthentication(BaseAuthentication):
if oauth_provider is None:
raise ImproperlyConfigured("The 'django-oauth-plus' package could not be imported. It is required for use with the 'OAuthAuthentication' class.")
-
def authenticate(self, request):
"""
- Returns two-tuple of (user, auth token) if authentication succeeds, or None otherwise.
+ Returns two-tuple of (user, token) if authentication succeeds,
+ or None otherwise.
"""
- from oauth_provider.store import store
- if self.is_valid_request(request):
- oauth_request = oauth_provider.utils.get_oauth_request(request)
-
- if not self.check_nonce(request, oauth_request):
- raise exceptions.AuthenticationFailed("Nonce check failed")
+ if not self.is_valid_request(request):
+ return None
- try:
- consumer = store.get_consumer(request, oauth_request,
- oauth_request.get_parameter('oauth_consumer_key'))
- except oauth_provider.store.InvalidConsumerError, e:
- raise exceptions.AuthenticationFailed(e)
+ oauth_request = oauth_provider.utils.get_oauth_request(request)
- if consumer.status != oauth_provider.consts.ACCEPTED:
- raise exceptions.AuthenticationFailed('Invalid consumer key status: %s' % consumer.get_status_display())
+ if not self.check_nonce(request, oauth_request):
+ raise exceptions.AuthenticationFailed("Nonce check failed")
- try:
- token = store.get_access_token(request, oauth_request,
- consumer, oauth_request.get_parameter('oauth_token'))
+ try:
+ consumer_key = oauth_request.get_parameter('oauth_consumer_key')
+ consumer = oauth_provider_store.get_consumer(request, oauth_request, consumer_key)
+ except oauth_provider_store.InvalidConsumerError, err:
+ raise exceptions.AuthenticationFailed(err)
- except oauth_provider.store.InvalidTokenError:
- raise exceptions.AuthenticationFailed(
- 'Invalid access token: %s' % oauth_request.get_parameter('oauth_token'))
+ if consumer.status != oauth_provider.consts.ACCEPTED:
+ msg = 'Invalid consumer key status: %s' % consumer.get_status_display()
+ raise exceptions.AuthenticationFailed(msg)
- try:
- self.validate_token(request, consumer, token)
- except oauth.Error, e:
- raise exceptions.AuthenticationFailed(e.message)
+ try:
+ token_param = oauth_request.get_parameter('oauth_token')
+ token = oauth_provider_store.get_access_token(request, oauth_request, consumer, token_param)
+ except oauth_provider_store.InvalidTokenError:
+ msg = 'Invalid access token: %s' % oauth_request.get_parameter('oauth_token')
+ raise exceptions.AuthenticationFailed(msg)
- if not self.check_active(token.user):
- raise exceptions.AuthenticationFailed('User not active: %s' % token.user.username)
+ try:
+ self.validate_token(request, consumer, token)
+ except oauth.Error, e:
+ raise exceptions.AuthenticationFailed(e.message)
- if consumer and token:
- return (token.user, token)
+ user = token.user
- raise exceptions.AuthenticationFailed(
- 'You are not allowed to access this resource.')
+ if not user.is_active:
+ raise exceptions.AuthenticationFailed('User inactive or deleted: %s' % user.username)
- return None
+ return (token.user, token)
def authenticate_header(self, request):
return 'OAuth realm="%s"' % self.www_authenticate_realm
@@ -226,9 +219,7 @@ class OAuthAuthentication(BaseAuthentication):
Checks to ensure that all the OAuth parameter names are in the
provided ``params``.
"""
- from oauth_provider.consts import OAUTH_PARAMETERS_NAMES
-
- for param_name in OAUTH_PARAMETERS_NAMES:
+ for param_name in oauth_provider.consts.OAUTH_PARAMETERS_NAMES:
if param_name not in params:
return False
@@ -237,28 +228,19 @@ class OAuthAuthentication(BaseAuthentication):
def is_valid_request(self, request):
"""
Checks whether the required parameters are either in the HTTP
- ``Authorization`` header sent by some clients (the preferred method
- according to OAuth spec) or fall back to ``GET/POST``.
+ `Authorization` header sent by some clients.
+ (The preferred method according to OAuth spec.)
+ Or fall back to `GET/POST`.
"""
- auth_params = request.META.get("HTTP_AUTHORIZATION", [])
+ auth_params = request.META.get('HTTP_AUTHORIZATION', [])
return self.is_in(auth_params) or self.is_in(request.REQUEST)
def validate_token(self, request, consumer, token):
oauth_server, oauth_request = oauth_provider.utils.initialize_server_request(request)
return oauth_server.verify_request(oauth_request, consumer, token)
- def check_active(self, user):
+ def check_nonce(self, request, oauth_request):
"""
- Ensures the user has an active account.
-
- Optimized for the ``django.contrib.auth.models.User`` case.
+ Checks nonce of request.
"""
- if not self.require_active:
- # Ignore & move on.
- return True
-
- return user.is_active
-
- def check_nonce(self, request, oauth_request):
- """Checks nonce of request"""
return oauth_provider.store.store.check_nonce(request, oauth_request, oauth_request['oauth_nonce'])