diff options
| author | Tom Christie | 2012-10-15 14:03:36 +0100 | 
|---|---|---|
| committer | Tom Christie | 2012-10-15 14:03:36 +0100 | 
| commit | 3c8f01b985396c9bfe802f0d1e25bbb59ea2a1a9 (patch) | |
| tree | 30535079a0f4f6900d318e8c46090bd135587b14 /rest_framework | |
| parent | 9c1fba3483b7e81da0744464dcf23a5f12711de2 (diff) | |
| download | django-rest-framework-3c8f01b985396c9bfe802f0d1e25bbb59ea2a1a9.tar.bz2 | |
Explicit CSRF failure message.  Fixes #60.
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/authentication.py | 22 | ||||
| -rw-r--r-- | rest_framework/renderers.py | 7 | ||||
| -rw-r--r-- | rest_framework/views.py | 6 | 
3 files changed, 25 insertions, 10 deletions
diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index d7624708..30c78ebc 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -4,6 +4,7 @@ Provides a set of pluggable authentication policies.  from django.contrib.auth import authenticate  from django.utils.encoding import smart_unicode, DjangoUnicodeDecodeError +from rest_framework import exceptions  from rest_framework.compat import CsrfViewMiddleware  from rest_framework.authtoken.models import Token  import base64 @@ -71,12 +72,23 @@ class SessionAuthentication(BaseAuthentication):          http_request = request._request          user = getattr(http_request, 'user', None) -        if user and user.is_active: -            # Enforce CSRF validation for session based authentication. -            resp = CsrfViewMiddleware().process_view(http_request, None, (), {}) +        # Unauthenticated, CSRF validation not required +        if not user or not user.is_active: +            return -            if resp is None:  # csrf passed -                return (user, None) +        # Enforce CSRF validation for session based authentication. +        class CSRFCheck(CsrfViewMiddleware): +            def _reject(self, request, reason): +                # Return the failure reason instead of an HttpResponse +                return reason + +        reason = CSRFCheck().process_view(http_request, None, (), {}) +        if reason: +            # CSRF failed, bail with explicit error message +            raise exceptions.PermissionDenied('CSRF Failed: %s' % reason) + +        # CSRF passed with authenticated user +        return (user, None)  class TokenAuthentication(BaseAuthentication): diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py index 2a3b0b6c..94d253c9 100644 --- a/rest_framework/renderers.py +++ b/rest_framework/renderers.py @@ -235,8 +235,11 @@ class BrowsableAPIRenderer(BaseRenderer):              return  # Cannot use form overloading          request = clone_request(request, method) -        if not view.has_permission(request): -            return  # Don't have permission +        try: +            if not view.has_permission(request): +                return  # Don't have permission +        except: +            return  # Don't have permission and exception explicitly raise          if method == 'DELETE' or method == 'OPTIONS':              return True  # Don't actually need to return a form diff --git a/rest_framework/views.py b/rest_framework/views.py index 92d4445f..62fc92f9 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -156,14 +156,14 @@ class APIView(View):          """          raise exceptions.Throttled(wait) -    def get_parser_context(self, request): +    def get_parser_context(self, http_request):          """          Returns a dict that is passed through to Parser.parse_stream(),          as the `parser_context` keyword argument.          """          return { -            'upload_handlers': request.upload_handlers, -            'meta': request.META, +            'upload_handlers': http_request.upload_handlers, +            'meta': http_request.META,          }      def get_renderer_context(self):  | 
