2017-05-27 20:35:02 +08:00
|
|
|
from django.apps import apps
|
2016-02-19 08:58:30 +08:00
|
|
|
from django.contrib.auth import authenticate, signals
|
2012-09-18 03:50:13 +08:00
|
|
|
from django.contrib.auth.models import User
|
2017-05-27 20:35:02 +08:00
|
|
|
from django.core.exceptions import FieldDoesNotExist
|
2015-01-28 20:35:27 +08:00
|
|
|
from django.test import TestCase, override_settings
|
2012-09-18 03:50:13 +08:00
|
|
|
from django.test.client import RequestFactory
|
2010-11-26 21:33:27 +08:00
|
|
|
|
2018-02-17 22:00:12 +08:00
|
|
|
from .models import MinimalUser, UserWithDisabledLastLoginField
|
2017-05-27 20:35:02 +08:00
|
|
|
|
2010-11-26 21:33:27 +08:00
|
|
|
|
2016-02-06 04:56:52 +08:00
|
|
|
@override_settings(ROOT_URLCONF="auth_tests.urls")
|
2010-11-26 21:33:27 +08:00
|
|
|
class SignalTestCase(TestCase):
|
2015-02-23 08:53:57 +08:00
|
|
|
@classmethod
|
|
|
|
def setUpTestData(cls):
|
2016-02-06 04:56:52 +08:00
|
|
|
cls.u1 = User.objects.create_user(username="testclient", password="password")
|
|
|
|
cls.u3 = User.objects.create_user(username="staff", password="password")
|
2010-11-26 21:33:27 +08:00
|
|
|
|
|
|
|
def listener_login(self, user, **kwargs):
|
|
|
|
self.logged_in.append(user)
|
|
|
|
|
|
|
|
def listener_logout(self, user, **kwargs):
|
|
|
|
self.logged_out.append(user)
|
|
|
|
|
2016-02-19 08:58:30 +08:00
|
|
|
def listener_login_failed(self, sender, **kwargs):
|
|
|
|
self.login_failed.append(kwargs)
|
2012-07-12 09:43:15 +08:00
|
|
|
|
2010-11-26 21:33:27 +08:00
|
|
|
def setUp(self):
|
|
|
|
"""Set up the listeners and reset the logged in/logged out counters"""
|
|
|
|
self.logged_in = []
|
|
|
|
self.logged_out = []
|
2012-07-12 09:43:15 +08:00
|
|
|
self.login_failed = []
|
2010-11-26 21:33:27 +08:00
|
|
|
signals.user_logged_in.connect(self.listener_login)
|
|
|
|
signals.user_logged_out.connect(self.listener_logout)
|
2012-07-12 09:43:15 +08:00
|
|
|
signals.user_login_failed.connect(self.listener_login_failed)
|
2010-11-26 21:33:27 +08:00
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
"""Disconnect the listeners"""
|
|
|
|
signals.user_logged_in.disconnect(self.listener_login)
|
|
|
|
signals.user_logged_out.disconnect(self.listener_logout)
|
2012-07-12 09:43:15 +08:00
|
|
|
signals.user_login_failed.disconnect(self.listener_login_failed)
|
2010-11-26 21:33:27 +08:00
|
|
|
|
|
|
|
def test_login(self):
|
2012-07-12 09:43:15 +08:00
|
|
|
# Only a successful login will trigger the success signal.
|
2010-11-26 21:33:27 +08:00
|
|
|
self.client.login(username="testclient", password="bad")
|
|
|
|
self.assertEqual(len(self.logged_in), 0)
|
2012-07-12 09:43:15 +08:00
|
|
|
self.assertEqual(len(self.login_failed), 1)
|
2016-02-19 08:58:30 +08:00
|
|
|
self.assertEqual(self.login_failed[0]["credentials"]["username"], "testclient")
|
2012-07-12 09:43:15 +08:00
|
|
|
# verify the password is cleansed
|
2016-02-19 08:58:30 +08:00
|
|
|
self.assertIn("***", self.login_failed[0]["credentials"]["password"])
|
|
|
|
self.assertIn("request", self.login_failed[0])
|
2012-07-12 09:43:15 +08:00
|
|
|
|
2010-11-26 21:33:27 +08:00
|
|
|
# Like this:
|
|
|
|
self.client.login(username="testclient", password="password")
|
|
|
|
self.assertEqual(len(self.logged_in), 1)
|
|
|
|
self.assertEqual(self.logged_in[0].username, "testclient")
|
|
|
|
|
2012-07-12 09:43:15 +08:00
|
|
|
# Ensure there were no more failures.
|
|
|
|
self.assertEqual(len(self.login_failed), 1)
|
|
|
|
|
2010-11-26 21:33:27 +08:00
|
|
|
def test_logout_anonymous(self):
|
|
|
|
# The log_out function will still trigger the signal for anonymous
|
|
|
|
# users.
|
2020-02-28 00:55:29 +08:00
|
|
|
self.client.post("/logout/next_page/")
|
2010-11-26 21:33:27 +08:00
|
|
|
self.assertEqual(len(self.logged_out), 1)
|
2016-06-17 02:19:18 +08:00
|
|
|
self.assertIsNone(self.logged_out[0])
|
2010-11-26 21:33:27 +08:00
|
|
|
|
|
|
|
def test_logout(self):
|
|
|
|
self.client.login(username="testclient", password="password")
|
2020-02-28 00:55:29 +08:00
|
|
|
self.client.post("/logout/next_page/")
|
2010-11-26 21:33:27 +08:00
|
|
|
self.assertEqual(len(self.logged_out), 1)
|
|
|
|
self.assertEqual(self.logged_out[0].username, "testclient")
|
2012-09-18 03:50:13 +08:00
|
|
|
|
|
|
|
def test_update_last_login(self):
|
2016-10-27 15:53:39 +08:00
|
|
|
"""Only `last_login` is updated in `update_last_login`"""
|
2015-02-23 08:53:57 +08:00
|
|
|
user = self.u3
|
2012-09-18 03:50:13 +08:00
|
|
|
old_last_login = user.last_login
|
|
|
|
|
|
|
|
user.username = "This username shouldn't get saved"
|
|
|
|
request = RequestFactory().get("/login")
|
2016-02-06 04:56:52 +08:00
|
|
|
signals.user_logged_in.send(sender=user.__class__, request=request, user=user)
|
2017-09-02 09:43:41 +08:00
|
|
|
user = User.objects.get(pk=user.pk)
|
2012-09-18 03:50:13 +08:00
|
|
|
self.assertEqual(user.username, "staff")
|
|
|
|
self.assertNotEqual(user.last_login, old_last_login)
|
2016-02-19 08:58:30 +08:00
|
|
|
|
|
|
|
def test_failed_login_without_request(self):
|
|
|
|
authenticate(username="testclient", password="bad")
|
|
|
|
self.assertIsNone(self.login_failed[0]["request"])
|
2017-05-27 20:35:02 +08:00
|
|
|
|
|
|
|
def test_login_with_custom_user_without_last_login_field(self):
|
|
|
|
"""
|
|
|
|
The user_logged_in signal is only registered if the user model has a
|
|
|
|
last_login field.
|
|
|
|
"""
|
|
|
|
last_login_receivers = signals.user_logged_in.receivers
|
|
|
|
try:
|
|
|
|
signals.user_logged_in.receivers = []
|
|
|
|
with self.assertRaises(FieldDoesNotExist):
|
|
|
|
MinimalUser._meta.get_field("last_login")
|
|
|
|
with self.settings(AUTH_USER_MODEL="auth_tests.MinimalUser"):
|
|
|
|
apps.get_app_config("auth").ready()
|
|
|
|
self.assertEqual(signals.user_logged_in.receivers, [])
|
|
|
|
|
2018-02-17 22:00:12 +08:00
|
|
|
# last_login is a property whose value is None.
|
|
|
|
self.assertIsNone(UserWithDisabledLastLoginField().last_login)
|
|
|
|
with self.settings(
|
|
|
|
AUTH_USER_MODEL="auth_tests.UserWithDisabledLastLoginField"
|
|
|
|
):
|
|
|
|
apps.get_app_config("auth").ready()
|
|
|
|
self.assertEqual(signals.user_logged_in.receivers, [])
|
|
|
|
|
2017-05-27 20:35:02 +08:00
|
|
|
with self.settings(AUTH_USER_MODEL="auth.User"):
|
|
|
|
apps.get_app_config("auth").ready()
|
|
|
|
self.assertEqual(len(signals.user_logged_in.receivers), 1)
|
|
|
|
finally:
|
|
|
|
signals.user_logged_in.receivers = last_login_receivers
|