api: prevent crash on invalid event_display_template (#54388)
This commit is contained in:
parent
7d7f52487c
commit
2921ed52a3
|
@ -130,6 +130,20 @@ def django_template_validator(value):
|
|||
raise ValidationError(_('syntax error: %s') % e)
|
||||
|
||||
|
||||
def event_template_validator(value):
|
||||
example_event = Event(
|
||||
start_datetime=now(),
|
||||
publication_date=now().date(),
|
||||
recurrence_end_date=now().date(),
|
||||
places=1,
|
||||
duration=1,
|
||||
)
|
||||
try:
|
||||
event_text = Template(value).render(Context({'event': example_event}))
|
||||
except (VariableDoesNotExist, TemplateSyntaxError) as e:
|
||||
raise ValidationError(_('syntax error: %s') % e)
|
||||
|
||||
|
||||
class ICSError(Exception):
|
||||
pass
|
||||
|
||||
|
@ -224,6 +238,7 @@ class Agenda(models.Model):
|
|||
_('Event display template'),
|
||||
max_length=256,
|
||||
blank=True,
|
||||
validators=[event_template_validator],
|
||||
help_text=_(
|
||||
'By default event labels will be displayed to users. '
|
||||
'This allows for a custom template to include additional informations. '
|
||||
|
|
|
@ -24,7 +24,7 @@ from django.db.models import Count, Prefetch, Q
|
|||
from django.db.models.functions import TruncDay
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.template import Context, Template
|
||||
from django.template import Context, Template, TemplateSyntaxError, VariableDoesNotExist
|
||||
from django.urls import reverse
|
||||
from django.utils.dateparse import parse_date, parse_datetime
|
||||
from django.utils.encoding import force_text
|
||||
|
@ -425,7 +425,10 @@ def get_event_detail(request, event, agenda=None, min_places=1, booked_user_exte
|
|||
agenda = agenda or event.agenda
|
||||
event_text = force_text(event)
|
||||
if agenda.event_display_template:
|
||||
event_text = Template(agenda.event_display_template).render(Context({'event': event}))
|
||||
try:
|
||||
event_text = Template(agenda.event_display_template).render(Context({'event': event}))
|
||||
except (VariableDoesNotExist, TemplateSyntaxError):
|
||||
pass
|
||||
elif event.label and event.primary_event is not None:
|
||||
event_text = '%s (%s)' % (
|
||||
event.label,
|
||||
|
|
|
@ -119,6 +119,18 @@ def test_datetime_api_label(app):
|
|||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
|
||||
assert resp.json['data'][0]['text'] == 'Hello world (4/5 places remaining)'
|
||||
|
||||
# invalid template yields default text
|
||||
invalid_templates = [
|
||||
'{{ syntax error }}',
|
||||
'{{ event.label|invalidfilter }}',
|
||||
'{{ event.label|default:notexist }}',
|
||||
]
|
||||
for template in invalid_templates:
|
||||
agenda.event_display_template = template
|
||||
agenda.save()
|
||||
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug)
|
||||
assert resp.json['data'][0]['text'] == 'Hello world'
|
||||
|
||||
|
||||
def test_datetime_api_urls(app):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0)
|
||||
|
|
|
@ -579,6 +579,30 @@ def test_options_agenda_booking_check_options(app, admin_user):
|
|||
app.get(url, status=404)
|
||||
|
||||
|
||||
def test_options_agenda_event_display_template(app, admin_user):
|
||||
agenda = Agenda.objects.create(label='Foo bar', kind='events')
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/agendas/%s/edit' % agenda.pk)
|
||||
valid_template = '{{ event.label|default:event.slug }} - {{ event.remaining_places|add:"5" }} / {{ event.start_datetime|date }} - {{ event.agenda.name }}'
|
||||
resp.form['event_display_template'] = valid_template
|
||||
resp = resp.form.submit().follow()
|
||||
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.event_display_template == valid_template
|
||||
|
||||
invalid_templates = [
|
||||
'{{ syntax error }}',
|
||||
'{{ event.label|invalidfilter }}',
|
||||
'{{ event.label|default:notexist }}',
|
||||
]
|
||||
for template in invalid_templates:
|
||||
resp = app.get('/manage/agendas/%s/edit' % agenda.pk)
|
||||
resp.form['event_display_template'] = template
|
||||
resp = resp.form.submit()
|
||||
assert 'syntax error' in resp.text
|
||||
|
||||
|
||||
def test_options_agenda_as_manager(app, manager_user):
|
||||
agenda = Agenda(label=u'Foo bar')
|
||||
agenda.view_role = manager_user.groups.all()[0]
|
||||
|
|
Loading…
Reference in New Issue