Commit 6332fd78 by Piotr Mitros

Fixed CSRF issue most likely introduced by move from Django templates

parent 6304feef
......@@ -13,6 +13,7 @@ from django.http import HttpResponse, Http404
from django.shortcuts import redirect
from django.template import Context, loader
from mitxmako.shortcuts import render_to_response, render_to_string
#from django.views.decorators.csrf import ensure_csrf_cookie
from django.db import connection
from lxml import etree
......
# Taken from Django 1.4
import warnings
from django.middleware.csrf import CsrfViewMiddleware, get_token
from django.utils.decorators import decorator_from_middleware, available_attrs
from functools import wraps
csrf_protect = decorator_from_middleware(CsrfViewMiddleware)
csrf_protect.__name__ = "csrf_protect"
csrf_protect.__doc__ = """
This decorator adds CSRF protection in exactly the same way as
CsrfViewMiddleware, but it can be used on a per view basis. Using both, or
using the decorator multiple times, is harmless and efficient.
"""
class _EnsureCsrfToken(CsrfViewMiddleware):
# We need this to behave just like the CsrfViewMiddleware, but not reject
# requests.
def _reject(self, request, reason):
return None
requires_csrf_token = decorator_from_middleware(_EnsureCsrfToken)
requires_csrf_token.__name__ = 'requires_csrf_token'
requires_csrf_token.__doc__ = """
Use this decorator on views that need a correct csrf_token available to
RequestContext, but without the CSRF protection that csrf_protect
enforces.
"""
class _EnsureCsrfCookie(CsrfViewMiddleware):
def _reject(self, request, reason):
return None
def process_view(self, request, callback, callback_args, callback_kwargs):
retval = super(_EnsureCsrfCookie, self).process_view(request, callback, callback_args, callback_kwargs)
# Forces process_response to send the cookie
get_token(request)
return retval
ensure_csrf_cookie = decorator_from_middleware(_EnsureCsrfCookie)
ensure_csrf_cookie.__name__ = 'ensure_csrf_cookie'
ensure_csrf_cookie.__doc__ = """
Use this decorator to ensure that a view sets a CSRF cookie, whether or not it
uses the csrf_token template tag, or the CsrfViewMiddleware is used.
"""
def csrf_response_exempt(view_func):
"""
Modifies a view function so that its response is exempt
from the post-processing of the CSRF middleware.
"""
warnings.warn("csrf_response_exempt is deprecated. It no longer performs a "
"function, and calls to it can be removed.",
PendingDeprecationWarning)
return view_func
def csrf_view_exempt(view_func):
"""
Marks a view function as being exempt from CSRF view protection.
"""
warnings.warn("csrf_view_exempt is deprecated. Use csrf_exempt instead.",
PendingDeprecationWarning)
return csrf_exempt(view_func)
def csrf_exempt(view_func):
"""
Marks a view function as being exempt from the CSRF view protection.
"""
# We could just do view_func.csrf_exempt = True, but decorators
# are nicer if they don't have side-effects, so we return a new
# function.
def wrapped_view(*args, **kwargs):
return view_func(*args, **kwargs)
wrapped_view.csrf_exempt = True
return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)
......@@ -15,6 +15,7 @@ from django.shortcuts import redirect
from mitxmako.shortcuts import render_to_response, render_to_string
from models import Registration, UserProfile
from django_future.csrf import ensure_csrf_cookie
log = logging.getLogger("mitx.user")
......@@ -24,7 +25,7 @@ def csrf_token(context):
return ''
return u'<div style="display:none"><input type="hidden" name="csrfmiddlewaretoken" value="%s" /></div>' % (csrf_token)
@ensure_csrf_cookie
def index(request):
if settings.COURSEWARE_ENABLED and request.user.is_authenticated():
return redirect('/courseware')
......@@ -44,6 +45,7 @@ def index(request):
# 'csrf': csrf_token })
# Need different levels of logging
@ensure_csrf_cookie
def login_user(request, error=""):
if 'email' not in request.POST or 'password' not in request.POST:
return render_to_response('login.html', {'error':error.replace('+',' ')})
......@@ -83,11 +85,13 @@ def login_user(request, error=""):
return HttpResponse(json.dumps({'success':False,
'error': 'Account not active. Check your e-mail.'}))
@ensure_csrf_cookie
def logout_user(request):
logout(request)
# print len(connection.queries), connection.queries
return redirect('/')
@ensure_csrf_cookie
def change_setting(request):
if not request.user.is_authenticated():
return redirect('/')
......@@ -104,6 +108,7 @@ def change_setting(request):
'language':up.language,
'location':up.location,}))
@ensure_csrf_cookie
def create_account(request, post_override=None):
js={'success':False}
......@@ -221,6 +226,7 @@ def create_random_account(create_account_function):
if settings.GENERATE_RANDOM_USER_CREDENTIALS:
create_account = create_random_account(create_account)
@ensure_csrf_cookie
def activate_account(request, key):
r=Registration.objects.filter(activation_key=key)
if len(r)==1:
......@@ -232,6 +238,7 @@ def activate_account(request, key):
return render_to_response("activation_invalid.html",{'csrf':csrf(request)['csrf_token']})
return HttpResponse("Unknown error. Please e-mail us to let us know how it happened.")
@ensure_csrf_cookie
def password_reset(request):
''' Attempts to send a password reset e-mail. '''
if request.method != "POST":
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment