Loading AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -417,6 +417,7 @@ answer newbie questions, and generally made Django that much better: Zain Memon Christian Metts michal@plovarna.cz Justin Michalicek <jmichalicek@gmail.com> Slawek Mikula <slawek dot mikula at gmail dot com> Katie Miller <katie@sub50.com> Shawn Milochik <shawn@milochik.com> Loading django/contrib/auth/forms.py +7 −2 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ 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): from_email=None, request=None, html_email_template_name=None): """ Generates a one-use only link for resetting password and sends to the user. Loading Loading @@ -263,7 +263,12 @@ class PasswordResetForm(forms.Form): # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) email = loader.render_to_string(email_template_name, c) send_mail(subject, email, from_email, [user.email]) if html_email_template_name: html_email = loader.render_to_string(html_email_template_name, c) else: html_email = None send_mail(subject, email, from_email, [user.email], html_message=html_email) class SetPasswordForm(forms.Form): Loading django/contrib/auth/tests/templates/registration/html_password_reset_email.html 0 → 100644 +1 −0 Original line number Diff line number Diff line <html><a href="{{ protocol }}://{{ domain }}/reset/{{ uid }}/{{ token }}/">Link</a></html> django/contrib/auth/tests/test_forms.py +55 −0 Original line number Diff line number Diff line from __future__ import unicode_literals import os import re from django import forms from django.contrib.auth import get_user_model Loading Loading @@ -452,6 +453,60 @@ class PasswordResetFormTest(TestCase): form.save() self.assertEqual(len(mail.outbox), 0) @override_settings( TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',), TEMPLATE_DIRS=( os.path.join(os.path.dirname(upath(__file__)), 'templates'), ), ) def test_save_plaintext_email(self): """ Test the PasswordResetForm.save() method with no html_email_template_name parameter passed in. Test to ensure original behavior is unchanged after the parameter was added. """ (user, username, email) = self.create_dummy_user() form = PasswordResetForm({"email": email}) self.assertTrue(form.is_valid()) form.save() self.assertEqual(len(mail.outbox), 1) message = mail.outbox[0].message() self.assertFalse(message.is_multipart()) self.assertEqual(message.get_content_type(), 'text/plain') self.assertEqual(message.get('subject'), 'Custom password reset on example.com') self.assertEqual(len(mail.outbox[0].alternatives), 0) self.assertEqual(message.get_all('to'), [email]) self.assertTrue(re.match(r'^http://example.com/reset/[\w+/-]', message.get_payload())) @override_settings( TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',), TEMPLATE_DIRS=( os.path.join(os.path.dirname(upath(__file__)), 'templates'), ), ) def test_save_html_email_template_name(self): """ Test the PasswordResetFOrm.save() method with html_email_template_name parameter specified. Test to ensure that a multipart email is sent with both text/plain and text/html parts. """ (user, username, email) = self.create_dummy_user() form = PasswordResetForm({"email": email}) self.assertTrue(form.is_valid()) form.save(html_email_template_name='registration/html_password_reset_email.html') self.assertEqual(len(mail.outbox), 1) self.assertEqual(len(mail.outbox[0].alternatives), 1) message = mail.outbox[0].message() self.assertEqual(message.get('subject'), 'Custom password reset on example.com') self.assertEqual(len(message.get_payload()), 2) self.assertTrue(message.is_multipart()) self.assertEqual(message.get_payload(0).get_content_type(), 'text/plain') self.assertEqual(message.get_payload(1).get_content_type(), 'text/html') self.assertEqual(message.get_all('to'), [email]) self.assertTrue(re.match(r'^http://example.com/reset/[\w/-]+', message.get_payload(0).get_payload())) self.assertTrue(re.match(r'^<html><a href="http://example.com/reset/[\w/-]+/">Link</a></html>$', message.get_payload(1).get_payload())) class ReadOnlyPasswordHashTest(TestCase): Loading django/contrib/auth/tests/test_views.py +19 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,25 @@ class PasswordResetTest(AuthViewsTestCase): self.assertEqual(len(mail.outbox), 1) self.assertTrue("http://" in mail.outbox[0].body) self.assertEqual(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email) # optional multipart text/html email has been added. Make sure original, # default functionality is 100% the same self.assertFalse(mail.outbox[0].message().is_multipart()) def test_html_mail_template(self): """ A multipart email with text/plain and text/html is sent if the html_email_template parameter is passed to the view """ response = self.client.post('/password_reset/html_email_template/', {'email': 'staffmember@example.com'}) self.assertEqual(response.status_code, 302) self.assertEqual(len(mail.outbox), 1) message = mail.outbox[0].message() self.assertEqual(len(message.get_payload()), 2) self.assertTrue(message.is_multipart()) self.assertEqual(message.get_payload(0).get_content_type(), 'text/plain') self.assertEqual(message.get_payload(1).get_content_type(), 'text/html') self.assertTrue('<html>' not in message.get_payload(0).get_payload()) self.assertTrue('<html>' in message.get_payload(1).get_payload()) def test_email_found_custom_from(self): "Email is sent if a valid email address is provided for password reset when a custom from_email is provided." Loading Loading
AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -417,6 +417,7 @@ answer newbie questions, and generally made Django that much better: Zain Memon Christian Metts michal@plovarna.cz Justin Michalicek <jmichalicek@gmail.com> Slawek Mikula <slawek dot mikula at gmail dot com> Katie Miller <katie@sub50.com> Shawn Milochik <shawn@milochik.com> Loading
django/contrib/auth/forms.py +7 −2 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ 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): from_email=None, request=None, html_email_template_name=None): """ Generates a one-use only link for resetting password and sends to the user. Loading Loading @@ -263,7 +263,12 @@ class PasswordResetForm(forms.Form): # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) email = loader.render_to_string(email_template_name, c) send_mail(subject, email, from_email, [user.email]) if html_email_template_name: html_email = loader.render_to_string(html_email_template_name, c) else: html_email = None send_mail(subject, email, from_email, [user.email], html_message=html_email) class SetPasswordForm(forms.Form): Loading
django/contrib/auth/tests/templates/registration/html_password_reset_email.html 0 → 100644 +1 −0 Original line number Diff line number Diff line <html><a href="{{ protocol }}://{{ domain }}/reset/{{ uid }}/{{ token }}/">Link</a></html>
django/contrib/auth/tests/test_forms.py +55 −0 Original line number Diff line number Diff line from __future__ import unicode_literals import os import re from django import forms from django.contrib.auth import get_user_model Loading Loading @@ -452,6 +453,60 @@ class PasswordResetFormTest(TestCase): form.save() self.assertEqual(len(mail.outbox), 0) @override_settings( TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',), TEMPLATE_DIRS=( os.path.join(os.path.dirname(upath(__file__)), 'templates'), ), ) def test_save_plaintext_email(self): """ Test the PasswordResetForm.save() method with no html_email_template_name parameter passed in. Test to ensure original behavior is unchanged after the parameter was added. """ (user, username, email) = self.create_dummy_user() form = PasswordResetForm({"email": email}) self.assertTrue(form.is_valid()) form.save() self.assertEqual(len(mail.outbox), 1) message = mail.outbox[0].message() self.assertFalse(message.is_multipart()) self.assertEqual(message.get_content_type(), 'text/plain') self.assertEqual(message.get('subject'), 'Custom password reset on example.com') self.assertEqual(len(mail.outbox[0].alternatives), 0) self.assertEqual(message.get_all('to'), [email]) self.assertTrue(re.match(r'^http://example.com/reset/[\w+/-]', message.get_payload())) @override_settings( TEMPLATE_LOADERS=('django.template.loaders.filesystem.Loader',), TEMPLATE_DIRS=( os.path.join(os.path.dirname(upath(__file__)), 'templates'), ), ) def test_save_html_email_template_name(self): """ Test the PasswordResetFOrm.save() method with html_email_template_name parameter specified. Test to ensure that a multipart email is sent with both text/plain and text/html parts. """ (user, username, email) = self.create_dummy_user() form = PasswordResetForm({"email": email}) self.assertTrue(form.is_valid()) form.save(html_email_template_name='registration/html_password_reset_email.html') self.assertEqual(len(mail.outbox), 1) self.assertEqual(len(mail.outbox[0].alternatives), 1) message = mail.outbox[0].message() self.assertEqual(message.get('subject'), 'Custom password reset on example.com') self.assertEqual(len(message.get_payload()), 2) self.assertTrue(message.is_multipart()) self.assertEqual(message.get_payload(0).get_content_type(), 'text/plain') self.assertEqual(message.get_payload(1).get_content_type(), 'text/html') self.assertEqual(message.get_all('to'), [email]) self.assertTrue(re.match(r'^http://example.com/reset/[\w/-]+', message.get_payload(0).get_payload())) self.assertTrue(re.match(r'^<html><a href="http://example.com/reset/[\w/-]+/">Link</a></html>$', message.get_payload(1).get_payload())) class ReadOnlyPasswordHashTest(TestCase): Loading
django/contrib/auth/tests/test_views.py +19 −0 Original line number Diff line number Diff line Loading @@ -128,6 +128,25 @@ class PasswordResetTest(AuthViewsTestCase): self.assertEqual(len(mail.outbox), 1) self.assertTrue("http://" in mail.outbox[0].body) self.assertEqual(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email) # optional multipart text/html email has been added. Make sure original, # default functionality is 100% the same self.assertFalse(mail.outbox[0].message().is_multipart()) def test_html_mail_template(self): """ A multipart email with text/plain and text/html is sent if the html_email_template parameter is passed to the view """ response = self.client.post('/password_reset/html_email_template/', {'email': 'staffmember@example.com'}) self.assertEqual(response.status_code, 302) self.assertEqual(len(mail.outbox), 1) message = mail.outbox[0].message() self.assertEqual(len(message.get_payload()), 2) self.assertTrue(message.is_multipart()) self.assertEqual(message.get_payload(0).get_content_type(), 'text/plain') self.assertEqual(message.get_payload(1).get_content_type(), 'text/html') self.assertTrue('<html>' not in message.get_payload(0).get_payload()) self.assertTrue('<html>' in message.get_payload(1).get_payload()) def test_email_found_custom_from(self): "Email is sent if a valid email address is provided for password reset when a custom from_email is provided." Loading