Commit bb5874d5 by Adam

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
parent 85453fb0
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment