diff options
Diffstat (limited to 'rest_framework/authentication.py')
| -rw-r--r-- | rest_framework/authentication.py | 104 |
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']) |
