Raise NotSupportedByMandrillError for unsupported attachment mimetypes.

This commit is contained in:
medmunds
2013-01-11 17:26:09 -08:00
parent 18d27fdb21
commit ad4b9f38ff
3 changed files with 34 additions and 4 deletions

View File

@@ -134,10 +134,10 @@ Djrill supports most of the functionality of Django's `EmailMessage`_ and
raise a ``djrill.NotSupportedByMandrillError`` exception when you attempt to raise a ``djrill.NotSupportedByMandrillError`` exception when you attempt to
send the message. (Mandrill doesn't support sending multiple html alternative send the message. (Mandrill doesn't support sending multiple html alternative
parts, or any non-html alternatives.) parts, or any non-html alternatives.)
* Djrill attempts to include a message's attachments, but Mandrill will * Djrill includes a message's attachments, but only with the mimetypes "text/\*",
(silently) ignore any attachment types it doesn't allow. According to "image/\*", or "application/pdf" (since that is all Mandrill allows). Any
Mandrill's docs, attachments are only allowed with the mimetypes "text/\*", other attachment types will raise a ``djrill.NotSupportedByMandrillError``
"image/\*", or "application/pdf". exception when you attempt to send the message.
* Djrill treats all cc and bcc recipients as if they were additional "to" * Djrill treats all cc and bcc recipients as if they were additional "to"
addresses. (Mandrill does not distinguish cc, and only allows a single bcc -- addresses. (Mandrill does not distinguish cc, and only allows a single bcc --
which Djrill doesn't use. *Caution:* depending on the ``preserve_recipients`` which Djrill doesn't use. *Caution:* depending on the ``preserve_recipients``

View File

@@ -226,6 +226,18 @@ class DjrillBackend(BaseEmailBackend):
if mimetype is None: if mimetype is None:
mimetype = DEFAULT_ATTACHMENT_MIME_TYPE mimetype = DEFAULT_ATTACHMENT_MIME_TYPE
# Mandrill silently filters attachments with unsupported mimetypes.
# This can be confusing, so we raise an exception instead.
(main, sub) = mimetype.lower().split('/')
attachment_allowed = (
main == 'text' or main == 'image'
or (main == 'application' and sub == 'pdf'))
if not attachment_allowed:
raise NotSupportedByMandrillError(
"Invalid attachment mimetype '%s'. Mandrill only supports "
"text/*, image/*, and application/pdf attachments."
% mimetype)
return { return {
'type': mimetype, 'type': mimetype,
'name': filename or "", 'name': filename or "",

View File

@@ -160,6 +160,24 @@ class DjrillBackendTests(DjrillBackendMockAPITestCase):
msg="Mandrill API should not be called when send fails silently") msg="Mandrill API should not be called when send fails silently")
self.assertEqual(sent, 0) self.assertEqual(sent, 0)
def test_attachment_errors(self):
# Mandrill silently strips attachments that aren't text/*, image/*,
# or application/pdf. We want to alert the Djrill user:
with self.assertRaises(NotSupportedByMandrillError):
msg = mail.EmailMessage('Subject', 'Body',
'from@example.com', ['to@example.com'])
# This is the default mimetype, but won't work with Mandrill:
msg.attach(content="test", mimetype="application/octet-stream")
msg.send()
with self.assertRaises(NotSupportedByMandrillError):
msg = mail.EmailMessage('Subject', 'Body',
'from@example.com', ['to@example.com'])
# Can't send Office docs, either:
msg.attach(filename="presentation.ppt", content="test",
mimetype="application/vnd.ms-powerpoint")
msg.send()
def test_mandrill_api_failure(self): def test_mandrill_api_failure(self):
self.mock_post.return_value = self.MockResponse(status_code=400) self.mock_post.return_value = self.MockResponse(status_code=400)
with self.assertRaises(MandrillAPIError): with self.assertRaises(MandrillAPIError):