Improve validation of email templates (#4184)

* Improve validation of email templates

* simplify SafeFormatter (skip attribute access code path altogether instead of blocklisting characters)

* let SafeFormatter optionally raise on missing key

* simplify placeholder validation

* rename parameter

* Remove unused import

---------

Co-authored-by: Raphael Michel <michel@rami.io>
This commit is contained in:
Mira
2024-06-10 16:41:52 +02:00
committed by GitHub
parent ab576bb643
commit dd6ebd7a48
3 changed files with 38 additions and 36 deletions

View File

@@ -73,6 +73,7 @@ from i18nfield.utils import I18nJSONEncoder
from pretix.base.channels import get_all_sales_channels
from pretix.base.email import get_available_placeholders
from pretix.base.forms import PlaceholderValidator
from pretix.base.models import Event, LogEntry, Order, TaxRule, Voucher
from pretix.base.models.event import EventMetaValue
from pretix.base.services import tickets
@@ -713,11 +714,6 @@ class MailSettingsSetup(EventPermissionRequiredMixin, MailSettingsSetupView):
class MailSettingsPreview(EventPermissionRequiredMixin, View):
permission = 'can_change_event_settings'
# return the origin text if key is missing in dict
class SafeDict(dict):
def __missing__(self, key):
return '{' + key + '}'
# create index-language mapping
@cached_property
def supported_locale(self):
@@ -742,7 +738,7 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
_('This value will be replaced based on dynamic parameters.'),
s
)
return self.SafeDict(ctx)
return ctx
def post(self, request, *args, **kwargs):
preview_item = request.POST.get('item', '')
@@ -758,12 +754,21 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
idx = matched.group('idx')
if idx in self.supported_locale:
with language(self.supported_locale[idx], self.request.event.settings.region):
if k.startswith('mail_subject_'):
msgs[self.supported_locale[idx]] = format_map(bleach.clean(v), self.placeholders(preview_item))
else:
msgs[self.supported_locale[idx]] = markdown_compile_email(
format_map(v, self.placeholders(preview_item))
)
try:
if k.startswith('mail_subject_'):
msgs[self.supported_locale[idx]] = format_map(
bleach.clean(v), self.placeholders(preview_item), raise_on_missing=True
)
else:
msgs[self.supported_locale[idx]] = markdown_compile_email(
format_map(v, self.placeholders(preview_item), raise_on_missing=True)
)
except ValueError:
msgs[self.supported_locale[idx]] = '<div class="alert alert-danger">{}</div>'.format(
PlaceholderValidator.error_message)
except KeyError as e:
msgs[self.supported_locale[idx]] = '<div class="alert alert-danger">{}</div>'.format(
_('Invalid placeholder: {%(value)s}') % {'value': e.args[0]})
return JsonResponse({
'item': preview_item,