UPD: dav_auth: refactor the ResetPasswordView for better name

This commit is contained in:
2020-12-22 11:51:59 +01:00
parent f3509d3a61
commit 5f296ff1c0
10 changed files with 42 additions and 35 deletions

View File

@@ -62,7 +62,7 @@ class SetPasswordForm(forms.Form):
return self.user return self.user
class ResetPasswordForm(forms.Form): class CreateAndSendPasswordForm(forms.Form):
username = auth_forms.UsernameField( username = auth_forms.UsernameField(
max_length=254, max_length=254,
label=_(u'E-Mail-Adresse'), label=_(u'E-Mail-Adresse'),

View File

@@ -15,7 +15,8 @@
<form action="" method="post"> <form action="" method="post">
{% csrf_token %} {% csrf_token %}
{% bootstrap_form form %} {% bootstrap_form form %}
<div class="pull-right"><a href="{% url 'dav_auth:reset_password' %}">{% trans 'Passwort vergessen?' %}</a></div> <div class="pull-right"><a
href="{% url 'dav_auth:recreate_password' %}">{% trans 'Passwort vergessen?' %}</a></div>
{% buttons %} {% buttons %}
<button type="submit" class="btn btn-success"> <button type="submit" class="btn btn-success">
{% bootstrap_icon 'log-in' %}&thinsp; {% bootstrap_icon 'log-in' %}&thinsp;

View File

@@ -6,7 +6,7 @@ from django.utils.translation import ugettext
from dav_base.tests.generic import FormDataSet, FormsTestCase from dav_base.tests.generic import FormDataSet, FormsTestCase
from ..forms import LoginForm, SetPasswordForm, ResetPasswordForm from ..forms import LoginForm, SetPasswordForm, CreateAndSendPasswordForm
TEST_USERNAME = 'root@localhost' TEST_USERNAME = 'root@localhost'
TEST_PASSWORD = u'me||ön 2' TEST_PASSWORD = u'me||ön 2'
@@ -193,8 +193,8 @@ class SetPasswordFormTestCase(FormsTestCase):
self.assertTrue(self.client.login(username=self.test_username, password=new_password)) self.assertTrue(self.client.login(username=self.test_username, password=new_password))
class ResetPasswordFormTestCase(FormsTestCase): class CreateAndSendPasswordFormTestCase(FormsTestCase):
form_class = ResetPasswordForm form_class = CreateAndSendPasswordForm
valid_data_sets = ( valid_data_sets = (
FormDataSet({'username': 'unittest@example.com'}), FormDataSet({'username': 'unittest@example.com'}),

View File

@@ -177,10 +177,10 @@ class TestCase(ScreenshotTestCase):
self.wait_until_stale(c, password2_field) self.wait_until_stale(c, password2_field)
self.save_screenshot('set_password_succeed', sequence=sequence_name) self.save_screenshot('set_password_succeed', sequence=sequence_name)
# Get password reset page -> since we are logged in, it should # Get password recreate page -> since we are logged in, it should
# redirect to set password page again -> save # redirect to set password page again -> save
html = c.find_element_by_tag_name('html') html = c.find_element_by_tag_name('html')
c.get(self.complete_url(reverse('dav_auth:reset_password'))) c.get(self.complete_url(reverse('dav_auth:recreate_password')))
self.wait_until_stale(c, html) self.wait_until_stale(c, html)
self.wait_on_presence(c, (By.ID, 'id_new_password')) self.wait_on_presence(c, (By.ID, 'id_new_password'))
self.save_screenshot('empty_set_password_form', sequence=sequence_name) self.save_screenshot('empty_set_password_form', sequence=sequence_name)
@@ -194,24 +194,24 @@ class TestCase(ScreenshotTestCase):
self.wait_until_stale(c, user_menu) self.wait_until_stale(c, user_menu)
self.save_screenshot('logout_succeed', sequence=sequence_name) self.save_screenshot('logout_succeed', sequence=sequence_name)
# Click on 'login' to access password reset link # Click on 'login' to access password recreate link
link = c.find_element_by_css_selector('#login-widget a') link = c.find_element_by_css_selector('#login-widget a')
link.click() link.click()
self.wait_on_presence(c, (By.ID, 'id_username')) self.wait_on_presence(c, (By.ID, 'id_username'))
# Locate password reset link, click it -> save password reset form # Locate password recreate link, click it -> save password recreate form
link = c.find_element_by_partial_link_text(ugettext(u'Passwort vergessen')) link = c.find_element_by_partial_link_text(ugettext(u'Passwort vergessen'))
link.click() link.click()
username_field = self.wait_on_presence(c, (By.ID, 'id_username')) username_field = self.wait_on_presence(c, (By.ID, 'id_username'))
self.save_screenshot('empty_reset_password_form', sequence=sequence_name) 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, no message)
username_field.send_keys(self.test_username[::-1]) username_field.send_keys(self.test_username[::-1])
username_field.send_keys(Keys.RETURN) username_field.send_keys(Keys.RETURN)
self.wait_until_stale(c, username_field) self.wait_until_stale(c, username_field)
self.save_screenshot('reset_password_invalid_user', sequence=sequence_name) self.save_screenshot('recreate_password_invalid_user', sequence=sequence_name)
# Locate password reset link, click it # Locate password recreate link, click it
link = c.find_element_by_partial_link_text(ugettext(u'Passwort vergessen')) link = c.find_element_by_partial_link_text(ugettext(u'Passwort vergessen'))
link.click() link.click()
username_field = self.wait_on_presence(c, (By.ID, 'id_username')) username_field = self.wait_on_presence(c, (By.ID, 'id_username'))
@@ -220,4 +220,4 @@ class TestCase(ScreenshotTestCase):
username_field.send_keys(self.test_username) username_field.send_keys(self.test_username)
username_field.send_keys(Keys.RETURN) username_field.send_keys(Keys.RETURN)
self.wait_until_stale(c, username_field) self.wait_until_stale(c, username_field)
self.save_screenshot('reset_password_valid_user', sequence=sequence_name) self.save_screenshot('recreate_password_valid_user', sequence=sequence_name)

View File

@@ -17,11 +17,11 @@ TEST_EMAIL = TEST_USERNAME
class TemplatesTestCase(SimpleTestCase): class TemplatesTestCase(SimpleTestCase):
def test_reset_link_in_login_form(self): def test_recreate_link_in_login_form(self):
login_url = reverse('dav_auth:login') login_url = reverse('dav_auth:login')
reset_url = reverse('dav_auth:reset_password') recreate_url = reverse('dav_auth:recreate_password')
text = ugettext('Passwort vergessen?') text = ugettext('Passwort vergessen?')
html = '<a href="{url}">{text}</a>'.format(url=reset_url, text=text) html = '<a href="{url}">{text}</a>'.format(url=recreate_url, text=text)
response = self.client.get(login_url) response = self.client.get(login_url)
self.assertInHTML(html, response.content.decode('utf-8')) self.assertInHTML(html, response.content.decode('utf-8'))

View File

@@ -9,5 +9,5 @@ class TestCase(UrlsTestCase):
Url('/auth/logout', 'dav_auth:logout', views.LogoutView.as_view(), status_code=302), Url('/auth/logout', 'dav_auth:logout', views.LogoutView.as_view(), status_code=302),
Url('/auth/password', 'dav_auth:set_password', views.SetPasswordView.as_view(), Url('/auth/password', 'dav_auth:set_password', views.SetPasswordView.as_view(),
redirect='/auth/login?next=/auth/password'), redirect='/auth/login?next=/auth/password'),
Url('/auth/password/reset', 'dav_auth:reset_password', views.ResetPasswordView.as_view()), Url('/auth/password/recreate', 'dav_auth:recreate_password', views.CreateAndSendPasswordView.as_view()),
) )

View File

@@ -7,7 +7,7 @@ from django.test import TestCase
from django.utils.translation import ugettext from django.utils.translation import ugettext
from django.urls import reverse from django.urls import reverse
from ..forms import LoginForm, SetPasswordForm, ResetPasswordForm from ..forms import LoginForm, SetPasswordForm, CreateAndSendPasswordForm
TEST_USERNAME = 'root@localhost' TEST_USERNAME = 'root@localhost'
TEST_PASSWORD = u'me||ön 2' TEST_PASSWORD = u'me||ön 2'
@@ -27,7 +27,7 @@ class ViewsTestCase(TestCase):
cls.logout_url = reverse('dav_auth:logout') cls.logout_url = reverse('dav_auth:logout')
cls.logout_redirect_url = resolve_url(cls.app_settings.logout_redirect_url) cls.logout_redirect_url = resolve_url(cls.app_settings.logout_redirect_url)
cls.set_password_url = reverse('dav_auth:set_password') cls.set_password_url = reverse('dav_auth:set_password')
cls.reset_password_url = reverse('dav_auth:reset_password') cls.recreate_password_url = reverse('dav_auth:recreate_password')
# Some messages # Some messages
cls.wrong_credentials_message = ugettext(u'Benutzername oder Passwort falsch.') cls.wrong_credentials_message = ugettext(u'Benutzername oder Passwort falsch.')
@@ -179,23 +179,23 @@ class ViewsTestCase(TestCase):
self.assertFalse(self.client.login(username=username, password=password), 'Old password still valid') self.assertFalse(self.client.login(username=username, password=password), 'Old password still valid')
self.assertTrue(self.client.login(username=username, password=new_password), 'New password not valid') self.assertTrue(self.client.login(username=username, password=new_password), 'New password not valid')
def test_reset_password_integrated_unauth_get(self): def test_recreate_password_integrated_unauth_get(self):
response = self.client.get(self.reset_password_url) response = self.client.get(self.recreate_password_url)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'dav_auth/forms/reset_password.html') self.assertTemplateUsed(response, 'dav_auth/forms/recreate_password.html')
self.assertIn('form', response.context) self.assertIn('form', response.context)
self.assertIsInstance(response.context['form'], ResetPasswordForm) self.assertIsInstance(response.context['form'], CreateAndSendPasswordForm)
field = response.context['form'].fields['username'] field = response.context['form'].fields['username']
self.assertTrue(field.required) self.assertTrue(field.required)
def test_reset_password_integrated_auth_get(self): def test_recreate_password_integrated_auth_get(self):
self.client.login(username=self.test_username, password=self.test_password) self.client.login(username=self.test_username, password=self.test_password)
response = self.client.get(self.reset_password_url) response = self.client.get(self.recreate_password_url)
self.assertRedirects(response, self.set_password_url) self.assertRedirects(response, self.set_password_url)
def test_reset_password_integrated_post(self): def test_recreate_password_integrated_post(self):
location = self.reset_password_url location = self.recreate_password_url
response = self.client.post(location, {'username': self.user.username}) response = self.client.post(location, {'username': self.user.username})
self.assertRedirects(response, self.login_url) self.assertRedirects(response, self.login_url)

View File

@@ -6,5 +6,5 @@ urlpatterns = [
url(r'^login$', views.LoginView.as_view(), name='login'), url(r'^login$', views.LoginView.as_view(), name='login'),
url(r'^logout$', views.LogoutView.as_view(), name='logout'), url(r'^logout$', views.LogoutView.as_view(), name='logout'),
url(r'^password$', views.SetPasswordView.as_view(), name='set_password'), url(r'^password$', views.SetPasswordView.as_view(), name='set_password'),
url(r'^password/reset$', views.ResetPasswordView.as_view(), name='reset_password'), url(r'^password/recreate$', views.CreateAndSendPasswordView.as_view(), name='recreate_password'),
] ]

View File

@@ -1,7 +1,9 @@
import logging import logging
from django.apps import apps from django.apps import apps
from django.core.exceptions import ValidationError
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import views as auth_views, get_user_model from django.contrib.auth import views as auth_views, get_user_model
from django.contrib.auth.password_validation import validate_password
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import resolve_url from django.shortcuts import resolve_url
from django.urls import reverse_lazy, reverse from django.urls import reverse_lazy, reverse
@@ -27,6 +29,10 @@ class LoginView(auth_views.LoginView):
def form_valid(self, form): def form_valid(self, form):
r = super(LoginView, self).form_valid(form) r = super(LoginView, self).form_valid(form)
try:
validate_password(form.cleaned_data['password'])
except ValidationError as e:
logger.warning(u'Weak password (%d): %s', self.request.user.pk, e)
messages.success(self.request, _(u'Benutzer angemeldet: %(username)s') % {'username': form.get_user()}) messages.success(self.request, _(u'Benutzer angemeldet: %(username)s') % {'username': form.get_user()})
return r return r
@@ -60,9 +66,9 @@ class SetPasswordView(auth_views.PasswordChangeView):
return r return r
class ResetPasswordView(generic.FormView): class CreateAndSendPasswordView(generic.FormView):
form_class = forms.ResetPasswordForm form_class = forms.CreateAndSendPasswordForm
template_name = 'dav_auth/forms/reset_password.html' template_name = 'dav_auth/forms/recreate_password.html'
success_url = reverse_lazy('dav_auth:login') success_url = reverse_lazy('dav_auth:login')
def form_valid(self, form): def form_valid(self, form):
@@ -76,13 +82,13 @@ class ResetPasswordView(generic.FormView):
email = emails.PasswordSetEmail(user, random_password) email = emails.PasswordSetEmail(user, random_password)
email.send() email.send()
messages.success(self.request, _(u'Neues Passwort versendet.')) messages.success(self.request, _(u'Neues Passwort versendet.'))
logger.info('Password reset for user \'%s\'', username) logger.info('Password recreated for user \'%s\'', username)
except user_model.DoesNotExist: except user_model.DoesNotExist:
logger.warning('Password reset for unknown user \'%s\'', username) logger.warning('Password recreated for unknown user \'%s\'', username)
return super(ResetPasswordView, self).form_valid(form) return super(CreateAndSendPasswordView, self).form_valid(form)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if request.user.is_authenticated: if request.user.is_authenticated:
return HttpResponseRedirect(reverse('dav_auth:set_password')) return HttpResponseRedirect(reverse('dav_auth:set_password'))
return super(ResetPasswordView, self).get(request, *args, **kwargs) return super(CreateAndSendPasswordView, self).get(request, *args, **kwargs)