Skip to content

Commit

Permalink
Handle huge single message email notifications
Browse files Browse the repository at this point in the history
fedmsg_meta does some insane things in its msg2long_form[0]. Add a guard
to make sure any crazy msg2long_form implementation can't produce a
multi-{MB,GB,TB...ZB} message.

Signed-off-by: Jeremy Cline <jeremy@jcline.org>
  • Loading branch information
jeremycline committed Mar 27, 2018
1 parent 1d9d28f commit eeff7f0
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Bug fixes
* Set digest content limits to 1k messages and 500k content length
(`#280 <https://github.com/fedora-infra/fmn/pull/280>`_).

* Limit single message emails to 500K characters to ensure multi-MB emails
don't get stuck in the message queue
(`#288 <https://github.com/fedora-infra/fmn/pull/288>`_).

v2.0.2
======
Expand Down
6 changes: 6 additions & 0 deletions fmn/formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,12 @@ def email(message, recipient):
except Exception:
_log.exception('fedmsg.meta.msg2link failed to handle %r', message)

if len(content) >= 500000:
# This email is enormous, too large to be sent. This happens if fedmsg_meta
# did something silly in its msg2long_form implementation.
content = (u'This message was too large to be sent!\n'
u'The message ID was: {}\n\n').format(message['msg_id'])

# Since we do simple text email, adding the footer to the content
# before setting the payload.
footer = config.app_conf.get('fmn.email.footer', u'')
Expand Down
23 changes: 23 additions & 0 deletions fmn/tests/test_formatters.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,29 @@ def test_email(self):
actual = formatters.email(self.message, self.recipient)
self.assertEqual(expected, actual)

@mock.patch('fmn.formatters.fedmsg.meta.msg2long_form', mock.Mock(return_value='a'*500000))
def test_email_too_big(self):
"""Assert huge single message emails are handled gracefully."""
expected = (
'Precedence: Bulk\n'
'Auto-Submitted: auto-generated\n'
'From: notifications@fedoraproject.org\n'
'To: jeremy@jcline.org\n'
'X-Fedmsg-Topic: org.fedoraproject.dev.fmn.filter.update\n'
'X-Fedmsg-Category: fmn\n'
'X-Fedmsg-Username: jcline\n'
'X-Fedmsg-Num-Packages: 0\n'
'Subject: jcline updated the rules on a fmn email filter\n'
'MIME-Version: 1.0\n'
'Content-Type: text/plain; charset="utf-8"\n'
'Content-Transfer-Encoding: base64\n\n'
'VGhpcyBtZXNzYWdlIHdhcyB0b28gbGFyZ2UgdG8gYmUgc2VudCEKVGhlIG1lc3NhZ2UgSUQgd2Fz\n'
'OiAyMDE3LTZhYTcxZDViLWZiZTQtNDllNy1hZmRkLWFmY2YwZDIyODAyYgoK\n'
)

actual = formatters.email(self.message, self.recipient)
self.assertEqual(expected, actual)

@mock.patch.dict('fmn.formatters.config.app_conf', {'fmn.email.subject_prefix': 'PREFIX: '})
def test_subject_prefix(self):
"""Assert the subject prefix is added if configured."""
Expand Down

0 comments on commit eeff7f0

Please sign in to comment.