Code

Ticket #1541: multipart_mail.diff

File multipart_mail.diff, 2.1 KB (added by bruce@…, 8 years ago)

mail.py patch

Line 
1Index: mail.py
2===================================================================
3--- mail.py     (revision 2562)
4+++ mail.py     (working copy)
5@@ -2,11 +2,19 @@
6 
7 from django.conf.settings import DEFAULT_FROM_EMAIL, EMAIL_HOST, EMAIL_SUBJECT_PREFIX, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD
8 from email.MIMEText import MIMEText
9+from email.MIMEMultipart import MIMEMultipart
10 import smtplib
11 
12 class BadHeaderError(ValueError):
13     pass
14 
15+class SafeMIMEMultipart(MIMEMultipart):
16+    def __setitem__(self, name, val):
17+        "Forbids multi-line headers, to prevent header injection."
18+        if '\n' in val or '\r' in val:
19+            raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name)
20+        MIMEMultipart.__setitem__(self, name, val)
21+
22 class SafeMIMEText(MIMEText):
23     def __setitem__(self, name, val):
24         "Forbids multi-line headers, to prevent header injection."
25@@ -18,6 +26,7 @@
26     """
27     Easy wrapper for sending a single message to a recipient list. All members
28     of the recipient list will see the other recipients in the 'To' field.
29+    Note that the message parameter can be either text or one of the SafeMIMExxx methods listed above.
30     """
31     return send_mass_mail([[subject, message, from_email, recipient_list]], fail_silently, auth_user, auth_password)
32 
33@@ -28,6 +37,7 @@
34 
35     If from_email is None, the DEFAULT_FROM_EMAIL setting is used.
36     If auth_user and auth_password are set, they're used to log in.
37+    Note that the message parameter can be either text or one of the SafeMIMExxx methods listed above.
38     """
39     try:
40         server = smtplib.SMTP(EMAIL_HOST)
41@@ -42,7 +52,12 @@
42         if not recipient_list:
43             continue
44         from_email = from_email or DEFAULT_FROM_EMAIL
45-        msg = SafeMIMEText(message)
46+
47+        if isinstance(message, SafeMIMEText) or isinstance(message, SafeMIMEMultipart):
48+            msg = message
49+        else:
50+            msg = SafeMIMEText(message)
51+
52         msg['Subject'] = subject
53         msg['From'] = from_email
54         msg['To'] = ', '.join(recipient_list)