diff options
| author | Hisham Mahmood <hishammahmood41@gmail.com> | 2024-05-05 11:21:28 +0500 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2024-05-22 08:51:17 +0200 |
| commit | c7fc9f20b49b5889a9a8f47de45165ac443c1a21 (patch) | |
| tree | 113e55d5b047f479375638c1f17d9c127aedf618 /django/contrib/auth/middleware.py | |
| parent | 7857507c7fc43350701700d4215a37baea7655f0 (diff) | |
Fixed #31405 -- Added LoginRequiredMiddleware.
Co-authored-by: Adam Johnson <me@adamj.eu>
Co-authored-by: Mehmet İnce <mehmet@mehmetince.net>
Co-authored-by: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
Diffstat (limited to 'django/contrib/auth/middleware.py')
| -rw-r--r-- | django/contrib/auth/middleware.py | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/django/contrib/auth/middleware.py b/django/contrib/auth/middleware.py index 6b8dd4340e..761929d67d 100644 --- a/django/contrib/auth/middleware.py +++ b/django/contrib/auth/middleware.py @@ -1,9 +1,13 @@ from functools import partial +from urllib.parse import urlparse +from django.conf import settings from django.contrib import auth -from django.contrib.auth import load_backend +from django.contrib.auth import REDIRECT_FIELD_NAME, load_backend from django.contrib.auth.backends import RemoteUserBackend +from django.contrib.auth.views import redirect_to_login from django.core.exceptions import ImproperlyConfigured +from django.shortcuts import resolve_url from django.utils.deprecation import MiddlewareMixin from django.utils.functional import SimpleLazyObject @@ -34,6 +38,56 @@ class AuthenticationMiddleware(MiddlewareMixin): request.auser = partial(auser, request) +class LoginRequiredMiddleware(MiddlewareMixin): + """ + Middleware that redirects all unauthenticated requests to a login page. + + Views using the login_not_required decorator will not be redirected. + """ + + redirect_field_name = REDIRECT_FIELD_NAME + + def process_view(self, request, view_func, view_args, view_kwargs): + if request.user.is_authenticated: + return None + + if not getattr(view_func, "login_required", True): + return None + + return self.handle_no_permission(request, view_func) + + def get_login_url(self, view_func): + login_url = getattr(view_func, "login_url", None) or settings.LOGIN_URL + if not login_url: + raise ImproperlyConfigured( + "No login URL to redirect to. Define settings.LOGIN_URL or " + "provide a login_url via the 'django.contrib.auth.decorators." + "login_required' decorator." + ) + return str(login_url) + + def get_redirect_field_name(self, view_func): + return getattr(view_func, "redirect_field_name", self.redirect_field_name) + + def handle_no_permission(self, request, view_func): + path = request.build_absolute_uri() + resolved_login_url = resolve_url(self.get_login_url(view_func)) + # If the login url is the same scheme and net location then use the + # path as the "next" url. + login_scheme, login_netloc = urlparse(resolved_login_url)[:2] + current_scheme, current_netloc = urlparse(path)[:2] + if (not login_scheme or login_scheme == current_scheme) and ( + not login_netloc or login_netloc == current_netloc + ): + path = request.get_full_path() + + return redirect_to_login( + path, + resolved_login_url, + self.get_redirect_field_name(view_func), + ) + + class RemoteUserMiddleware(MiddlewareMixin): """ Middleware for utilizing web-server-provided authentication. |
