2024-05-05 06:21:28 +00:00
|
|
|
from django.conf import settings
|
|
|
|
from django.contrib.auth import REDIRECT_FIELD_NAME
|
|
|
|
from django.contrib.auth.middleware import (
|
|
|
|
AuthenticationMiddleware,
|
|
|
|
LoginRequiredMiddleware,
|
|
|
|
)
|
2014-04-01 00:16:09 +00:00
|
|
|
from django.contrib.auth.models import User
|
2021-03-10 13:08:37 +00:00
|
|
|
from django.core.exceptions import ImproperlyConfigured
|
2019-09-26 17:06:35 +00:00
|
|
|
from django.http import HttpRequest, HttpResponse
|
2024-05-05 06:21:28 +00:00
|
|
|
from django.test import TestCase, modify_settings, override_settings
|
|
|
|
from django.urls import reverse
|
2014-04-01 00:16:09 +00:00
|
|
|
|
|
|
|
|
2015-09-03 00:50:34 +00:00
|
|
|
class TestAuthenticationMiddleware(TestCase):
|
2018-11-24 02:24:25 +00:00
|
|
|
@classmethod
|
|
|
|
def setUpTestData(cls):
|
|
|
|
cls.user = User.objects.create_user(
|
|
|
|
"test_user", "test@example.com", "test_password"
|
|
|
|
)
|
|
|
|
|
2014-04-01 00:16:09 +00:00
|
|
|
def setUp(self):
|
2019-09-26 17:06:35 +00:00
|
|
|
self.middleware = AuthenticationMiddleware(lambda req: HttpResponse())
|
2015-09-03 00:50:34 +00:00
|
|
|
self.client.force_login(self.user)
|
2014-12-03 12:33:44 +00:00
|
|
|
self.request = HttpRequest()
|
|
|
|
self.request.session = self.client.session
|
|
|
|
|
2015-09-03 00:50:34 +00:00
|
|
|
def test_no_password_change_doesnt_invalidate_session(self):
|
|
|
|
self.request.session = self.client.session
|
2019-09-26 17:06:35 +00:00
|
|
|
self.middleware(self.request)
|
2020-04-29 14:45:00 +00:00
|
|
|
self.assertIsNotNone(self.request.user)
|
|
|
|
self.assertFalse(self.request.user.is_anonymous)
|
|
|
|
|
2015-09-03 00:50:34 +00:00
|
|
|
def test_changed_password_invalidates_session(self):
|
|
|
|
# After password change, user should be anonymous
|
2014-12-03 12:33:44 +00:00
|
|
|
self.user.set_password("new_password")
|
|
|
|
self.user.save()
|
2019-09-26 17:06:35 +00:00
|
|
|
self.middleware(self.request)
|
2014-12-03 12:33:44 +00:00
|
|
|
self.assertIsNotNone(self.request.user)
|
2016-04-02 11:18:26 +00:00
|
|
|
self.assertTrue(self.request.user.is_anonymous)
|
2014-12-03 12:33:44 +00:00
|
|
|
# session should be flushed
|
|
|
|
self.assertIsNone(self.request.session.session_key)
|
2019-10-23 06:04:14 +00:00
|
|
|
|
|
|
|
def test_no_session(self):
|
|
|
|
msg = (
|
|
|
|
"The Django authentication middleware requires session middleware "
|
|
|
|
"to be installed. Edit your MIDDLEWARE setting to insert "
|
|
|
|
"'django.contrib.sessions.middleware.SessionMiddleware' before "
|
|
|
|
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
|
|
|
|
)
|
2021-03-10 13:08:37 +00:00
|
|
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
2019-10-23 06:04:14 +00:00
|
|
|
self.middleware(HttpRequest())
|
2023-02-13 23:24:35 +00:00
|
|
|
|
|
|
|
async def test_auser(self):
|
|
|
|
self.middleware(self.request)
|
|
|
|
auser = await self.request.auser()
|
|
|
|
self.assertEqual(auser, self.user)
|
|
|
|
auser_second = await self.request.auser()
|
|
|
|
self.assertIs(auser, auser_second)
|
2024-05-05 06:21:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
@override_settings(ROOT_URLCONF="auth_tests.urls")
|
|
|
|
@modify_settings(
|
|
|
|
MIDDLEWARE={"append": "django.contrib.auth.middleware.LoginRequiredMiddleware"}
|
|
|
|
)
|
|
|
|
class TestLoginRequiredMiddleware(TestCase):
|
|
|
|
@classmethod
|
|
|
|
def setUpTestData(cls):
|
|
|
|
cls.user = User.objects.create_user(
|
|
|
|
"test_user", "test@example.com", "test_password"
|
|
|
|
)
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
self.middleware = LoginRequiredMiddleware(lambda req: HttpResponse())
|
|
|
|
self.request = HttpRequest()
|
|
|
|
|
|
|
|
def test_public_paths(self):
|
|
|
|
paths = ["public_view", "public_function_view"]
|
|
|
|
for path in paths:
|
|
|
|
response = self.client.get(f"/{path}/")
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
|
|
|
|
def test_protected_paths(self):
|
|
|
|
paths = ["protected_view", "protected_function_view"]
|
|
|
|
for path in paths:
|
|
|
|
response = self.client.get(f"/{path}/")
|
|
|
|
self.assertRedirects(
|
|
|
|
response,
|
|
|
|
settings.LOGIN_URL + f"?next=/{path}/",
|
|
|
|
fetch_redirect_response=False,
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_login_required_paths(self):
|
|
|
|
paths = ["login_required_cbv_view", "login_required_decorator_view"]
|
|
|
|
for path in paths:
|
|
|
|
response = self.client.get(f"/{path}/")
|
|
|
|
self.assertRedirects(
|
|
|
|
response,
|
|
|
|
"/custom_login/" + f"?step=/{path}/",
|
|
|
|
fetch_redirect_response=False,
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_admin_path(self):
|
|
|
|
admin_url = reverse("admin:index")
|
|
|
|
response = self.client.get(admin_url)
|
|
|
|
self.assertRedirects(
|
|
|
|
response,
|
|
|
|
reverse("admin:login") + f"?next={admin_url}",
|
|
|
|
target_status_code=200,
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_non_existent_path(self):
|
|
|
|
response = self.client.get("/non_existent/")
|
|
|
|
self.assertEqual(response.status_code, 404)
|
|
|
|
|
|
|
|
def test_paths_with_logged_in_user(self):
|
|
|
|
paths = [
|
|
|
|
"public_view",
|
|
|
|
"public_function_view",
|
|
|
|
"protected_view",
|
|
|
|
"protected_function_view",
|
|
|
|
"login_required_cbv_view",
|
|
|
|
"login_required_decorator_view",
|
|
|
|
]
|
|
|
|
self.client.login(username="test_user", password="test_password")
|
|
|
|
for path in paths:
|
|
|
|
response = self.client.get(f"/{path}/")
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
|
|
|
|
def test_get_login_url_from_view_func(self):
|
|
|
|
def view_func(request):
|
|
|
|
return HttpResponse()
|
|
|
|
|
|
|
|
view_func.login_url = "/custom_login/"
|
|
|
|
login_url = self.middleware.get_login_url(view_func)
|
|
|
|
self.assertEqual(login_url, "/custom_login/")
|
|
|
|
|
|
|
|
@override_settings(LOGIN_URL="/settings_login/")
|
|
|
|
def test_get_login_url_from_settings(self):
|
|
|
|
login_url = self.middleware.get_login_url(lambda: None)
|
|
|
|
self.assertEqual(login_url, "/settings_login/")
|
|
|
|
|
|
|
|
@override_settings(LOGIN_URL=None)
|
|
|
|
def test_get_login_url_no_login_url(self):
|
|
|
|
with self.assertRaises(ImproperlyConfigured) as e:
|
|
|
|
self.middleware.get_login_url(lambda: None)
|
|
|
|
self.assertEqual(
|
|
|
|
str(e.exception),
|
|
|
|
"No login URL to redirect to. Define settings.LOGIN_URL or provide "
|
|
|
|
"a login_url via the 'django.contrib.auth.decorators.login_required' "
|
|
|
|
"decorator.",
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_get_redirect_field_name_from_view_func(self):
|
|
|
|
def view_func(request):
|
|
|
|
return HttpResponse()
|
|
|
|
|
|
|
|
view_func.redirect_field_name = "next_page"
|
|
|
|
redirect_field_name = self.middleware.get_redirect_field_name(view_func)
|
|
|
|
self.assertEqual(redirect_field_name, "next_page")
|
|
|
|
|
|
|
|
@override_settings(
|
|
|
|
MIDDLEWARE=[
|
|
|
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
|
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
|
|
|
"auth_tests.test_checks.LoginRequiredMiddlewareSubclass",
|
|
|
|
],
|
|
|
|
LOGIN_URL="/settings_login/",
|
|
|
|
)
|
|
|
|
def test_login_url_resolve_logic(self):
|
|
|
|
paths = ["login_required_cbv_view", "login_required_decorator_view"]
|
|
|
|
for path in paths:
|
|
|
|
response = self.client.get(f"/{path}/")
|
|
|
|
self.assertRedirects(
|
|
|
|
response,
|
|
|
|
"/custom_login/" + f"?step=/{path}/",
|
|
|
|
fetch_redirect_response=False,
|
|
|
|
)
|
|
|
|
paths = ["protected_view", "protected_function_view"]
|
|
|
|
for path in paths:
|
|
|
|
response = self.client.get(f"/{path}/")
|
|
|
|
self.assertRedirects(
|
|
|
|
response,
|
|
|
|
f"/settings_login/?redirect_to=/{path}/",
|
|
|
|
fetch_redirect_response=False,
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_get_redirect_field_name_default(self):
|
|
|
|
redirect_field_name = self.middleware.get_redirect_field_name(lambda: None)
|
|
|
|
self.assertEqual(redirect_field_name, REDIRECT_FIELD_NAME)
|