dav_auth: small refactorings and improvements under the hood
Run tests / Execute tox to run the test suite (push) Successful in 3m38s

This commit is contained in:
2026-05-28 16:50:44 +02:00
parent d9cfffb8c2
commit 50a33a9f47
7 changed files with 102 additions and 27 deletions
+5
View File
@@ -9,4 +9,9 @@ class TestCase(AppsTestCase):
settings = (
AppSetting('login_redirect_url', 'root', str),
AppSetting('logout_redirect_url', 'root', str),
AppSetting('auto_password_length', 32, int),
AppSetting('auto_password_characters', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'abcdefghijklmnopqrstuvwxyz'
'0123456789'
'#$%&@^~.,:;/_-*+!?', str),
)
+37 -9
View File
@@ -9,7 +9,8 @@ from selenium.webdriver.common.keys import Keys
from dav_base.tests.generic import ScreenshotTestCase
TEST_USERNAME = 'root@localhost'
TEST_PASSWORD = 'me||ön 21ABll'
TEST_STRONG_PASSWORD = 'me||ön 21ABll'
TEST_WEAK_PASSWORD = 'mellon'
TEST_EMAIL = TEST_USERNAME
@@ -20,10 +21,11 @@ class TestCase(ScreenshotTestCase):
def setUp(self):
super().setUp()
# Need a test user
# (we start with a weak password, because we want to see the weak password warning)
self.test_username = TEST_USERNAME
self.test_password = TEST_PASSWORD
self.test_password = TEST_WEAK_PASSWORD
model = get_user_model()
self.user = model.objects.create_user(username=TEST_USERNAME, password=TEST_PASSWORD, email=TEST_EMAIL)
self.user = model.objects.create_user(username=TEST_USERNAME, password=TEST_WEAK_PASSWORD, email=TEST_EMAIL)
def test_screenshots(self):
sequence_name = 'walkthrough'
@@ -86,7 +88,7 @@ class TestCase(ScreenshotTestCase):
self.user.is_active = True
self.user.save()
# Login -> save success message
# Login -> save success message and weak password warning
username_field = c.find_element(By.ID, 'id_username')
username_field.clear()
username_field.send_keys(self.test_username)
@@ -95,7 +97,7 @@ class TestCase(ScreenshotTestCase):
password_field.send_keys(self.test_password)
password_field.send_keys(Keys.RETURN)
alert_button = self.wait_on_presence(c, (By.CSS_SELECTOR, '#messages .alert-success button.close'))
self.save_screenshot('login_succeed', sequence=sequence_name)
self.save_screenshot('login_weak_password_succeed', sequence=sequence_name)
alert_button.click()
# Open user dropdown menu -> save menu
@@ -122,9 +124,9 @@ class TestCase(ScreenshotTestCase):
# New passwords mismatch -> save error message
password_field.clear()
password_field.send_keys(self.test_password)
password_field.send_keys(TEST_STRONG_PASSWORD)
password2_field.clear()
password2_field.send_keys(self.test_password[::-1])
password2_field.send_keys(TEST_WEAK_PASSWORD)
password2_field.send_keys(Keys.RETURN)
self.wait_until_stale(c, password2_field)
self.save_screenshot('error_mismatch', sequence=sequence_name)
@@ -166,7 +168,7 @@ class TestCase(ScreenshotTestCase):
self.save_screenshot('error_too_similar', sequence=sequence_name)
# Change password -> save success message
password = self.test_password[::-1]
password = TEST_STRONG_PASSWORD
password_field = c.find_element(By.ID, 'id_new_password')
password_field.clear()
password_field.send_keys(password)
@@ -176,6 +178,7 @@ class TestCase(ScreenshotTestCase):
password2_field.send_keys(Keys.RETURN)
self.wait_until_stale(c, password2_field)
self.save_screenshot('set_password_succeed', sequence=sequence_name)
self.test_password = password
# Get password recreate page -> since we are logged in, it should
# redirect to set password page again -> save
@@ -196,6 +199,31 @@ class TestCase(ScreenshotTestCase):
self.wait_until_stale(c, user_menu)
self.save_screenshot('logout_succeed', sequence=sequence_name)
# Login again, this time with a new strong password
link = c.find_element(By.CSS_SELECTOR, '#login-widget a')
link.click()
self.wait_on_presence(c, (By.ID, 'id_username'))
username_field = c.find_element(By.ID, 'id_username')
username_field.clear()
username_field.send_keys(self.test_username)
password_field = c.find_element(By.ID, 'id_password')
password_field.clear()
password_field.send_keys(self.test_password)
password_field.send_keys(Keys.RETURN)
alert_button = self.wait_on_presence(c, (By.CSS_SELECTOR, '#messages .alert-success button.close'))
self.save_screenshot('login_strong_password_succeed', sequence=sequence_name)
alert_button.click()
# Logout again
dropdown_button = self.wait_on_presence(c, (By.ID, 'user_dropdown_button'))
dropdown_button.click()
user_menu = c.find_element(By.CSS_SELECTOR, '#login-widget ul')
#link = user_menu.find_element(By.PARTIAL_LINK_TEXT, gettext('Logout'))
#link.click()
button = c.find_element(By.ID, 'id_logout_button')
button.click()
self.wait_until_stale(c, user_menu)
# Click on 'login' to access password recreate link
link = c.find_element(By.CSS_SELECTOR, '#login-widget a')
link.click()
@@ -207,7 +235,7 @@ class TestCase(ScreenshotTestCase):
username_field = self.wait_on_presence(c, (By.ID, 'id_username'))
self.save_screenshot('empty_recreate_password_form', sequence=sequence_name)
# Enter invalid username -> save result (login form, no message)
# Enter invalid username -> save result (login form, success message - do not reveal user does not exist)
username_field.send_keys(self.test_username[::-1])
username_field.send_keys(Keys.RETURN)
self.wait_until_stale(c, username_field)
+19 -1
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from django.apps import apps
from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
from django.contrib.messages import get_messages
from django.core import mail as django_mail
from django.shortcuts import resolve_url
@@ -115,7 +116,7 @@ class ViewsTestCase(TestCase):
with self.assertLogs('dav_auth.views', level='WARNING') as cm:
response = self.client.post(self.login_url, {'username': username, 'password': password})
self.assertStartsWith(cm.output[0], 'WARNING:dav_auth.views:Weak password')
self.assertStartsWith(cm.output[0], 'WARNING:dav_auth.views:Detected weak password for user id')
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, self.login_redirect_url)
@@ -248,6 +249,7 @@ class ViewsTestCase(TestCase):
location = self.recreate_password_url
response = self.client.post(location, {'username': self.user.username})
new_password = response.context['password']
messages = list(get_messages(response.wsgi_request))
self.assertEqual(len(messages), 1)
self.assertEqual(messages[0].message, self.new_password_sent_message)
@@ -259,6 +261,7 @@ class ViewsTestCase(TestCase):
recipients = mail.recipients()
self.assertIn(recipient, recipients)
self.assertEqual(len(recipients), 1)
self.assertIn(new_password, mail.body)
response = self.client.get(location)
self.assertFalse(response.context['user'].is_authenticated, 'User is logged in')
@@ -276,3 +279,18 @@ class ViewsTestCase(TestCase):
self.assertRedirects(response, self.login_url)
self.assertEqual(len(django_mail.outbox), 0)
def test_new_password_length(self):
location = self.recreate_password_url
default_password_length = 32
response = self.client.post(location, {'username': self.user.username})
new_password = response.context['password']
self.assertEqual(len(new_password), default_password_length)
def test_new_password_is_valid(self):
location = self.recreate_password_url
response = self.client.post(location, {'username': self.user.username})
new_password = response.context['password']
validate_password(new_password)