workflows: reject mails over 50MB (#50002) #563
|
@ -287,6 +287,38 @@ def test_email_django_escaping(pub, emails):
|
|||
assert emails.get('1 < 3')
|
||||
|
||||
|
||||
def test_email_too_big(pub, emails):
|
||||
pub.loggederror_class.wipe()
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'baz'
|
||||
formdef.fields = [
|
||||
FileField(id='3', label='File', varname='file'),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
upload = PicklableUpload('test.txt', 'text/plain')
|
||||
upload.receive([b'x' * 50_000_000])
|
||||
formdata = formdef.data_class()()
|
||||
formdata.data = {'3': upload}
|
||||
formdata.just_created()
|
||||
formdata.store()
|
||||
pub.substitutions.feed(formdata)
|
||||
|
||||
sendmail = SendmailWorkflowStatusItem()
|
||||
sendmail.subject = 'foobar'
|
||||
sendmail.body = 'test'
|
||||
sendmail.to = ['to@example.net']
|
||||
sendmail.attachments = ['form_var_file_raw']
|
||||
sendmail.perform(formdata)
|
||||
get_response().process_after_jobs()
|
||||
assert emails.count() == 0
|
||||
assert pub.loggederror_class.count() == 1
|
||||
logged_error = pub.loggederror_class.select()[0]
|
||||
assert logged_error.summary == 'Email too big to be sent'
|
||||
os.unlink(formdata.data['3'].get_fs_filename()) # clean big file
|
||||
|
||||
|
||||
def test_email_attachments(pub, emails):
|
||||
formdef = FormDef()
|
||||
formdef.name = 'baz'
|
||||
|
|
|
@ -344,6 +344,9 @@ def email(
|
|||
if html_body:
|
||||
email_msg.content_subtype = 'html'
|
||||
|
||||
if len(str(email_msg.message())) > 50_000_000:
|
||||
raise errors.TooBigEmailError()
|
||||
|
||||
email_to_send = EmailToSend(email_msg, smtp_timeout)
|
||||
if not fire_and_forget:
|
||||
email_to_send()
|
||||
|
|
|
@ -76,6 +76,10 @@ class EmailError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class TooBigEmailError(EmailError):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class InternalServerError(PublishError):
|
||||
status_code = 500
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ from quixote.html import htmltext
|
|||
|
||||
from wcs.mail_templates import MailTemplate
|
||||
from wcs.qommon import _, emails
|
||||
from wcs.qommon.errors import TooBigEmailError
|
||||
from wcs.qommon.form import (
|
||||
ComputedExpressionWidget,
|
||||
SingleSelectWidget,
|
||||
|
@ -395,25 +396,28 @@ class SendmailWorkflowStatusItem(WorkflowStatusItem):
|
|||
)
|
||||
formdata.store()
|
||||
|
||||
if len(addresses) > 1:
|
||||
emails.email(
|
||||
mail_subject,
|
||||
mail_body,
|
||||
email_rcpt=None,
|
||||
bcc=addresses,
|
||||
email_from=email_from,
|
||||
attachments=attachments,
|
||||
fire_and_forget=True,
|
||||
)
|
||||
else:
|
||||
emails.email(
|
||||
mail_subject,
|
||||
mail_body,
|
||||
email_rcpt=addresses,
|
||||
email_from=email_from,
|
||||
attachments=attachments,
|
||||
fire_and_forget=True,
|
||||
)
|
||||
try:
|
||||
if len(addresses) > 1:
|
||||
emails.email(
|
||||
mail_subject,
|
||||
mail_body,
|
||||
email_rcpt=None,
|
||||
bcc=addresses,
|
||||
email_from=email_from,
|
||||
attachments=attachments,
|
||||
fire_and_forget=True,
|
||||
)
|
||||
else:
|
||||
emails.email(
|
||||
mail_subject,
|
||||
mail_body,
|
||||
email_rcpt=addresses,
|
||||
email_from=email_from,
|
||||
attachments=attachments,
|
||||
fire_and_forget=True,
|
||||
)
|
||||
except TooBigEmailError:
|
||||
get_publisher().record_error(_('Email too big to be sent'), formdata=formdata, status_item=self)
|
||||
|
||||
def i18n_scan(self, base_location):
|
||||
location = '%sitems/%s/' % (base_location, self.id)
|
||||
|
|
Loading…
Reference in New Issue
Peut-être qu'on pourrait ici enregistrer la longueur du mail refusé (et la longueur max acceptée) afin que ça puisse être affiché dans l'erreur enregistrée, pour mieux comprendre la cause.
J'avais une idée comme ça au début mais le modlèle LoggedError ne permet pas d'ajouter des informations supplémentaires et je ne voulais pas me lancer dans des développements là-dedans. (et garder le même message de base pour que ça soit mergé en une seule erreur). Je verrai pour faire évoluer ça plus tard, selon les retours.