From 1761b24efb04fc623ff53bbd7fa2acee054aa1bd Mon Sep 17 00:00:00 2001 From: Fabio Caccamo Date: Mon, 11 Dec 2023 22:39:29 +0100 Subject: [PATCH] Add `MAINTENANCE_MODE_LOGOUT_AUTHENTICATED_USER` setting support. #139 --- README.md | 5 ++++ maintenance_mode/http.py | 7 +++++- maintenance_mode/settings.py | 3 +++ tests/tests.py | 48 +++++++++++++++++++++++++++--------- 4 files changed, 51 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 6a780bf..9e7b6f9 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,11 @@ MAINTENANCE_MODE_IGNORE_URLS = () MAINTENANCE_MODE_IGNORE_TESTS = False ``` +```python +# if True authenticated users will be logged out from their current session +MAINTENANCE_MODE_LOGOUT_AUTHENTICATED_USER = False +``` + ```python # the absolute url where users will be redirected to during maintenance-mode MAINTENANCE_MODE_REDIRECT_URL = None diff --git a/maintenance_mode/http.py b/maintenance_mode/http.py index 816934f..a8c3e37 100644 --- a/maintenance_mode/http.py +++ b/maintenance_mode/http.py @@ -2,6 +2,7 @@ import sys from django.conf import settings +from django.contrib.auth import logout from django.core.exceptions import ImproperlyConfigured from django.shortcuts import redirect, render from django.urls import NoReverseMatch, Resolver404, resolve, reverse @@ -39,7 +40,7 @@ def get_maintenance_response(request): request, settings.MAINTENANCE_MODE_TEMPLATE, status=settings.MAINTENANCE_MODE_STATUS_CODE, - **kwargs + **kwargs, ) response["Retry-After"] = settings.MAINTENANCE_MODE_RETRY_AFTER add_never_cache_headers(response) @@ -87,6 +88,10 @@ def _need_maintenance_ignore_users(request): user = request.user + if settings.MAINTENANCE_MODE_LOGOUT_AUTHENTICATED_USER and user.is_authenticated: + logout(request) + user = request.user + if settings.MAINTENANCE_MODE_IGNORE_ANONYMOUS_USER and user.is_anonymous: return False diff --git a/maintenance_mode/settings.py b/maintenance_mode/settings.py index a1711ef..0e79437 100644 --- a/maintenance_mode/settings.py +++ b/maintenance_mode/settings.py @@ -37,6 +37,9 @@ if not hasattr(settings, "MAINTENANCE_MODE_IGNORE_URLS"): settings.MAINTENANCE_MODE_IGNORE_URLS = None +if not hasattr(settings, "MAINTENANCE_MODE_LOGOUT_AUTHENTICATED_USER"): + settings.MAINTENANCE_MODE_LOGOUT_AUTHENTICATED_USER = False + if not hasattr(settings, "MAINTENANCE_MODE_REDIRECT_URL"): settings.MAINTENANCE_MODE_REDIRECT_URL = None diff --git a/tests/tests.py b/tests/tests.py index 6579571..ecd9010 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1,6 +1,7 @@ import os import re import sys +from importlib import import_module from io import StringIO from tempfile import mkstemp from unittest.mock import patch @@ -99,30 +100,32 @@ def tearDown(self): def assertMaintenanceResponse(self, response): self.assertTemplateUsed(settings.MAINTENANCE_MODE_TEMPLATE) + self.assertTrue(response is not None) self.assertEqual(response.status_code, settings.MAINTENANCE_MODE_STATUS_CODE) def assertOkResponse(self, response): + self.assertTrue(response is not None) self.assertEqual(response.status_code, 200) - def __get_anonymous_user_request(self, url): + def __get_request_for_user_and_url(self, user, url): request = self.request_factory.get(url) - request.user = self.anonymous_user + request.user = user + engine = import_module(settings.SESSION_ENGINE) + request.session = engine.SessionStore() + request.session.save() return request + def __get_anonymous_user_request(self, url): + return self.__get_request_for_user_and_url(self.anonymous_user, url) + def __get_authenticated_user_request(self, url): - request = self.request_factory.get(url) - request.user = self.authenticated_user - return request + return self.__get_request_for_user_and_url(self.authenticated_user, url) def __get_staff_user_request(self, url): - request = self.request_factory.get(url) - request.user = self.staff_user - return request + return self.__get_request_for_user_and_url(self.staff_user, url) def __get_superuser_request(self, url): - request = self.request_factory.get(url) - request.user = self.superuser - return request + return self.__get_request_for_user_and_url(self.superuser, url) def __login_staff_user(self): self.client.login(username="staff-user", password="test") @@ -826,6 +829,29 @@ def test_middleware_ignore_ip_addresses_get_client_ip_address(self): response = self.middleware.process_request(request) self.assertMaintenanceResponse(response) + def test_middleware_logout_authenticated_user(self): + self.__reset_state() + + settings.MAINTENANCE_MODE = True + + settings.MAINTENANCE_MODE_IGNORE_ANONYMOUS_USER = True + settings.MAINTENANCE_MODE_LOGOUT_AUTHENTICATED_USER = True + request = self.__get_authenticated_user_request("/") + response = self.middleware.process_request(request) + self.assertEqual(response, None) + + settings.MAINTENANCE_MODE_IGNORE_ANONYMOUS_USER = False + settings.MAINTENANCE_MODE_LOGOUT_AUTHENTICATED_USER = True + request = self.__get_authenticated_user_request("/") + response = self.middleware.process_request(request) + self.assertMaintenanceResponse(response) + + settings.MAINTENANCE_MODE_IGNORE_ANONYMOUS_USER = False + settings.MAINTENANCE_MODE_LOGOUT_AUTHENTICATED_USER = False + request = self.__get_authenticated_user_request("/") + response = self.middleware.process_request(request) + self.assertMaintenanceResponse(response) + def test_middleware_ignore_anonymous_user(self): self.__reset_state()