UPD: dav_auth: refactor the ResetPasswordView for better name
This commit is contained in:
@@ -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'),
|
||||||
|
|||||||
@@ -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' %} 
|
{% bootstrap_icon 'log-in' %} 
|
||||||
|
|||||||
@@ -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'}),
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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'))
|
||||||
|
|
||||||
|
|||||||
@@ -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()),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user