aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--djangorestframework/authenticators.py20
-rw-r--r--djangorestframework/request.py41
-rw-r--r--djangorestframework/resource.py10
-rw-r--r--djangorestframework/response.py6
4 files changed, 50 insertions, 27 deletions
diff --git a/djangorestframework/authenticators.py b/djangorestframework/authenticators.py
index 0d267b64..e382de10 100644
--- a/djangorestframework/authenticators.py
+++ b/djangorestframework/authenticators.py
@@ -10,26 +10,6 @@ from djangorestframework.utils import as_tuple
import base64
-class AuthenticatorMixin(object):
- """Adds pluggable authentication behaviour."""
-
- """The set of authenticators to use."""
- authenticators = None
-
- def authenticate(self, request):
- """Attempt to authenticate the request, returning an authentication context or None.
- An authentication context may be any object, although in many cases it will simply be a :class:`User` instance."""
-
- # Attempt authentication against each authenticator in turn,
- # and return None if no authenticators succeed in authenticating the request.
- for authenticator in as_tuple(self.authenticators):
- auth_context = authenticator(self).authenticate(request)
- if auth_context:
- return auth_context
-
- return None
-
-
class BaseAuthenticator(object):
"""All authenticators should extend BaseAuthenticator."""
diff --git a/djangorestframework/request.py b/djangorestframework/request.py
index 71ff8c0b..8a4330b4 100644
--- a/djangorestframework/request.py
+++ b/djangorestframework/request.py
@@ -9,7 +9,7 @@ from django.http.multipartparser import LimitBytes
from StringIO import StringIO
class RequestMixin(object):
- """Mixin behaviour to deal with requests."""
+ """Mixin class to provide request parsing behaviour."""
USE_FORM_OVERLOADING = True
METHOD_PARAM = "_method"
@@ -214,3 +214,42 @@ class RequestMixin(object):
+class AuthMixin(object):
+ """Mixin class to provide authentication and permissions."""
+ authenticators = ()
+ permitters = ()
+
+ @property
+ def auth(self):
+ if not hasattr(self, '_auth'):
+ self._auth = self._authenticate()
+ return self._auth
+
+ # TODO?
+ #@property
+ #def user(self):
+ # if not has_attr(self, '_user'):
+ # auth = self.auth
+ # if isinstance(auth, User...):
+ # self._user = auth
+ # else:
+ # self._user = getattr(auth, 'user', None)
+ # return self._user
+
+ def check_permissions(self):
+ if not self.permissions:
+ return
+
+ auth = self.auth
+ for permitter_cls in self.permitters:
+ permitter = permission_cls(self)
+ permitter.permit(auth)
+
+ def _authenticate(self):
+ for authenticator_cls in self.authenticators:
+ authenticator = authenticator_cls(self)
+ auth = authenticator.authenticate(self.request)
+ if auth:
+ return auth
+ return None
+
diff --git a/djangorestframework/resource.py b/djangorestframework/resource.py
index 6ec22073..e6290363 100644
--- a/djangorestframework/resource.py
+++ b/djangorestframework/resource.py
@@ -6,7 +6,7 @@ from djangorestframework.emitters import EmitterMixin
from djangorestframework.authenticators import AuthenticatorMixin
from djangorestframework.validators import FormValidatorMixin
from djangorestframework.response import Response, ResponseException
-from djangorestframework.request import RequestMixin
+from djangorestframework.request import RequestMixin, AuthMixin
from djangorestframework import emitters, parsers, authenticators, status
@@ -18,7 +18,7 @@ from djangorestframework import emitters, parsers, authenticators, status
__all__ = ['Resource']
-class Resource(EmitterMixin, AuthenticatorMixin, FormValidatorMixin, RequestMixin, View):
+class Resource(EmitterMixin, AuthMixin, FormValidatorMixin, RequestMixin, View):
"""Handles incoming requests and maps them to REST operations,
performing authentication, input deserialization, input validation, output serialization."""
@@ -139,7 +139,7 @@ class Resource(EmitterMixin, AuthenticatorMixin, FormValidatorMixin, RequestMixi
# Typically the context will be a user, or None if this is an anonymous request,
# but it could potentially be more complex (eg the context of a request key which
# has been signed against a particular set of permissions)
- auth_context = self.authenticate(request)
+ auth_context = self.auth
# If using a form POST with '_method'/'_content'/'_content_type' overrides, then alter
# self.method, self.content_type, self.CONTENT appropriately.
@@ -173,6 +173,10 @@ class Resource(EmitterMixin, AuthenticatorMixin, FormValidatorMixin, RequestMixi
except ResponseException, exc:
response = exc.response
+
+ except:
+ import traceback
+ traceback.print_exc()
# Always add these headers.
#
diff --git a/djangorestframework/response.py b/djangorestframework/response.py
index fb2e14a2..809e1754 100644
--- a/djangorestframework/response.py
+++ b/djangorestframework/response.py
@@ -8,7 +8,7 @@ class NoContent(object):
"""Used to indicate no body in http response.
(We cannot just use None, as that is a valid, serializable response object.)
- TODO: On relflection I'm going to get rid of this and just not support serailized 'None' responses.
+ TODO: On reflection I'm going to get rid of this and just not support serialized 'None' responses.
"""
pass
@@ -23,8 +23,8 @@ class Response(object):
@property
def status_text(self):
- """Return reason text corrosponding to our HTTP response status code.
- Provided for convienience."""
+ """Return reason text corresponding to our HTTP response status code.
+ Provided for convenience."""
return STATUS_CODE_TEXT.get(self.status, '')