Projet

Général

Profil

0001-views-better-display-password-reset-instructions-380.patch

Valentin Deniaud, 08 janvier 2020 15:42

Télécharger (7,01 ko)

Voir les différences:

Subject: [PATCH] views: better display password reset instructions (#38054)

 .../password_reset_instructions.html          | 37 +++++++++++++++++++
 src/authentic2/urls.py                        |  3 ++
 src/authentic2/views.py                       | 24 ++++++++----
 tests/test_password_reset.py                  | 21 ++++++-----
 4 files changed, 68 insertions(+), 17 deletions(-)
 create mode 100644 src/authentic2/templates/registration/password_reset_instructions.html
src/authentic2/templates/registration/password_reset_instructions.html
1
{% extends "authentic2/base-page.html" %}
2
{% load i18n gadjo %}
3

  
4
{% block page-title %}
5
  {% trans "Password reset instructions" %}
6
{% endblock %}
7

  
8
{% block content %}
9
  <p><strong>
10
    {% blocktrans with email=request.session.reset_email %}
11
    If your email address exists in ou database, an email has been sent to {{ email }}.
12
    {% endblocktrans %}
13
  </strong></p>
14
  <p><strong>
15
    {% blocktrans %}
16
    Follow the instructions in this email in order to choose a new password.
17
    {% endblocktrans %}
18
  </strong></p>
19
  {% block advice %}
20
    <p>
21
    {% blocktrans %}
22
    The email may take several minutes to be received. It can also be
23
    considered as spam: please look in your "junk mail" folder.
24
    {% endblocktrans %}
25
    </p>
26
    <p>
27
    {% blocktrans %}
28
    If you still have not received the instructions, add "{{from_email_address}}"
29
    to your address book or authorized sender list, and then repeat the
30
    password reset process.
31
    {% endblocktrans %}
32
  {% endblock %}
33
    </p>
34
    {% block back %}
35
      <p><a href="{% url 'auth_login' %}">{% trans "Back to login" %}</a></p>
36
    {% endblock %}
37
{% endblock %}
src/authentic2/urls.py
81 81
    url(r'^password/reset/$',
82 82
        views.password_reset,
83 83
        name='password_reset'),
84
    url(r'^password/reset/instructions/$',
85
        views.password_reset_instructions,
86
        name='password_reset_instructions'),
84 87

  
85 88
    # Legacy, only there to provide old view names to resolver
86 89
    url(r'^password/change/$',
src/authentic2/views.py
626 626
    return HttpResponseRedirect(request.get_full_path())
627 627

  
628 628

  
629
class PasswordResetView(cbv.NextURLViewMixin, FormView):
629
class PasswordResetView(FormView):
630 630
    '''Ask for an email and send a password reset link by mail'''
631 631
    form_class = passwords_forms.PasswordResetForm
632 632
    title = _('Password Reset')
633
    next_url_default = '/'
633

  
634
    def get_success_url(self):
635
        return reverse('password_reset_instructions')
634 636

  
635 637
    def get_template_names(self):
636 638
        return [
......
653 655

  
654 656
    def form_valid(self, form):
655 657
        form.save()
656
        # return to next URL
657
        messages.info(self.request, _('If your email address exists in our '
658
                                      'database, you will receive an email '
659
                                      'containing instructions to reset '
660
                                      'your password'))
658
        self.request.session['reset_email'] = form.cleaned_data['email']
661 659
        return super(PasswordResetView, self).form_valid(form)
662 660

  
663 661
password_reset = PasswordResetView.as_view()
664 662

  
665 663

  
664
class PasswordResetInstructionsView(TemplateView):
665
    template_name = 'registration/password_reset_instructions.html'
666

  
667
    def get_context_data(self, **kwargs):
668
        ctx = super(PasswordResetInstructionsView, self).get_context_data(**kwargs)
669
        ctx['from_email_address'] = parseaddr(settings.DEFAULT_FROM_EMAIL)[1]
670
        return ctx
671

  
672

  
673
password_reset_instructions = PasswordResetInstructionsView.as_view()
674

  
675

  
666 676
class PasswordResetConfirmView(cbv.RedirectToNextURLViewMixin, FormView):
667 677
    '''Validate password reset link, show a set password form and login
668 678
       the user.
tests/test_password_reset.py
39 39
    assert str(app.session['_auth_user_id']) == str(simple_user.pk)
40 40

  
41 41

  
42
def test_view(app, simple_user, mailoutbox):
43
    url = reverse('password_reset') + '?next=/moncul/'
42
def test_view(app, simple_user, mailoutbox, settings):
43
    url = reverse('password_reset')
44 44
    resp = app.get(url, status=200)
45 45
    resp.form.set('email', simple_user.email)
46 46
    assert len(mailoutbox) == 0
47
    settings.DEFAULT_FROM_EMAIL = 'show only addr <noreply@example.net>'
47 48
    resp = resp.form.submit()
48
    assert resp['Location'].endswith('/moncul/')
49
    assert resp['Location'].endswith('/instructions/')
50
    resp = resp.follow()
51
    assert simple_user.email in resp.text
52
    assert '"noreply@example.net"' in resp.text
53
    assert 'show only addr' not in resp.text
49 54
    assert len(mailoutbox) == 1
50 55
    url = utils.get_link_from_mail(mailoutbox[0])
51 56
    relative_url = url.split('testserver')[1]
......
55 60
    resp = resp.form.submit()
56 61
    # verify user is logged
57 62
    assert str(app.session['_auth_user_id']) == str(simple_user.pk)
58
    # verify next_url was kept
59
    assert resp['Location'].endswith('/moncul/')
60 63

  
61 64
    with override_settings(A2_USER_CAN_RESET_PASSWORD=False):
62
        url = reverse('password_reset') + '?next=/moncul/'
65
        url = reverse('password_reset')
63 66
        app.get(url, status=404)
64 67

  
65 68
def test_user_filter(app, simple_user, mailoutbox, settings):
66 69
    settings.A2_USER_FILTER = {'username': 'xxx'}  # will not match simple_user
67 70

  
68
    url = reverse('password_reset') + '?next=/moncul/'
71
    url = reverse('password_reset')
69 72
    resp = app.get(url, status=200)
70 73
    resp.form.set('email', simple_user.email)
71 74
    assert len(mailoutbox) == 0
72 75
    resp = resp.form.submit()
73
    assert resp['Location'].endswith('/moncul/')
74 76
    assert len(mailoutbox) == 0
75 77

  
76 78

  
77 79
def test_user_exclude(app, simple_user, mailoutbox, settings):
78 80
    settings.A2_USER_EXCLUDE = {'username': simple_user.username}  # will not match simple_user
79 81

  
80
    url = reverse('password_reset') + '?next=/moncul/'
82
    url = reverse('password_reset')
81 83
    resp = app.get(url, status=200)
82 84
    resp.form.set('email', simple_user.email)
83 85
    assert len(mailoutbox) == 0
84 86
    resp = resp.form.submit()
85
    assert resp['Location'].endswith('/moncul/')
86 87
    assert len(mailoutbox) == 0
87
-