views: better display password reset instructions (#38054)
This commit is contained in:
parent
8e4831c64e
commit
abed3fa8cc
|
@ -0,0 +1,37 @@
|
||||||
|
{% extends "authentic2/base-page.html" %}
|
||||||
|
{% load i18n gadjo %}
|
||||||
|
|
||||||
|
{% block page-title %}
|
||||||
|
{% trans "Password reset instructions" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<p><strong>
|
||||||
|
{% blocktrans with email=request.session.reset_email %}
|
||||||
|
If your email address exists in our database, an email has been sent to {{ email }}.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</strong></p>
|
||||||
|
<p><strong>
|
||||||
|
{% blocktrans %}
|
||||||
|
Follow the instructions in this email in order to choose a new password.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</strong></p>
|
||||||
|
{% block advice %}
|
||||||
|
<p>
|
||||||
|
{% blocktrans %}
|
||||||
|
The email may take several minutes to be received. It can also be
|
||||||
|
considered as spam: please look in your "junk mail" folder.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{% blocktrans %}
|
||||||
|
If you still have not received the instructions, add "{{from_email_address}}"
|
||||||
|
to your address book or authorized sender list, and then repeat the
|
||||||
|
password reset process.
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% endblock %}
|
||||||
|
</p>
|
||||||
|
{% block back %}
|
||||||
|
<p><a href="{% url 'auth_login' %}">{% trans "Back to login" %}</a></p>
|
||||||
|
{% endblock %}
|
||||||
|
{% endblock %}
|
|
@ -81,6 +81,9 @@ accounts_urlpatterns = [
|
||||||
url(r'^password/reset/$',
|
url(r'^password/reset/$',
|
||||||
views.password_reset,
|
views.password_reset,
|
||||||
name='password_reset'),
|
name='password_reset'),
|
||||||
|
url(r'^password/reset/instructions/$',
|
||||||
|
views.password_reset_instructions,
|
||||||
|
name='password_reset_instructions'),
|
||||||
|
|
||||||
# Legacy, only there to provide old view names to resolver
|
# Legacy, only there to provide old view names to resolver
|
||||||
url(r'^password/change/$',
|
url(r'^password/change/$',
|
||||||
|
|
|
@ -626,11 +626,13 @@ def csrf_failure_view(request, reason=""):
|
||||||
return HttpResponseRedirect(request.get_full_path())
|
return HttpResponseRedirect(request.get_full_path())
|
||||||
|
|
||||||
|
|
||||||
class PasswordResetView(cbv.NextURLViewMixin, FormView):
|
class PasswordResetView(FormView):
|
||||||
'''Ask for an email and send a password reset link by mail'''
|
'''Ask for an email and send a password reset link by mail'''
|
||||||
form_class = passwords_forms.PasswordResetForm
|
form_class = passwords_forms.PasswordResetForm
|
||||||
title = _('Password Reset')
|
title = _('Password Reset')
|
||||||
next_url_default = '/'
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse('password_reset_instructions')
|
||||||
|
|
||||||
def get_template_names(self):
|
def get_template_names(self):
|
||||||
return [
|
return [
|
||||||
|
@ -653,16 +655,24 @@ class PasswordResetView(cbv.NextURLViewMixin, FormView):
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
form.save()
|
form.save()
|
||||||
# return to next URL
|
self.request.session['reset_email'] = form.cleaned_data['email']
|
||||||
messages.info(self.request, _('If your email address exists in our '
|
|
||||||
'database, you will receive an email '
|
|
||||||
'containing instructions to reset '
|
|
||||||
'your password'))
|
|
||||||
return super(PasswordResetView, self).form_valid(form)
|
return super(PasswordResetView, self).form_valid(form)
|
||||||
|
|
||||||
password_reset = PasswordResetView.as_view()
|
password_reset = PasswordResetView.as_view()
|
||||||
|
|
||||||
|
|
||||||
|
class PasswordResetInstructionsView(TemplateView):
|
||||||
|
template_name = 'registration/password_reset_instructions.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
ctx = super(PasswordResetInstructionsView, self).get_context_data(**kwargs)
|
||||||
|
ctx['from_email_address'] = parseaddr(settings.DEFAULT_FROM_EMAIL)[1]
|
||||||
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
|
password_reset_instructions = PasswordResetInstructionsView.as_view()
|
||||||
|
|
||||||
|
|
||||||
class PasswordResetConfirmView(cbv.RedirectToNextURLViewMixin, FormView):
|
class PasswordResetConfirmView(cbv.RedirectToNextURLViewMixin, FormView):
|
||||||
'''Validate password reset link, show a set password form and login
|
'''Validate password reset link, show a set password form and login
|
||||||
the user.
|
the user.
|
||||||
|
|
|
@ -39,13 +39,18 @@ def test_send_password_reset_email(app, simple_user, mailoutbox):
|
||||||
assert str(app.session['_auth_user_id']) == str(simple_user.pk)
|
assert str(app.session['_auth_user_id']) == str(simple_user.pk)
|
||||||
|
|
||||||
|
|
||||||
def test_view(app, simple_user, mailoutbox):
|
def test_view(app, simple_user, mailoutbox, settings):
|
||||||
url = reverse('password_reset') + '?next=/moncul/'
|
url = reverse('password_reset')
|
||||||
resp = app.get(url, status=200)
|
resp = app.get(url, status=200)
|
||||||
resp.form.set('email', simple_user.email)
|
resp.form.set('email', simple_user.email)
|
||||||
assert len(mailoutbox) == 0
|
assert len(mailoutbox) == 0
|
||||||
|
settings.DEFAULT_FROM_EMAIL = 'show only addr <noreply@example.net>'
|
||||||
resp = resp.form.submit()
|
resp = resp.form.submit()
|
||||||
assert resp['Location'].endswith('/moncul/')
|
assert resp['Location'].endswith('/instructions/')
|
||||||
|
resp = resp.follow()
|
||||||
|
assert simple_user.email in resp.text
|
||||||
|
assert '"noreply@example.net"' in resp.text
|
||||||
|
assert 'show only addr' not in resp.text
|
||||||
assert len(mailoutbox) == 1
|
assert len(mailoutbox) == 1
|
||||||
url = utils.get_link_from_mail(mailoutbox[0])
|
url = utils.get_link_from_mail(mailoutbox[0])
|
||||||
relative_url = url.split('testserver')[1]
|
relative_url = url.split('testserver')[1]
|
||||||
|
@ -55,32 +60,28 @@ def test_view(app, simple_user, mailoutbox):
|
||||||
resp = resp.form.submit()
|
resp = resp.form.submit()
|
||||||
# verify user is logged
|
# verify user is logged
|
||||||
assert str(app.session['_auth_user_id']) == str(simple_user.pk)
|
assert str(app.session['_auth_user_id']) == str(simple_user.pk)
|
||||||
# verify next_url was kept
|
|
||||||
assert resp['Location'].endswith('/moncul/')
|
|
||||||
|
|
||||||
with override_settings(A2_USER_CAN_RESET_PASSWORD=False):
|
with override_settings(A2_USER_CAN_RESET_PASSWORD=False):
|
||||||
url = reverse('password_reset') + '?next=/moncul/'
|
url = reverse('password_reset')
|
||||||
app.get(url, status=404)
|
app.get(url, status=404)
|
||||||
|
|
||||||
def test_user_filter(app, simple_user, mailoutbox, settings):
|
def test_user_filter(app, simple_user, mailoutbox, settings):
|
||||||
settings.A2_USER_FILTER = {'username': 'xxx'} # will not match simple_user
|
settings.A2_USER_FILTER = {'username': 'xxx'} # will not match simple_user
|
||||||
|
|
||||||
url = reverse('password_reset') + '?next=/moncul/'
|
url = reverse('password_reset')
|
||||||
resp = app.get(url, status=200)
|
resp = app.get(url, status=200)
|
||||||
resp.form.set('email', simple_user.email)
|
resp.form.set('email', simple_user.email)
|
||||||
assert len(mailoutbox) == 0
|
assert len(mailoutbox) == 0
|
||||||
resp = resp.form.submit()
|
resp = resp.form.submit()
|
||||||
assert resp['Location'].endswith('/moncul/')
|
|
||||||
assert len(mailoutbox) == 0
|
assert len(mailoutbox) == 0
|
||||||
|
|
||||||
|
|
||||||
def test_user_exclude(app, simple_user, mailoutbox, settings):
|
def test_user_exclude(app, simple_user, mailoutbox, settings):
|
||||||
settings.A2_USER_EXCLUDE = {'username': simple_user.username} # will not match simple_user
|
settings.A2_USER_EXCLUDE = {'username': simple_user.username} # will not match simple_user
|
||||||
|
|
||||||
url = reverse('password_reset') + '?next=/moncul/'
|
url = reverse('password_reset')
|
||||||
resp = app.get(url, status=200)
|
resp = app.get(url, status=200)
|
||||||
resp.form.set('email', simple_user.email)
|
resp.form.set('email', simple_user.email)
|
||||||
assert len(mailoutbox) == 0
|
assert len(mailoutbox) == 0
|
||||||
resp = resp.form.submit()
|
resp = resp.form.submit()
|
||||||
assert resp['Location'].endswith('/moncul/')
|
|
||||||
assert len(mailoutbox) == 0
|
assert len(mailoutbox) == 0
|
||||||
|
|
Loading…
Reference in New Issue