From d8d853378b3ff75c03d8bd91ea026d2b8c642b0f Mon Sep 17 00:00:00 2001 From: sujayskumar Date: Thu, 18 Jun 2015 18:19:35 +0530 Subject: [PATCH] Fixed #24944 -- Added extra_email_context parameter to password_reset() view. --- AUTHORS | 1 + django/contrib/auth/forms.py | 6 ++++-- django/contrib/auth/views.py | 4 +++- docs/releases/1.9.txt | 3 +++ docs/topics/auth/default.txt | 9 ++++++++- .../templates/registration/password_reset_email.html | 1 + tests/auth_tests/test_views.py | 12 ++++++++++++ tests/auth_tests/urls.py | 2 ++ 8 files changed, 34 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 48322c4e197..4886eb2881a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -667,6 +667,7 @@ answer newbie questions, and generally made Django that much better: Stephen Burrows Steven L. Smith (fvox13) Stuart Langridge + Sujay S Kumar Sune Kirkeby Sung-Jin Hong SuperJared diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py index 8d0dacb3bb3..b1cedc916c0 100644 --- a/django/contrib/auth/forms.py +++ b/django/contrib/auth/forms.py @@ -229,7 +229,8 @@ class PasswordResetForm(forms.Form): subject_template_name='registration/password_reset_subject.txt', email_template_name='registration/password_reset_email.html', use_https=False, token_generator=default_token_generator, - from_email=None, request=None, html_email_template_name=None): + from_email=None, request=None, html_email_template_name=None, + extra_email_context=None): """ Generates a one-use only link for resetting password and sends to the user. @@ -251,7 +252,8 @@ class PasswordResetForm(forms.Form): 'token': token_generator.make_token(user), 'protocol': 'https' if use_https else 'http', } - + if extra_email_context is not None: + context.update(extra_email_context) self.send_mail(subject_template_name, email_template_name, context, from_email, user.email, html_email_template_name=html_email_template_name) diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index 8bc4c0c9800..2c39d0f0186 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -175,7 +175,8 @@ def password_reset(request, is_admin_site=False, post_reset_redirect=None, from_email=None, extra_context=None, - html_email_template_name=None): + html_email_template_name=None, + extra_email_context=None): if post_reset_redirect is None: post_reset_redirect = reverse('password_reset_done') else: @@ -191,6 +192,7 @@ def password_reset(request, is_admin_site=False, 'subject_template_name': subject_template_name, 'request': request, 'html_email_template_name': html_email_template_name, + 'extra_email_context': extra_email_context, } if is_admin_site: warnings.warn( diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt index 411d8bc2550..c2079f27d0d 100644 --- a/docs/releases/1.9.txt +++ b/docs/releases/1.9.txt @@ -209,6 +209,9 @@ Minor features makes it possible to use ``REMOTE_USER`` for setups where the header is only populated on login pages instead of every request in the session. +* The :func:`~django.contrib.auth.views.password_reset` view accepts an + ``extra_email_context`` parameter. + :mod:`django.contrib.contenttypes` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index e0bbb6eb645..8da0e78c472 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -1219,7 +1219,7 @@ implementation details see :ref:`using-the-views`. The ``current_app`` parameter is deprecated and will be removed in Django 2.0. Callers should set ``request.current_app`` instead. -.. function:: password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None) +.. function:: password_reset(request, is_admin_site=False, template_name='registration/password_reset_form.html', email_template_name='registration/password_reset_email.html', subject_template_name='registration/password_reset_subject.txt', password_reset_form=PasswordResetForm, token_generator=default_token_generator, post_reset_redirect=None, from_email=None, current_app=None, extra_context=None, html_email_template_name=None, extra_email_context=None) Allows a user to reset their password by generating a one-time use link that can be used to reset the password, and sending that link to the @@ -1280,6 +1280,9 @@ implementation details see :ref:`using-the-views`. for generating a ``text/html`` multipart email with the password reset link. By default, HTML email is not sent. + * ``extra_email_context``: A dictionary of context data that will available + in the email template. + .. deprecated:: 1.8 The ``is_admin_site`` argument is deprecated and will be removed in @@ -1290,6 +1293,10 @@ implementation details see :ref:`using-the-views`. The ``current_app`` parameter is deprecated and will be removed in Django 2.0. Callers should set ``request.current_app`` instead. + .. versionadded:: 1.9 + + The ``extra_email_context`` parameter was added. + **Template context:** * ``form``: The form (see ``password_reset_form`` above) for resetting diff --git a/tests/auth_tests/templates/registration/password_reset_email.html b/tests/auth_tests/templates/registration/password_reset_email.html index baac2fc2dd5..07043aa92e5 100644 --- a/tests/auth_tests/templates/registration/password_reset_email.html +++ b/tests/auth_tests/templates/registration/password_reset_email.html @@ -1 +1,2 @@ {{ protocol }}://{{ domain }}/reset/{{ uid }}/{{ token }}/ +Email email context: "{{ greeting }}" diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py index 7b497ac458e..723b20a8124 100644 --- a/tests/auth_tests/test_views.py +++ b/tests/auth_tests/test_views.py @@ -174,6 +174,18 @@ class PasswordResetTest(AuthViewsTestCase): # default functionality is 100% the same self.assertFalse(mail.outbox[0].message().is_multipart()) + def test_extra_email_context(self): + """ + extra_email_context should be available in the email template context. + """ + response = self.client.post( + '/password_reset_extra_email_context/', + {'email': 'staffmember@example.com'}, + ) + self.assertEqual(response.status_code, 302) + self.assertEqual(len(mail.outbox), 1) + self.assertIn('Email email context: "Hello!"', mail.outbox[0].body) + def test_html_mail_template(self): """ A multipart email with text/plain and text/html is sent diff --git a/tests/auth_tests/urls.py b/tests/auth_tests/urls.py index 2851b451e1b..0c43123f87a 100644 --- a/tests/auth_tests/urls.py +++ b/tests/auth_tests/urls.py @@ -71,6 +71,8 @@ urlpatterns = auth_urlpatterns + [ url(r'^logout/next_page/named/$', views.logout, dict(next_page='password_reset')), url(r'^remote_user/$', remote_user_auth_view), url(r'^password_reset_from_email/$', views.password_reset, dict(from_email='staffmember@example.com')), + url(r'^password_reset_extra_email_context/$', views.password_reset, + dict(extra_email_context=dict(greeting='Hello!'))), url(r'^password_reset/custom_redirect/$', views.password_reset, dict(post_reset_redirect='/custom/')), url(r'^password_reset/custom_redirect/named/$', views.password_reset, dict(post_reset_redirect='password_reset')), url(r'^password_reset/html_email_template/$', views.password_reset,