diff --git a/ietf/meeting/tests_views.py b/ietf/meeting/tests_views.py index 0101287a1..14e3f99b8 100644 --- a/ietf/meeting/tests_views.py +++ b/ietf/meeting/tests_views.py @@ -1,6 +1,7 @@ import os import shutil import datetime +import urlparse from django.core.urlresolvers import reverse as urlreverse from django.conf import settings @@ -179,6 +180,8 @@ class EditTests(TestCase): 'saveas': "saveas", }) self.assertEqual(r.status_code, 302) + # Verify that we actually got redirected to a new place. + self.assertNotEqual(urlparse.urlparse(r.url).path, url) # get schedule = meeting.get_schedule_by_name("foo") @@ -211,6 +214,40 @@ class EditTests(TestCase): r = self.client.get(url) self.assertEqual(r.status_code, 200) + def test_save_agenda_broken_names(self): + meeting = make_meeting_test_data() + + # save as new name (requires valid existing agenda) + url = urlreverse("ietf.meeting.views.edit_agenda", kwargs=dict(num=meeting.number, + owner=meeting.agenda.owner_email(), + name=meeting.agenda.name)) + self.client.login(username="ad", password="ad+password") + r = self.client.post(url, { + 'savename': "/no/this/should/not/work/it/is/too/long", + 'saveas': "saveas", + }) + self.assertEqual(r.status_code, 302) + self.assertEqual(urlparse.urlparse(r.url).path, url) + # TODO: Verify that an error message was in fact returned. + + r = self.client.post(url, { + 'savename': "/invalid/chars/", + 'saveas': "saveas", + }) + # TODO: Verify that an error message was in fact returned. + self.assertEqual(r.status_code, 302) + self.assertEqual(urlparse.urlparse(r.url).path, url) + + # Non-ASCII alphanumeric characters + r = self.client.post(url, { + 'savename': u"f\u00E9ling", + 'saveas': "saveas", + }) + # TODO: Verify that an error message was in fact returned. + self.assertEqual(r.status_code, 302) + self.assertEqual(urlparse.urlparse(r.url).path, url) + + def test_edit_timeslots(self): meeting = make_meeting_test_data() diff --git a/ietf/meeting/views.py b/ietf/meeting/views.py index ceaae58b8..c396d4988 100644 --- a/ietf/meeting/views.py +++ b/ietf/meeting/views.py @@ -12,6 +12,7 @@ import debug # pyflakes:ignore from django import forms from django.shortcuts import render_to_response, redirect from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, Http404 +from django.contrib import messages from django.core.urlresolvers import reverse from django.db.models import Q from django.template import RequestContext @@ -88,8 +89,11 @@ def get_user_agent(request): user_agent = "" return user_agent +def ascii_alphanumeric(string): + return re.match(r'^[a-zA-Z0-9]*$', string) + class SaveAsForm(forms.Form): - savename = forms.CharField(max_length=100) + savename = forms.CharField(max_length=16) @role_required('Area Director','Secretariat') def agenda_create(request, num=None, owner=None, name=None): @@ -99,22 +103,30 @@ def agenda_create(request, num=None, owner=None, name=None): if schedule is None: # here we have to return some ajax to display an error. - raise Http404("No meeting information for meeting %s owner %s schedule %s available" % (num, owner, name)) + messages.error("Error: No meeting information for meeting %s owner %s schedule %s available" % (num, owner, name)) + return redirect(edit_agenda, num=num, owner=owner, name=name) # authorization was enforced by the @group_require decorator above. saveasform = SaveAsForm(request.POST) if not saveasform.is_valid(): - return HttpResponse(status=404) + messages.info(request, "This name is not valid. Please choose another one.") + return redirect(edit_agenda, num=num, owner=owner, name=name) savedname = saveasform.cleaned_data['savename'] + if not ascii_alphanumeric(savedname): + messages.info(request, "This name contains illegal characters. Please choose another one.") + return redirect(edit_agenda, num=num, owner=owner, name=name) + # create the new schedule, and copy the scheduledsessions try: sched = meeting.schedule_set.get(name=savedname, owner=request.user.person) if sched: - # XXX needs to record a session error and redirect to where? return redirect(edit_agenda, meeting.number, sched.name) + else: + messages.info(request, "Agenda creation failed. Please try again.") + return redirect(edit_agenda, num=num, owner=owner, name=name) except Schedule.DoesNotExist: pass