~ubuntu-branches/ubuntu/quantal/schooltool.intervention/quantal-201209201712

« back to all changes in this revision

Viewing changes to src/schooltool/intervention/browser/security.txt

  • Committer: Bazaar Package Importer
  • Author(s): Gediminas Paulauskas
  • Date: 2011-02-24 17:10:33 UTC
  • Revision ID: james.westby@ubuntu.com-20110224171033-8wflfqxxe3zld6bf
Tags: upstream-0.4.2
ImportĀ upstreamĀ versionĀ 0.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
=====================
 
2
Intervention Security
 
3
=====================
 
4
 
 
5
These are the functional tests for intervention security.
 
6
 
 
7
First we need to set up the school.
 
8
 
 
9
    >>> from schooltool.app.browser.ftests import setup
 
10
    >>> setup.setUpBasicSchool()
 
11
 
 
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.
 
19
 
 
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')
 
29
 
 
30
We'll create sessions for each user.
 
31
 
 
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')
 
39
 
 
40
All tests will use the test_access() method to test which users are allowed
 
41
to visit which urls.
 
42
 
 
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:
 
50
    ...             try:
 
51
    ...                 user.open(url)
 
52
    ...             except Unauthorized:
 
53
    ...                 raise Exception('%s could not access %s' % (
 
54
    ...                     user.username, url))
 
55
    ...             except NotFound:
 
56
    ...                 raise Exception('%s could not access %s' % (
 
57
    ...                     user.username, url))
 
58
    ...         else:
 
59
    ...             try:
 
60
    ...                 user.open(url)
 
61
    ...                 raise Exception('%s should not be able to access %s' % (
 
62
    ...                     user.username, url))
 
63
    ...             except Unauthorized:
 
64
    ...                 pass
 
65
    ...             except NotFound:
 
66
    ...                 pass
 
67
 
 
68
We need to add the advisors to each student.
 
69
 
 
70
    >>> ftests.addAdvisors('Student1', ['counselor', 'teacher1', 'teacher2'])
 
71
    >>> ftests.addAdvisors('Student2', ['counselor'])
 
72
    >>> ftests.addAdvisors('Student3', ['teacher1', 'teacher2'])
 
73
 
 
74
Next we'll create some sections, setting up various combinations between
 
75
teachers and students.
 
76
 
 
77
    >>> ftests.addCourseSectionMembers('course1', 'section1', ['Teacher1'],
 
78
    ...     ['Student1', 'Student2'])
 
79
    >>> ftests.addCourseSectionMembers('course2', 'section2', ['Teacher2'],
 
80
    ...     ['Student3'])
 
81
 
 
82
We need to visit the student intervention centers using the traversal adapter
 
83
to auto-vivify the InterventionStudent objects.
 
84
 
 
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()
 
90
 
 
91
Now we can create variables with urls for the student intervention center as
 
92
well as add message and goals.
 
93
 
 
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'
 
104
 
 
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'
 
114
 
 
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.
 
118
 
 
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)
 
123
 
 
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.
 
126
 
 
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])
 
130
 
 
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.
 
133
 
 
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])
 
137
 
 
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
 
142
the goal.
 
143
 
 
144
    >>> ftests.addMessage(principal, add_msg_student1, ['student1'])
 
145
    From: ...
 
146
    >>> ftests.addEditGoal(principal, add_goal_student1, ['student1'])
 
147
    From: ...
 
148
 
 
149
    >>> message_url = student1_messages + '/1'
 
150
    >>> goal_url = student1_goals + '/1'
 
151
    >>> goal_edit = goal_url + '/editGoal.html'
 
152
 
 
153
    >>> test_access(message_url, all_staff + [student1])
 
154
    >>> test_access(goal_url, all_staff + [student1])
 
155
    >>> test_access(goal_edit, all_staff)
 
156
 
 
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.
 
159
 
 
160
    >>> ftests.addEditGoal(principal, goal_edit, ['teacher1'])
 
161
    >>> test_access(goal_url, all_staff)
 
162
    >>> test_access(goal_edit, all_staff)
 
163
 
 
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.
 
168
 
 
169
    >>> ftests.addMessage(principal, add_msg_student1, ['counselor'])
 
170
    From: ...
 
171
    >>> ftests.addEditGoal(principal, add_goal_student1, ['counselor'])
 
172
    From: ...
 
173
 
 
174
    >>> message_url = student1_messages + '/2'
 
175
    >>> goal_url = student1_goals + '/2'
 
176
    >>> goal_edit = goal_url + '/editGoal.html'
 
177
 
 
178
    >>> test_access(message_url, all_staff)
 
179
    >>> test_access(goal_url, all_staff)
 
180
    >>> test_access(goal_edit, all_staff)
 
181
 
 
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.
 
186
 
 
187
    >>> ftests.addMessage(principal, add_msg_student2, ['counselor'])
 
188
    From: ...
 
189
    >>> ftests.addEditGoal(principal, add_goal_student2, ['counselor'])
 
190
    From: ...
 
191
 
 
192
    >>> message_url = student2_messages + '/1'
 
193
    >>> goal_url = student2_goals + '/1'
 
194
    >>> goal_edit = goal_url + '/editGoal.html'
 
195
 
 
196
    >>> test_access(message_url, [principal, counselor, teacher1])
 
197
    >>> test_access(goal_url, [principal, counselor, teacher1])
 
198
    >>> test_access(goal_edit, [principal, counselor, teacher1])
 
199
 
 
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
 
204
administrator.
 
205
 
 
206
    >>> ftests.addAdvisors('Student2', ['teacher2'])
 
207
    >>> ftests.addMessage(principal, add_msg_student2, ['teacher2'])
 
208
    From: ...
 
209
    >>> ftests.addEditGoal(principal, add_goal_student2, ['teacher2'])
 
210
    From: ...
 
211
    >>> ftests.removeAdvisors('Student2', ['teacher2'])
 
212
 
 
213
    >>> message_url = student2_messages + '/2'
 
214
    >>> goal_url = student2_goals + '/2'
 
215
    >>> goal_edit = goal_url + '/editGoal.html'
 
216
 
 
217
    >>> test_access(message_url, all_staff)
 
218
    >>> test_access(goal_url, all_staff)
 
219
    >>> test_access(goal_edit, all_staff)
 
220
 
 
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
 
223
the goal.
 
224
 
 
225
    >>> ftests.addEditGoal(principal, goal_edit, ['teacher1'])
 
226
    >>> test_access(goal_url, [principal, counselor, teacher1])
 
227
    >>> test_access(goal_edit, [principal, counselor, teacher1])
 
228
 
 
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.
 
233
 
 
234
    >>> ftests.addMessage(principal, add_msg_student3, ['teacher1'])
 
235
    From: ...
 
236
    >>> ftests.addEditGoal(principal, add_goal_student3, ['teacher1'])
 
237
    From: ...
 
238
 
 
239
    >>> message_url = student3_messages + '/1'
 
240
    >>> goal_url = student3_goals + '/1'
 
241
    >>> goal_edit = goal_url + '/editGoal.html'
 
242
 
 
243
    >>> test_access(message_url, [principal, teacher1, teacher2])
 
244
    >>> test_access(goal_url, [principal, teacher1, teacher2])
 
245
    >>> test_access(goal_edit, [principal, teacher1, teacher2])
 
246
 
 
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
 
251
administrator.
 
252
 
 
253
    >>> ftests.addAdvisors('Student3', ['counselor'])
 
254
    >>> ftests.addMessage(principal, add_msg_student3, ['counselor'])
 
255
    From: ...
 
256
    >>> ftests.addEditGoal(principal, add_goal_student3, ['counselor'])
 
257
    From: ...
 
258
    >>> ftests.removeAdvisors('Student3', ['counselor'])
 
259
 
 
260
    >>> message_url = student3_messages + '/2'
 
261
    >>> goal_url = student3_goals + '/2'
 
262
    >>> goal_edit = goal_url + '/editGoal.html'
 
263
 
 
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.
 
266
 
 
267
    >>> test_access(message_url, all_staff)
 
268
    >>> test_access(goal_url, all_staff)
 
269
    >>> test_access(goal_edit, all_staff)
 
270
 
 
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
 
273
the goal.
 
274
 
 
275
    >>> ftests.addEditGoal(principal, goal_edit, ['teacher1'])
 
276
    >>> test_access(goal_url, [principal, teacher1, teacher2])
 
277
    >>> test_access(goal_edit, [principal, teacher1, teacher2])
 
278
 
 
279
 
 
280
Intervention dashboard security
 
281
-------------------------------
 
282
 
 
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.
 
287
 
 
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'
 
303
 
 
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])
 
318