Skip to content

Commit f4a72ff

Browse files
committed
cleaned up permissions on dajaxice calls, ported and expanded more tests, refactored sendEmail, made a secr filter more robust
- Legacy-Id: 7457
1 parent f292af9 commit f4a72ff

6 files changed

Lines changed: 121 additions & 19 deletions

File tree

ietf/meeting/ajax.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,12 @@ def readonly(request, meeting_num, schedule_id):
5353
'owner_href': request.build_absolute_uri(schedule.owner.json_url()),
5454
'read_only': read_only})
5555

56-
@role_required('Area Director','Secretariat')
5756
@dajaxice_register
5857
def update_timeslot_pinned(request, schedule_id, scheduledsession_id, pinned=False):
58+
59+
if not has_role(request.user,('Area Director','Secretariat')):
60+
return json.dumps({'error':'no permission'})
61+
5962
schedule = get_object_or_404(Schedule, pk = int(schedule_id))
6063
meeting = schedule.meeting
6164
cansee,canedit = agenda_permissions(meeting, schedule, request.user)
@@ -75,7 +78,6 @@ def update_timeslot_pinned(request, schedule_id, scheduledsession_id, pinned=Fal
7578

7679
return json.dumps({'message':'valid'})
7780

78-
@role_required('Secretariat')
7981
@dajaxice_register
8082
def update_timeslot_purpose(request,
8183
meeting_num,
@@ -85,6 +87,9 @@ def update_timeslot_purpose(request,
8587
duration= None,
8688
time = None):
8789

90+
if not has_role(request.user,'Secretariat'):
91+
return json.dumps({'error':'no permission'})
92+
8893
meeting = get_meeting(meeting_num)
8994
ts_id = int(timeslot_id)
9095
time_str = time

ietf/meeting/models.py

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,20 @@ def vtimezone(self):
206206
return ''
207207

208208
def set_official_agenda(self, agenda):
209+
# send_notification should be refactored into Session
210+
from ietf.secr.meetings.views import send_notification
209211
if self.agenda != agenda:
210212
self.agenda = agenda
211213
self.save()
212214
if self.agenda is not None:
213-
self.agenda.sendEmail()
215+
for ss in self.agenda.scheduledsession_set.all():
216+
session = ss.session
217+
if session.status.slug == "schedw":
218+
session.status_id = "sched"
219+
session.scheduled = datetime.datetime.now()
220+
session.save()
221+
# refactoring send_notification will obviate this odd hoop-jump
222+
send_notification(None, Session.objects.filter(id=session.id))
214223

215224
class Meta:
216225
ordering = ["-date", ]
@@ -604,18 +613,6 @@ def delete_schedule(self):
604613
self.scheduledsession_set.all().delete()
605614
self.delete()
606615

607-
# send email to every session requester whose session is now scheduled.
608-
# mark the sessions as now state scheduled, rather than waiting.
609-
def sendEmail(self):
610-
for ss in self.scheduledsession_set.all():
611-
session = ss.session
612-
if session.status.slug == "schedw":
613-
session.status_id = "sched"
614-
session.scheduled = datetime.datetime.now()
615-
session.save()
616-
from ietf.secr.meetings.views import send_notification
617-
send_notification(None, Session.objects.filter(id=session.id))
618-
619616
# to be renamed ScheduleTimeslotSessionAssignments (stsa)
620617
class ScheduledSession(models.Model):
621618
"""

ietf/meeting/test_data.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def make_meeting_test_data():
2323
time=datetime.datetime.combine(datetime.date.today(), datetime.time(9, 30)))
2424
mars_session = Session.objects.create(meeting=meeting, group=Group.objects.get(acronym="mars"),
2525
attendees=10, requested_by=system_person,
26-
requested_duration=20, status_id="sched",
26+
requested_duration=20, status_id="schedw",
2727
scheduled=datetime.datetime.now())
2828
ScheduledSession.objects.create(timeslot=slot, session=mars_session, schedule=schedule)
2929

@@ -32,7 +32,7 @@ def make_meeting_test_data():
3232
time=datetime.datetime.combine(datetime.date.today(), datetime.time(10, 30)))
3333
ames_session = Session.objects.create(meeting=meeting, group=Group.objects.get(acronym="ames"),
3434
attendees=10, requested_by=system_person,
35-
requested_duration=20, status_id="sched",
35+
requested_duration=20, status_id="schedw",
3636
scheduled=datetime.datetime.now())
3737
ScheduledSession.objects.create(timeslot=slot, session=ames_session, schedule=schedule)
3838

ietf/meeting/tests_api.py

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from ietf.meeting.models import Schedule, TimeSlot, Session, ScheduledSession, Meeting, Constraint
1111
from ietf.meeting.helpers import get_meeting
1212
from ietf.meeting.test_data import make_meeting_test_data
13+
from ietf.utils.mail import outbox
1314

1415

1516
class ApiTests(TestCase):
@@ -173,16 +174,34 @@ def test_person_json(self):
173174

174175
url = urlreverse("ietf.person.ajax.person_json", kwargs=dict(personid=person.pk))
175176
r = self.client.get(url)
177+
self.assertEqual(r.status_code, 200)
176178
info = json.loads(r.content)
177179
self.assertEqual(info["name"], person.name)
178180

181+
def test_sessions_json(self):
182+
meeting = make_meeting_test_data()
183+
184+
url = urlreverse("ietf.meeting.ajax.sessions_json",kwargs=dict(num=meeting.number))
185+
r = self.client.get(url)
186+
self.assertEqual(r.status_code, 200)
187+
info = json.loads(r.content)
188+
self.assertEqual(set([x['short_name'] for x in info]),set(['mars','ames']))
189+
190+
schedule = Schedule.objects.filter(meeting=meeting).first()
191+
url = urlreverse("ietf.meeting.ajax.scheduledsessions_json",kwargs=dict(num=meeting.number,name=schedule.name))
192+
self.assertEqual(r.status_code, 200)
193+
info = json.loads(r.content)
194+
self.assertEqual(set([x['short_name'] for x in info]),set(['mars','ames']))
195+
196+
179197
def test_slot_json(self):
180198
meeting = make_meeting_test_data()
181199
slot = meeting.timeslot_set.all()[0]
182200

183201
url = urlreverse("ietf.meeting.ajax.timeslot_sloturl",
184202
kwargs=dict(num=meeting.number, slotid=slot.pk))
185203
r = self.client.get(url)
204+
self.assertEqual(r.status_code, 200)
186205
info = json.loads(r.content)
187206
self.assertEqual(info["timeslot_id"], slot.pk)
188207

@@ -200,15 +219,18 @@ def test_create_new_slot(self):
200219
}
201220

202221
# unauthorized post
222+
prior_slotcount = meeting.timeslot_set.count()
203223
self.client.login(remote_user="ad")
204224
r = self.client.post(url, post_data)
205225
self.assertEqual(r.status_code, 403)
226+
self.assertEqual(meeting.timeslot_set.count(),prior_slotcount)
206227

207-
# create room
228+
# create slot
208229
self.client.login(remote_user="secretary")
209230
r = self.client.post(url, post_data)
210231
self.assertEqual(r.status_code, 302)
211232
self.assertTrue(meeting.timeslot_set.filter(time=slot_time))
233+
self.assertEqual(meeting.timeslot_set.count(),prior_slotcount+1)
212234

213235
def test_delete_slot(self):
214236
meeting = make_meeting_test_data()
@@ -343,9 +365,19 @@ def test_set_meeting_agenda(self):
343365
schedule.public = True
344366
schedule.save()
345367

368+
prior_length= len(outbox)
369+
r = self.client.post(url, post_data)
370+
self.assertEqual(r.status_code, 200)
371+
self.assertEqual(Meeting.objects.get(pk=meeting.pk).agenda, schedule)
372+
self.assertEqual(len(outbox),prior_length+2)
373+
374+
# Post it again, and make sure mail isn't resent
375+
376+
prior_length= len(outbox)
346377
r = self.client.post(url, post_data)
347378
self.assertEqual(r.status_code, 200)
348379
self.assertEqual(Meeting.objects.get(pk=meeting.pk).agenda, schedule)
380+
self.assertEqual(len(outbox),prior_length)
349381

350382
def test_read_only(self):
351383
meeting = make_meeting_test_data()
@@ -404,3 +436,60 @@ def test_update_timeslot_pinned(self):
404436
r = self.client.post(url, post_data)
405437
self.assertEqual(r.status_code, 200)
406438
self.assertTrue(ScheduledSession.objects.get(pk=scheduled.pk).pinned)
439+
440+
class UnusedButExposedApiTests(TestCase):
441+
442+
def test_manipulate_timeslot_via_dajaxice(self):
443+
meeting = make_meeting_test_data()
444+
slot_time = datetime.date.today()
445+
446+
url = '/dajaxice/ietf.meeting.update_timeslot_purpose/'
447+
448+
create_post_data = {
449+
'argv' : json.dumps({
450+
"meeting_num" : meeting.number,
451+
"timeslot_id" : 0,
452+
"purpose" : "plenary",
453+
"room_id" : meeting.room_set.first().id,
454+
"time" : slot_time.strftime("%Y-%m-%d %H:%M:%S"),
455+
"duration" : 3600
456+
})}
457+
458+
prior_timeslot_count = meeting.timeslot_set.count()
459+
# Create as nobody should fail
460+
r = self.client.post(url, create_post_data)
461+
self.assertEqual(r.status_code, 200)
462+
info = json.loads(r.content)
463+
self.assertTrue('error' in info and info['error']=='no permission')
464+
self.assertEqual(meeting.timeslot_set.count(),prior_timeslot_count)
465+
466+
# Successful create
467+
self.client.login(remote_user="secretary")
468+
r = self.client.post(url, create_post_data)
469+
self.assertEqual(r.status_code, 200)
470+
info = json.loads(r.content)
471+
self.assertFalse('error' in info)
472+
self.assertTrue('roomtype' in info)
473+
self.assertEqual(info['roomtype'],'plenary')
474+
self.assertEqual(meeting.timeslot_set.count(),prior_timeslot_count+1)
475+
476+
modify_post_data = {
477+
'argv' : json.dumps({
478+
"meeting_num" : meeting.number,
479+
"timeslot_id" : meeting.timeslot_set.get(time=slot_time).id,
480+
"purpose" : "session"
481+
})}
482+
483+
# Fail as non-secretariat
484+
self.client.login(remote_user="plain")
485+
r = self.client.post(url, modify_post_data)
486+
self.assertEqual(r.status_code, 200)
487+
info = json.loads(r.content)
488+
self.assertTrue('error' in info and info['error']=='no permission')
489+
self.assertEqual(meeting.timeslot_set.get(time=slot_time).type.name,'Plenary')
490+
491+
# Successful change of purpose
492+
self.client.login(remote_user="secretary")
493+
r = self.client.post(url, modify_post_data)
494+
self.assertEqual(r.status_code, 200)
495+
self.assertEqual(meeting.timeslot_set.get(time=slot_time).type.name,'Session')

ietf/secr/meetings/views.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,13 @@ def add(request):
273273
if form.is_valid():
274274
meeting = form.save()
275275

276+
schedule = Schedule.objects.create(meeting = meeting,
277+
name = 'Empty Schedule',
278+
owner = Person.objects.get(name='(System)'),
279+
visible = True,
280+
public = True)
281+
meeting.set_official_agenda(schedule)
282+
276283
#Create Physical new meeting directory and subdirectories
277284
make_directories(meeting)
278285

ietf/secr/proceedings/templatetags/ams_filters.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ def display_duration(value):
3131
'5400':'1.5 Hours',
3232
'7200':'2 Hours',
3333
'9000':'2.5 Hours'}
34-
return map[value]
34+
if value in map:
35+
return map[value]
36+
else:
37+
x=int(value)
38+
return "%d Hours %d Minutes %d Seconds"%(x//3600,(x%3600)//60,x%60)
3539

3640
@register.filter
3741
def get_published_date(doc):

0 commit comments

Comments
 (0)