# Imports
from django.conf import settings
from django.http import HttpResponseRedirect
from django.utils.http import is_safe_url
from django.contrib.auth.views import REDIRECT_FIELD_NAME
import re
from superdjango.conf import SUPERDJANGO
from superdjango.exceptions import NoUserInRequest
# Exports
__all__ = (
"LoginRequiredMiddleware",
)
# Constants
# Get the default redirect URL.
LOGIN_REDIRECT_URL = settings.LOGIN_REDIRECT_URL
# Get the LOGIN_URL in case we need to redirect.
LOGIN_URL = settings.LOGIN_URL
# The login URL must be excluded or you'd never be able to get to it.
EXCLUDED_URLS = [re.compile(LOGIN_URL.lstrip('/'))]
# Additional URLs may be added in settings.
if SUPERDJANGO.USER_LOGIN_EXCLUDED_URLS:
EXCLUDED_URLS += [re.compile(expr) for expr in SUPERDJANGO.USER_LOGIN_EXCLUDED_URLS]
# Middleware
[docs]class LoginRequiredMiddleware(object):
"""Require a user login for the whole site, except certain URLs.
.. code-block:: python
# settings.py
MIDDLEWARE = [
# ...
'superdjango.accounts.middleware.LoginRequiredMiddleware',
]
.. note::
This requires ``django.contrib.auth.middleware.AuthenticationMiddleware`` in ``MIDDLEWARE_CLASSES`` and
``django.core.context_processors.auth`` in your ``TEMPLATES`` configuration.
"""
# noinspection PyMethodMayBeStatic
[docs] def process_request(self, request):
"""Check the request for an authenticated user.
If the user is unauthenticated, a redirect is issued to the ``LOGIN_URL`` plus the current path using the
``REDIRECT_FIELD_NAME``.
:raise: NoUserInRequest
:raises: ``NoUserInRequest`` when `django.contrib.auth.middleware.AuthenticationMiddleware`` is not in
``MIDDLEWARE_CLASSES``.
"""
if not hasattr(request, "user"):
raise NoUserInRequest()
if not request.user.is_authenticated:
path = request.path_info.lstrip('/')
if not any(m.match(path) for m in EXCLUDED_URLS):
redirect_url = LOGIN_URL
if len(path) > 0 and is_safe_url(request.path_info, [request.get_host()]):
redirect_url = "%s?%s=%s" % (LOGIN_URL, REDIRECT_FIELD_NAME, request.path_info)
return HttpResponseRedirect(redirect_url)