Explicit CSRF failure message. Fixes #60.

This commit is contained in:
Tom Christie 2012-10-15 14:03:36 +01:00
parent 9c1fba3483
commit 3c8f01b985
3 changed files with 25 additions and 10 deletions

View File

@ -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):

View File

@ -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

View File

@ -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):