truncate email from addresses if >320 chars when encoded (TNL-4264) (#12171)
* truncate email from addresses if >320 chars when encoded (TNL-4264) * use exact lengths
This commit is contained in:
@@ -32,6 +32,7 @@ from celery.exceptions import RetryTaskError # pylint: disable=no-name-in-modul
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.mail import EmailMultiAlternatives, get_connection
|
||||
from django.core.mail.message import forbid_multi_line_headers
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from bulk_email.models import (
|
||||
@@ -384,13 +385,20 @@ def _filter_optouts_from_recipients(to_list, course_id):
|
||||
return to_list, num_optout
|
||||
|
||||
|
||||
def _get_source_address(course_id, course_title):
|
||||
def _get_source_address(course_id, course_title, truncate=True):
|
||||
"""
|
||||
Calculates an email address to be used as the 'from-address' for sent emails.
|
||||
|
||||
Makes a unique from name and address for each course, e.g.
|
||||
|
||||
"COURSE_TITLE" Course Staff <coursenum-no-reply@courseupdates.edx.org>
|
||||
"COURSE_TITLE" Course Staff <course_name-no-reply@courseupdates.edx.org>
|
||||
|
||||
If, when decoded to ascii, this from_addr is longer than 320 characters,
|
||||
use the course_name rather than the course title, e.g.
|
||||
|
||||
"course_name" Course Staff <course_name-no-reply@courseupdates.edx.org>
|
||||
|
||||
The "truncate" kwarg is only used for tests.
|
||||
|
||||
"""
|
||||
course_title_no_quotes = re.sub(r'"', '', course_title)
|
||||
@@ -418,10 +426,11 @@ def _get_source_address(course_id, course_title):
|
||||
|
||||
from_addr = format_address(course_title_no_quotes)
|
||||
|
||||
# If it's longer than 320 characters, reformat, but with the course name
|
||||
# rather than course title. Amazon SES's from address field appears to have a maximum
|
||||
# length of 320.
|
||||
if len(from_addr) >= 320:
|
||||
# If the encoded from_addr is longer than 320 characters, reformat,
|
||||
# but with the course name rather than course title.
|
||||
# Amazon SES's from address field appears to have a maximum length of 320.
|
||||
__, encoded_from_addr = forbid_multi_line_headers('from', from_addr, 'utf-8')
|
||||
if len(encoded_from_addr) >= 320 and truncate:
|
||||
from_addr = format_address(course_name)
|
||||
|
||||
return from_addr
|
||||
|
||||
@@ -10,11 +10,13 @@ from unittest import skipIf
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import mail
|
||||
from django.core.mail.message import forbid_multi_line_headers
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.management import call_command
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from bulk_email.models import Optout
|
||||
from bulk_email.tasks import _get_source_address
|
||||
from courseware.tests.factories import StaffFactory, InstructorFactory
|
||||
from instructor_task.subtasks import update_subtask_status
|
||||
from student.roles import CourseStaffRole
|
||||
@@ -322,13 +324,24 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase)
|
||||
'message': 'test message for self'
|
||||
}
|
||||
|
||||
# make very long display_name for course
|
||||
long_name = u"x" * 321
|
||||
# make display_name that's longer than 320 characters when encoded
|
||||
# to ascii, but shorter than 320 unicode characters
|
||||
long_name = u"é" * 200
|
||||
|
||||
course = CourseFactory.create(
|
||||
display_name=long_name, number="bulk_email_course_name"
|
||||
)
|
||||
instructor = InstructorFactory(course_key=course.id)
|
||||
|
||||
unexpected_from_addr = _get_source_address(
|
||||
course.id, course.display_name, truncate=False
|
||||
)
|
||||
__, encoded_unexpected_from_addr = forbid_multi_line_headers(
|
||||
"from", unexpected_from_addr, 'utf-8'
|
||||
)
|
||||
self.assertEqual(len(encoded_unexpected_from_addr), 748)
|
||||
self.assertEqual(len(unexpected_from_addr), 261)
|
||||
|
||||
self.login_as_user(instructor)
|
||||
send_mail_url = reverse('send_email', kwargs={'course_id': unicode(course.id)})
|
||||
response = self.client.post(send_mail_url, test_email)
|
||||
@@ -337,11 +350,13 @@ class TestEmailSendFromDashboardMockedHtmlToText(EmailSendFromDashboardTestCase)
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
from_email = mail.outbox[0].from_email
|
||||
|
||||
expected_from_addr = (
|
||||
u'"{course_name}" Course Staff <{course_name}-no-reply@example.com>'
|
||||
).format(course_name=course.id.course)
|
||||
|
||||
self.assertEqual(
|
||||
from_email,
|
||||
u'"{course_name}" Course Staff <{course_name}-no-reply@example.com>'.format(
|
||||
course_name=course.id.course
|
||||
)
|
||||
expected_from_addr
|
||||
)
|
||||
self.assertEqual(len(from_email), 83)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user