Allow validation of CSRF cookie to be done in view using a CBV mixin or an helper function (refs #5617)
Use the CBV for a do-nothing use or on a function based view you must apply the decorators @csrf_exempt and @ensure_csrf_cookie on your view (in this order) and use utils.csrf_token_check(request, form) to check for the cookie before validating your form.
This commit is contained in:
parent
25ef99ffae
commit
31c743d879
|
@ -0,0 +1,26 @@
|
|||
from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt
|
||||
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.forms import Form
|
||||
|
||||
from . import utils
|
||||
|
||||
class ValidateCSRFMixin(object):
|
||||
'''Move CSRF token validation inside the form validation.
|
||||
|
||||
This mixin must always be the leftest one and if your class override
|
||||
form_valid() or dispatch() you should move those overrides in a base
|
||||
class.
|
||||
'''
|
||||
@method_decorator(csrf_exempt)
|
||||
def dispatch(self, *args, **kwargs):
|
||||
return super(ValidateCSRFMixin, self).dispatch(*args, **kwargs)
|
||||
|
||||
@method_decorator(ensure_csrf_cookie)
|
||||
def form_valid(self, *args, **kwargs):
|
||||
for form in args:
|
||||
if isinstance(form, Form):
|
||||
utils.csrf_token_check(self.request, form)
|
||||
if not form.is_valid():
|
||||
return self.form_invalid(form)
|
||||
return super(ValidateCSRFMixin, self).form_valid(*args, **kwargs)
|
|
@ -17,6 +17,7 @@ from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login
|
|||
from django import forms
|
||||
from django.forms.util import ErrorList
|
||||
from django.utils import html, http
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from authentic2.saml.saml2utils import filter_attribute_private_key, \
|
||||
filter_element_private_key
|
||||
|
@ -430,3 +431,11 @@ def attribute_values_to_identifier(values):
|
|||
normalized = normalize_attribute_values(values)
|
||||
assert len(normalized) == 1, 'multi-valued attribute cannot be used as an identifier'
|
||||
return list(normalized)[0]
|
||||
|
||||
def csrf_token_check(request, form):
|
||||
'''Check a request for CSRF cookie validation, and add an error to the form
|
||||
if check fails.
|
||||
'''
|
||||
if form.is_valid() and not getattr(request, 'csrf_processing_done', False):
|
||||
msg = _('The form was out of date, please try again.')
|
||||
form._errors[forms.forms.NON_FIELD_ERRORS] = ErrorList([msg])
|
||||
|
|
Loading…
Reference in New Issue