2011-03-28 10:11:19 +08:00
|
|
|
from functools import wraps
|
2009-10-27 08:36:34 +08:00
|
|
|
|
2015-01-28 20:35:27 +08:00
|
|
|
from django.middleware.csrf import CsrfViewMiddleware, get_token
|
2017-01-22 02:20:17 +08:00
|
|
|
from django.utils.decorators import decorator_from_middleware
|
2015-01-28 20:35:27 +08:00
|
|
|
|
2009-10-27 08:36:34 +08:00
|
|
|
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.
|
|
|
|
"""
|
|
|
|
|
2010-10-28 19:47:15 +08:00
|
|
|
|
|
|
|
class _EnsureCsrfToken(CsrfViewMiddleware):
|
2017-01-25 04:36:07 +08:00
|
|
|
# Behave like CsrfViewMiddleware but don't reject requests or log warnings.
|
2010-10-28 19:47:15 +08:00
|
|
|
def _reject(self, request, reason):
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
requires_csrf_token = decorator_from_middleware(_EnsureCsrfToken)
|
|
|
|
requires_csrf_token.__name__ = 'requires_csrf_token'
|
2010-12-23 05:49:20 +08:00
|
|
|
requires_csrf_token.__doc__ = """
|
2010-10-28 19:47:15 +08:00
|
|
|
Use this decorator on views that need a correct csrf_token available to
|
|
|
|
RequestContext, but without the CSRF protection that csrf_protect
|
|
|
|
enforces.
|
|
|
|
"""
|
|
|
|
|
2011-05-10 05:35:24 +08:00
|
|
|
|
|
|
|
class _EnsureCsrfCookie(CsrfViewMiddleware):
|
|
|
|
def _reject(self, request, reason):
|
|
|
|
return None
|
|
|
|
|
|
|
|
def process_view(self, request, callback, callback_args, callback_kwargs):
|
2017-01-21 21:13:44 +08:00
|
|
|
retval = super().process_view(request, callback, callback_args, callback_kwargs)
|
2017-01-25 04:36:07 +08:00
|
|
|
# Force process_response to send the cookie
|
2011-05-10 05:35:24 +08:00
|
|
|
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.
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
2011-03-31 01:35:41 +08:00
|
|
|
def csrf_exempt(view_func):
|
2017-01-25 04:36:07 +08:00
|
|
|
"""Mark a view function as being exempt from the CSRF view protection."""
|
|
|
|
# view_func.csrf_exempt = True would also work, but decorators are nicer
|
|
|
|
# if they don't have side effects, so return a new function.
|
2009-10-27 08:36:34 +08:00
|
|
|
def wrapped_view(*args, **kwargs):
|
|
|
|
return view_func(*args, **kwargs)
|
|
|
|
wrapped_view.csrf_exempt = True
|
2017-01-22 02:20:17 +08:00
|
|
|
return wraps(view_func)(wrapped_view)
|