5
These are the functional tests for intervention security.
7
First we need to set up the school.
9
>>> from schooltool.app.browser.ftests import setup
10
>>> setup.setUpBasicSchool()
12
We'll create a princpal, a guidance counselor, two teachers and three students.
13
The principal will not teach or advise any student, but by virtue of being
14
in the administrators group, will be able to do everything for all student
15
data. The counselor doesn't teach at all but advises two of the three students.
16
This will give him the ability to create and edit data for those two students.
17
The two teachers will have a combination between teaching some of the students
18
and advising some. The corner cases will come from the various combinations.
20
>>> from schooltool.intervention.browser import ftests
21
>>> ftests.addPerson('Principal', 'Principal', 'principal', 'pwd',
22
... groups=['administrators'])
23
>>> ftests.addPerson('Counselor', 'Counselor', 'counselor', 'pwd')
24
>>> ftests.addPerson('Teacher1', 'Teacher1', 'teacher1', 'pwd')
25
>>> ftests.addPerson('Teacher2', 'Teacher2', 'teacher2', 'pwd')
26
>>> ftests.addPerson('Student1', 'Student1', 'student1', 'pwd')
27
>>> ftests.addPerson('Student2', 'Student2', 'student2', 'pwd')
28
>>> ftests.addPerson('Student3', 'Student3', 'student3', 'pwd')
30
We'll create sessions for each user.
32
>>> principal = setup.logIn('principal', 'pwd')
33
>>> counselor = setup.logIn('counselor', 'pwd')
34
>>> teacher1 = setup.logIn('teacher1', 'pwd')
35
>>> teacher2 = setup.logIn('teacher2', 'pwd')
36
>>> student1 = setup.logIn('student1', 'pwd')
37
>>> student2 = setup.logIn('student2', 'pwd')
38
>>> student3 = setup.logIn('student3', 'pwd')
40
All tests will use the test_access() method to test which users are allowed
43
>>> user_list = [principal, counselor, teacher1, teacher2, student1,
44
... student2, student3]
45
>>> from zope.publisher.interfaces import NotFound
46
>>> from zope.security.interfaces import Unauthorized
47
>>> def test_access(url, allowed_list):
48
... for user in user_list:
49
... if user in allowed_list:
52
... except Unauthorized:
53
... raise Exception('%s could not access %s' % (
54
... user.username, url))
56
... raise Exception('%s could not access %s' % (
57
... user.username, url))
61
... raise Exception('%s should not be able to access %s' % (
62
... user.username, url))
63
... except Unauthorized:
68
We need to add the advisors to each student.
70
>>> ftests.addAdvisors('Student1', ['counselor', 'teacher1', 'teacher2'])
71
>>> ftests.addAdvisors('Student2', ['counselor'])
72
>>> ftests.addAdvisors('Student3', ['teacher1', 'teacher2'])
74
Next we'll create some sections, setting up various combinations between
75
teachers and students.
77
>>> ftests.addCourseSectionMembers('course1', 'section1', ['Teacher1'],
78
... ['Student1', 'Student2'])
79
>>> ftests.addCourseSectionMembers('course2', 'section2', ['Teacher2'],
82
We need to visit the student intervention centers using the traversal adapter
83
to auto-vivify the InterventionStudent objects.
85
>>> for student in ['Student1', 'Student2', 'Student3']:
86
... principal.getLink('Manage').click()
87
... principal.getLink('Persons').click()
88
... principal.getLink(student).click()
89
... principal.getLink('Intervention Center').click()
91
Now we can create variables with urls for the student intervention center as
92
well as add message and goals.
94
>>> schoolyear_url = 'http://localhost/schooltool.interventions/2005-2006'
95
>>> student1_url = schoolyear_url + '/student1'
96
>>> student2_url = schoolyear_url + '/student2'
97
>>> student3_url = schoolyear_url + '/student3'
98
>>> add_msg_student1 = student1_url + '/messages/+/addMessage.html'
99
>>> add_msg_student2 = student2_url + '/messages/+/addMessage.html'
100
>>> add_msg_student3 = student3_url + '/messages/+/addMessage.html'
101
>>> add_goal_student1 = student1_url + '/goals/+/addGoal.html'
102
>>> add_goal_student2 = student2_url + '/goals/+/addGoal.html'
103
>>> add_goal_student3 = student3_url + '/goals/+/addGoal.html'
105
>>> trv_student1 = 'http://localhost/persons/student1/schoolyears/2005-2006'
106
>>> trv_student2 = 'http://localhost/persons/student2/schoolyears/2005-2006'
107
>>> trv_student3 = 'http://localhost/persons/student3/schoolyears/2005-2006'
108
>>> student1_messages = trv_student1 + '/messages'
109
>>> student2_messages = trv_student2 + '/messages'
110
>>> student3_messages = trv_student3 + '/messages'
111
>>> student1_goals = trv_student1 + '/goals'
112
>>> student2_goals = trv_student2 + '/goals'
113
>>> student3_goals = trv_student3 + '/goals'
115
We'll test viewing student1's data as well as adding messages and goals.
116
Since all staff either teach or advise student1, or they are an administrator,
117
they all can access the student data. The students may not.
119
>>> all_staff = [principal, counselor, teacher1, teacher2]
120
>>> test_access(student1_url, all_staff)
121
>>> test_access(add_msg_student1, all_staff)
122
>>> test_access(add_goal_student1, all_staff)
124
We'll test viewing student2's data as well as adding messages and goals.
125
Since teacher2 does not either teach or advise student2, he won't have access.
127
>>> test_access(student2_url, [principal, counselor, teacher1])
128
>>> test_access(add_msg_student2, [principal, counselor, teacher1])
129
>>> test_access(add_goal_student2, [principal, counselor, teacher1])
131
We'll test viewing student3's data as well as adding messages and goals.
132
Since the counselor does not teach or advise student3, he won't have access.
134
>>> test_access(student3_url, [principal, teacher1, teacher2])
135
>>> test_access(add_msg_student3, [principal, teacher1, teacher2])
136
>>> test_access(add_goal_student3, [principal, teacher1, teacher2])
138
The first message and goal we'll add for student1 will be for the student only.
139
The same people who are allowed to add messages or goals will be able to view
140
and edit them. Additionally, the student, by virtue of being on the persons
141
responsible list, will be able to view the message and goal, but not edit
144
>>> ftests.addMessage(principal, add_msg_student1, ['student1'])
146
>>> ftests.addEditGoal(principal, add_goal_student1, ['student1'])
149
>>> message_url = student1_messages + '/1'
150
>>> goal_url = student1_goals + '/1'
151
>>> goal_edit = goal_url + '/editGoal.html'
153
>>> test_access(message_url, all_staff + [student1])
154
>>> test_access(goal_url, all_staff + [student1])
155
>>> test_access(goal_edit, all_staff)
157
We'll have the principal edit the goal to remove student1 from the persons
158
responsible list. Then we'll test that student1 can no longer access the goal.
160
>>> ftests.addEditGoal(principal, goal_edit, ['teacher1'])
161
>>> test_access(goal_url, all_staff)
162
>>> test_access(goal_edit, all_staff)
164
The second message and goal we'll add for student1 will be for the counselor.
165
The same people who are allowed to add messages or goals will be able to view
166
and edit them. This time, the student, not being on the persons responsible
167
list, will not be able to view the message and goal, nor edit the goal.
169
>>> ftests.addMessage(principal, add_msg_student1, ['counselor'])
171
>>> ftests.addEditGoal(principal, add_goal_student1, ['counselor'])
174
>>> message_url = student1_messages + '/2'
175
>>> goal_url = student1_goals + '/2'
176
>>> goal_edit = goal_url + '/editGoal.html'
178
>>> test_access(message_url, all_staff)
179
>>> test_access(goal_url, all_staff)
180
>>> test_access(goal_edit, all_staff)
182
The first message and goal we'll add for student2 will be for the counselor.
183
The same people who are allowed to add messages or goals will be able to view
184
and edit them. That means teacher2 will not have access becuase he is not
185
teacher or advisor and is not on the persons responsible list.
187
>>> ftests.addMessage(principal, add_msg_student2, ['counselor'])
189
>>> ftests.addEditGoal(principal, add_goal_student2, ['counselor'])
192
>>> message_url = student2_messages + '/1'
193
>>> goal_url = student2_goals + '/1'
194
>>> goal_edit = goal_url + '/editGoal.html'
196
>>> test_access(message_url, [principal, counselor, teacher1])
197
>>> test_access(goal_url, [principal, counselor, teacher1])
198
>>> test_access(goal_edit, [principal, counselor, teacher1])
200
Now we'll add teacher2 as an advisor of student2, create a message and goal
201
for teacher2, and then remove teacher2 as the advisor of student2. This will
202
allow us to test the access granted to teacher2 that comes from being on the
203
list of persons responsible even if he is not a teacher, advisor or
206
>>> ftests.addAdvisors('Student2', ['teacher2'])
207
>>> ftests.addMessage(principal, add_msg_student2, ['teacher2'])
209
>>> ftests.addEditGoal(principal, add_goal_student2, ['teacher2'])
211
>>> ftests.removeAdvisors('Student2', ['teacher2'])
213
>>> message_url = student2_messages + '/2'
214
>>> goal_url = student2_goals + '/2'
215
>>> goal_edit = goal_url + '/editGoal.html'
217
>>> test_access(message_url, all_staff)
218
>>> test_access(goal_url, all_staff)
219
>>> test_access(goal_edit, all_staff)
221
We'll have the principal edit the goal to remove teacher2 from the persons
222
responsible list. Then we'll test that teacher2 can no longer view or edit
225
>>> ftests.addEditGoal(principal, goal_edit, ['teacher1'])
226
>>> test_access(goal_url, [principal, counselor, teacher1])
227
>>> test_access(goal_edit, [principal, counselor, teacher1])
229
The first message and goal we'll add for student3 will be for teacher1.
230
The same people who are allowed to add messages or goals will be able to view
231
and edit them. That means the counselor will not have access becuase he is not
232
a teacher or advisor of student3 and is not on the persons responsible list.
234
>>> ftests.addMessage(principal, add_msg_student3, ['teacher1'])
236
>>> ftests.addEditGoal(principal, add_goal_student3, ['teacher1'])
239
>>> message_url = student3_messages + '/1'
240
>>> goal_url = student3_goals + '/1'
241
>>> goal_edit = goal_url + '/editGoal.html'
243
>>> test_access(message_url, [principal, teacher1, teacher2])
244
>>> test_access(goal_url, [principal, teacher1, teacher2])
245
>>> test_access(goal_edit, [principal, teacher1, teacher2])
247
Now we'll add counselor as an advisor of student3, create a message and goal
248
for counselor, and then remove counselor as the advisor of student3. This will
249
allow us to test the access granted to counselor that comes from being on the
250
list of persons responsible even if he is not a teacher, advisor or
253
>>> ftests.addAdvisors('Student3', ['counselor'])
254
>>> ftests.addMessage(principal, add_msg_student3, ['counselor'])
256
>>> ftests.addEditGoal(principal, add_goal_student3, ['counselor'])
258
>>> ftests.removeAdvisors('Student3', ['counselor'])
260
>>> message_url = student3_messages + '/2'
261
>>> goal_url = student3_goals + '/2'
262
>>> goal_edit = goal_url + '/editGoal.html'
264
Now we'll test that counselor has the same acesss as that of the other staff,
265
all of whom are either the teacher, advisor or administrator of the student.
267
>>> test_access(message_url, all_staff)
268
>>> test_access(goal_url, all_staff)
269
>>> test_access(goal_edit, all_staff)
271
We'll have the principal edit the goal to remove counselor from the persons
272
responsible list. Then we'll test that counselor can no longer view or edit
275
>>> ftests.addEditGoal(principal, goal_edit, ['teacher1'])
276
>>> test_access(goal_url, [principal, teacher1, teacher2])
277
>>> test_access(goal_edit, [principal, teacher1, teacher2])
280
Intervention dashboard security
281
-------------------------------
283
It's one thing to protect the student intervention data from the wrong user's
284
eyes, but there's also an intervention dashboard view that exposes information
285
about student interventions. We will make sure that users are only allowed to
286
see their own dashboard.
288
>>> users_url = 'http://localhost/persons'
289
>>> principal_inbox = users_url + '/principal/intervention_tab'
290
>>> principal_search = principal_inbox + '/search_students.html'
291
>>> counselor_inbox = users_url + '/counselor/intervention_tab'
292
>>> counselor_search = counselor_inbox + '/search_students.html'
293
>>> teacher1_inbox = users_url + '/teacher1/intervention_tab'
294
>>> teacher1_search = teacher1_inbox + '/search_students.html'
295
>>> teacher2_inbox = users_url + '/teacher2/intervention_tab'
296
>>> teacher2_search = teacher2_inbox + '/search_students.html'
297
>>> student1_inbox = users_url + '/student1/intervention_tab'
298
>>> student1_search = student1_inbox + '/search_students.html'
299
>>> student2_inbox = users_url + '/student2/intervention_tab'
300
>>> student2_search = student2_inbox + '/search_students.html'
301
>>> student3_inbox = users_url + '/student3/intervention_tab'
302
>>> student3_search = student3_inbox + '/search_students.html'
304
>>> test_access(principal_inbox, [principal])
305
>>> test_access(principal_search, [principal])
306
>>> test_access(counselor_inbox, [counselor])
307
>>> test_access(counselor_search, [counselor])
308
>>> test_access(teacher1_inbox, [teacher1])
309
>>> test_access(teacher1_search, [teacher1])
310
>>> test_access(teacher2_inbox, [teacher2])
311
>>> test_access(teacher2_search, [teacher2])
312
>>> test_access(student1_inbox, [student1])
313
>>> test_access(student1_search, [student1])
314
>>> test_access(student2_inbox, [student2])
315
>>> test_access(student2_search, [student2])
316
>>> test_access(student3_inbox, [student3])
317
>>> test_access(student3_search, [student3])