source: main/waeup.kofa/trunk/src/waeup/kofa/permissions.py @ 12841

Last change on this file since 12841 was 12835, checked in by Henrik Bettermann, 10 years ago

Add some docstrings.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 21.4 KB
Line 
1## $Id: permissions.py 12835 2015-03-31 14:50:49Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18import grok
19from zope.component import getUtilitiesFor
20from zope.interface import Interface
21from zope.securitypolicy.interfaces import IRole, IPrincipalRoleMap
22from waeup.kofa.interfaces import ILocalRolesAssignable
23
24class Public(grok.Permission):
25    """The everyone-can-do-this-permission is being applied to views/pages
26    that are used by everyone.
27    """
28    grok.name('waeup.Public')
29
30class Anonymous(grok.Permission):
31    """The waeup.Anonymous permission is applied to
32    views/pages which are dedicated to anonymous users only. Logged-in users
33    can't access these views.
34    """
35    grok.name('waeup.Anonymous')
36
37class Authenticated(grok.Permission):
38    """The waeup.Authenticated permission is applied to pages
39    which can only be used by logged-in users and not by anonymous users.
40    """
41    grok.name('waeup.Authenticated')
42
43class ViewAcademics(grok.Permission):
44    """The waeup.viewAcademics permission is applied to all
45    views of the Academic Section. Users with this permission can view but
46    not edit content in the Academic Section.
47    """
48    grok.name('waeup.viewAcademics')
49
50class ManageAcademics(grok.Permission):
51    """The waeup.manageAcademics permission is applied to all edit
52    pages in the Academic Section. Users who have this permission
53    can change/edit context objects.
54    """
55    grok.name('waeup.manageAcademics')
56
57class ManagePortal(grok.Permission):
58    """The waeup.managePortal permission is used for very few pages
59    (e.g. the DatacenterSettings page) and is dedicated to portal managers.
60    It is furthermore used to control delete methods of container
61    pages in the Academic Section. The waeup.manageAcademics permission,
62    described above, does enable users to edit content but not to
63    remove sub-containers, like faculties, departments or certificates.
64    Users must have the waeup.managePorta permission too to remove
65    entire containers.
66    """
67    grok.name('waeup.managePortal')
68
69class ManageUsers(grok.Permission):
70    """The waeup.manageUsers permission is a real superuser permission
71    and therefore very 'dangerous'. It allows to add, remove or edit
72    user accounts. Editing a user account includes the option to assign
73    or remove roles. That means that a user with this permission can lock out
74    other users by either removing their account or by removing all
75    permsissions. Only the system administrator will be able to revert this.
76    """
77    grok.name('waeup.manageUsers')
78
79class ShowStudents(grok.Permission):
80    """Users with this permission can see the 'Students' tab and
81    search and browse all students. If they also have the waeup.exportData
82    permission they can export all student data too.
83
84    Bursary or Department Officers don't have the general waeup.exportData
85    permission (see Roles section) and are only allowed to export bursary
86    or payments overview data respectively.
87    """
88    grok.name('waeup.showStudents')
89
90class ClearAllStudents(grok.Permission):
91    """The waeup.clearAllStudents permission allows to clear all students
92    in a department.
93    """
94    grok.name('waeup.clearAllStudents')
95
96class EditScores(grok.Permission):
97    """The waeup.editScores permission allows to edit scores in course tickets.
98    """
99    grok.name('waeup.editScores')
100
101class EditUser(grok.Permission):
102    """The waeup.editUser permission is required for editing
103    single user accounts.
104    """
105    grok.name('waeup.editUser')
106
107class ManageDataCenter(grok.Permission):
108    """The waeup.manageDataCenter permission allows to access all pages
109    in the data center. It does not automatically allow to process data.
110    """
111    grok.name('waeup.manageDataCenter')
112
113class ImportData(grok.Permission):
114    """The waeup.importData permission allows to import any kind of portal
115    data.
116    """
117    grok.name('waeup.importData')
118
119class ExportData(grok.Permission):
120    """The waeup.exportData permission allows to export any kind of portal
121    data.
122    """
123    grok.name('waeup.exportData')
124
125class ExportPaymentsOverview(grok.Permission):
126    grok.name('waeup.exportPaymentsOverview')
127
128class ExportBursaryData(grok.Permission):
129    grok.name('waeup.exportBursaryData')
130
131class ViewTranscript(grok.Permission):
132    grok.name('waeup.viewTranscript')
133
134class ManagePortalConfiguration(grok.Permission):
135    """The waeup.managePortalConfiguration permission allows to
136    edit global and sessional portal configuration data.
137    """
138    grok.name('waeup.managePortalConfiguration')
139
140class ManageACBatches(grok.Permission):
141    """The waeup.manageACBatches permission allows to view and
142    manage accesscodes.
143    """
144    grok.name('waeup.manageACBatches')
145
146class PutBiometricDataPermission(grok.Permission):
147    """This permission allows to upload/change biometric data.
148    """
149    grok.name('waeup.putBiometricData')
150
151class GetBiometricDataPermission(grok.Permission):
152    """This permission allows to read biometric data.
153    """
154    grok.name('waeup.getBiometricData')
155
156
157# Local Roles
158class ApplicationsManager(grok.Role):
159    grok.name('waeup.local.ApplicationsManager')
160    grok.title(u'Applications Manager')
161    grok.permissions('waeup.viewAcademics')
162
163class DepartmentManager(grok.Role):
164    grok.name('waeup.local.DepartmentManager')
165    grok.title(u'Department Manager')
166    grok.permissions('waeup.manageAcademics',
167                     'waeup.showStudents',
168                     'waeup.exportData')
169
170class DepartmentOfficer(grok.Role):
171    grok.name('waeup.local.DepartmentOfficer')
172    grok.title(u'Department Officer')
173    grok.permissions('waeup.showStudents',
174                     'waeup.viewAcademics',
175                     'waeup.exportPaymentsOverview')
176
177class ClearanceOfficer(grok.Role):
178    """The clearance officer role is meant for the
179    assignment of dynamic roles only.
180    """
181    grok.name('waeup.local.ClearanceOfficer')
182    grok.title(u'Clearance Officer')
183    grok.permissions('waeup.showStudents',
184                     'waeup.viewAcademics',
185                     'waeup.exportData',
186                     'waeup.clearAllStudents')
187
188class LocalStudentsManager(grok.Role):
189    """The local students manager role is meant for the
190    assignment of dynamic roles only.
191    """
192    grok.name('waeup.local.LocalStudentsManager')
193    grok.title(u'Students Manager')
194    grok.permissions('waeup.showStudents',
195                     'waeup.viewAcademics',
196                     'waeup.exportData')
197
198class LocalWorkflowManager(grok.Role):
199    """The local workflow manager role is meant for the
200    assignment of dynamic roles only.
201    """
202    grok.name('waeup.local.LocalWorkflowManager')
203    grok.title(u'Student Workflow Manager')
204    grok.permissions('waeup.showStudents',
205                     'waeup.viewAcademics',
206                     'waeup.exportData')
207
208class UGClearanceOfficer(grok.Role):
209    """The clearance officer role is meant for the
210    assignment of dynamic roles only.
211    """
212    grok.name('waeup.local.UGClearanceOfficer')
213    grok.title(u'UG Clearance Officer')
214    grok.permissions('waeup.showStudents',
215                     'waeup.viewAcademics',
216                     'waeup.exportData',
217                     'waeup.clearAllStudents')
218
219class PGClearanceOfficer(grok.Role):
220    """The clearance officer role is meant for the
221    assignment of dynamic roles only.
222    """
223    grok.name('waeup.local.PGClearanceOfficer')
224    grok.title(u'PG Clearance Officer')
225    grok.permissions('waeup.showStudents',
226                     'waeup.viewAcademics',
227                     'waeup.exportData',
228                     'waeup.clearAllStudents')
229
230class CourseAdviser100(grok.Role):
231    """The 100 level course adviser role is meant for the
232    assignment of dynamic roles only.
233    """
234    grok.name('waeup.local.CourseAdviser100')
235    grok.title(u'Course Adviser 100L')
236    grok.permissions('waeup.showStudents',
237                     'waeup.viewAcademics',
238                     'waeup.exportData')
239
240class CourseAdviser200(grok.Role):
241    """The course 200 level adviser role is meant for the
242    assignment of dynamic roles only.
243    """
244    grok.name('waeup.local.CourseAdviser200')
245    grok.title(u'Course Adviser 200L')
246    grok.permissions('waeup.showStudents',
247                     'waeup.viewAcademics',
248                     'waeup.exportData')
249
250class CourseAdviser300(grok.Role):
251    """The 300 level course adviser role is meant for the
252    assignment of dynamic roles only.
253    """
254    grok.name('waeup.local.CourseAdviser300')
255    grok.title(u'Course Adviser 300L')
256    grok.permissions('waeup.showStudents',
257                     'waeup.viewAcademics',
258                     'waeup.exportData')
259
260class CourseAdviser400(grok.Role):
261    """The 400 level course adviser role is meant for the
262    assignment of dynamic roles only.
263    """
264    grok.name('waeup.local.CourseAdviser400')
265    grok.title(u'Course Adviser 400L')
266    grok.permissions('waeup.showStudents',
267                     'waeup.viewAcademics',
268                     'waeup.exportData')
269
270class CourseAdviser500(grok.Role):
271    """The 500 level course adviser role is meant for the
272    assignment of dynamic roles only.
273    """
274    grok.name('waeup.local.CourseAdviser500')
275    grok.title(u'Course Adviser 500L')
276    grok.permissions('waeup.showStudents',
277                     'waeup.viewAcademics',
278                     'waeup.exportData')
279
280class CourseAdviser600(grok.Role):
281    """The 600 level course adviser role is meant for the
282    assignment of dynamic roles only.
283    """
284    grok.name('waeup.local.CourseAdviser600')
285    grok.title(u'Course Adviser 600L')
286    grok.permissions('waeup.showStudents',
287                     'waeup.viewAcademics',
288                     'waeup.exportData')
289
290class CourseAdviser700(grok.Role):
291    """The 700 level course adviser role is meant for the
292    assignment of dynamic roles only.
293    """
294    grok.name('waeup.local.CourseAdviser700')
295    grok.title(u'Course Adviser 700L')
296    grok.permissions('waeup.showStudents',
297                     'waeup.viewAcademics',
298                     'waeup.exportData')
299
300class CourseAdviser800(grok.Role):
301    """The 800 level course adviser role is meant for the
302    assignment of dynamic roles only.
303    """
304    grok.name('waeup.local.CourseAdviser800')
305    grok.title(u'Course Adviser 800L')
306    grok.permissions('waeup.showStudents',
307                     'waeup.viewAcademics',
308                     'waeup.exportData')
309
310class Lecturer(grok.Role):
311    """The lecturer role is meant for the
312    assignment of dynamic roles only.
313    """
314    grok.name('waeup.local.Lecturer')
315    grok.title(u'Lecturer')
316    grok.permissions('waeup.showStudents',
317                     'waeup.editScores',
318                     'waeup.viewAcademics',
319                     'waeup.exportData')
320
321class Owner(grok.Role):
322    grok.name('waeup.local.Owner')
323    grok.title(u'Owner')
324    grok.permissions('waeup.editUser')
325
326# Site Roles
327class AcademicsOfficer(grok.Role):
328    grok.name('waeup.AcademicsOfficer')
329    grok.title(u'Academics Officer (view only)')
330    grok.permissions('waeup.viewAcademics')
331
332class AcademicsManager(grok.Role):
333    grok.name('waeup.AcademicsManager')
334    grok.title(u'Academics Manager')
335    title = u'Academics Manager'
336    grok.permissions('waeup.viewAcademics',
337                     'waeup.manageAcademics')
338
339class ACManager(grok.Role):
340    grok.name('waeup.ACManager')
341    grok.title(u'Access Code Manager')
342    grok.permissions('waeup.manageACBatches')
343
344class DataCenterManager(grok.Role):
345    grok.name('waeup.DataCenterManager')
346    grok.title(u'Datacenter Manager')
347    grok.permissions('waeup.manageDataCenter')
348
349class ImportManager(grok.Role):
350    grok.name('waeup.ImportManager')
351    grok.title(u'Import Manager')
352    grok.permissions('waeup.manageDataCenter',
353                     'waeup.importData')
354
355class ExportManager(grok.Role):
356    grok.name('waeup.ExportManager')
357    grok.title(u'Export Manager')
358    grok.permissions('waeup.manageDataCenter',
359                     'waeup.exportData')
360
361class BursaryOfficer(grok.Role):
362    grok.name('waeup.BursaryOfficer')
363    grok.title(u'Bursary Officer')
364    grok.permissions('waeup.showStudents',
365                     'waeup.viewAcademics',
366                     'waeup.exportBursaryData')
367
368class UsersManager(grok.Role):
369    grok.name('waeup.UsersManager')
370    grok.title(u'Users Manager')
371    grok.permissions('waeup.manageUsers',
372                     'waeup.editUser')
373
374class WorkflowManager(grok.Role):
375    grok.name('waeup.WorkflowManager')
376    grok.title(u'Workflow Manager')
377    grok.permissions('waeup.triggerTransition')
378
379class PortalManager(grok.Role):
380    """The portal manager role is the maximum set of Kofa permissions
381    which are needed to manage the entire portal. This set must not
382    be changed or customized. It is recommended to assign this role only
383    to only a few portal administrators. A less dangerous manager role is the
384    CCOfficer role described below. For the most tasks the CCOfficer role
385    is sufficient.
386    """
387    grok.name('waeup.PortalManager')
388    grok.title(u'Portal Manager')
389    grok.permissions('waeup.managePortal',
390                     'waeup.manageUsers',
391                     'waeup.viewAcademics', 'waeup.manageAcademics',
392                     'waeup.manageACBatches',
393                     'waeup.manageDataCenter',
394                     'waeup.importData',
395                     'waeup.exportData',
396                     'waeup.viewTranscript',
397                     'waeup.viewDocuments', 'waeup.manageDocuments',
398                     'waeup.managePortalConfiguration', 'waeup.viewApplication',
399                     'waeup.manageApplication', 'waeup.handleApplication',
400                     'waeup.viewApplicantsTab', 'waeup.payApplicant',
401                     'waeup.viewApplicationStatistics',
402                     'waeup.viewStudent', 'waeup.manageStudent',
403                     'waeup.clearStudent', 'waeup.payStudent',
404                     'waeup.uploadStudentFile', 'waeup.showStudents',
405                     'waeup.clearAllStudents',
406                     'waeup.editScores',
407                     'waeup.triggerTransition',
408                     'waeup.viewStudentsContainer','waeup.viewStudentsTab',
409                     'waeup.handleAccommodation',
410                     'waeup.viewHostels', 'waeup.manageHostels',
411                     'waeup.editUser',
412                     'waeup.loginAsStudent',
413                     'waeup.manageReports',
414                     'waeup.manageJobs',
415                     )
416
417class CCOfficer(grok.Role):
418    """The Computer Center Officer role is basically a copy
419    of the the PortalManager role. Some 'dangerous' permissions are excluded
420    by commenting them out (see source code). If officers need to gain more
421    access rights than defined in this role, do not hastily switch to the
422    PortalManager role but add further manager roles instead. These additional
423    roles could be: UsersManager, ACManager, ImportManager, WorkflowManager
424    or StudentImpersonator.
425    """
426    grok.baseclass()
427    grok.name('waeup.CCOfficer')
428    grok.title(u'Computer Center Officer')
429    grok.permissions(#'waeup.managePortal',
430                     #'waeup.manageUsers',
431                     'waeup.viewAcademics', 'waeup.manageAcademics',
432                     #'waeup.manageACBatches',
433                     'waeup.manageDataCenter',
434                     #'waeup.importData',
435                     'waeup.exportData',
436                     'waeup.viewTranscript',
437                     'waeup.viewDocuments', 'waeup.manageDocuments',
438                     'waeup.managePortalConfiguration', 'waeup.viewApplication',
439                     'waeup.manageApplication', 'waeup.handleApplication',
440                     'waeup.viewApplicantsTab', 'waeup.payApplicant',
441                     'waeup.viewApplicationStatistics',
442                     'waeup.viewStudent', 'waeup.manageStudent',
443                     'waeup.clearStudent', 'waeup.payStudent',
444                     'waeup.uploadStudentFile', 'waeup.showStudents',
445                     'waeup.clearAllStudents',
446                     'waeup.editScores',
447                     #'waeup.triggerTransition',
448                     'waeup.viewStudentsContainer','waeup.viewStudentsTab',
449                     'waeup.handleAccommodation',
450                     'waeup.viewHostels', 'waeup.manageHostels',
451                     #'waeup.editUser',
452                     #'waeup.loginAsStudent',
453                     'waeup.manageReports',
454                     #'waeup.manageJobs',
455                     )
456
457def get_all_roles():
458    """Return a list of tuples ``<ROLE-NAME>, <ROLE>``.
459    """
460    return getUtilitiesFor(IRole)
461
462def get_waeup_roles(also_local=False):
463    """Get all Kofa roles.
464
465    Kofa roles are ordinary roles whose id by convention starts with
466    a ``waeup.`` prefix.
467
468    If `also_local` is ``True`` (``False`` by default), also local
469    roles are returned. Local Kofa roles are such whose id starts
470    with ``waeup.local.`` prefix (this is also a convention).
471
472    Returns a generator of the found roles.
473    """
474    for name, item in get_all_roles():
475        if not name.startswith('waeup.'):
476            # Ignore non-Kofa roles...
477            continue
478        if not also_local and name.startswith('waeup.local.'):
479            # Ignore local roles...
480            continue
481        yield item
482
483def get_waeup_role_names():
484    """Get the ids of all Kofa roles.
485
486    See :func:`get_waeup_roles` for what a 'KofaRole' is.
487
488    This function returns a sorted list of Kofa role names.
489    """
490    return sorted([x.id for x in get_waeup_roles()])
491
492class LocalRolesAssignable(grok.Adapter):
493    """Default implementation for `ILocalRolesAssignable`.
494
495    This adapter returns a list for dictionaries for objects for which
496    we want to know the roles assignable to them locally.
497
498    The returned dicts contain a ``name`` and a ``title`` entry which
499    give a role (``name``) and a description, for which kind of users
500    the permission is meant to be used (``title``).
501
502    Having this adapter registered we make sure, that for each normal
503    object we get a valid `ILocalRolesAssignable` adapter.
504
505    Objects that want to offer certain local roles, can do so by
506    setting a (preferably class-) attribute to a list of role ids.
507
508    You can also define different adapters for different contexts to
509    have different role lookup mechanisms become available. But in
510    normal cases it should be sufficient to use this basic adapter.
511    """
512    grok.context(Interface)
513    grok.provides(ILocalRolesAssignable)
514
515    _roles = []
516
517    def __init__(self, context):
518        self.context = context
519        role_ids = getattr(context, 'local_roles', self._roles)
520        self._roles = [(name, role) for name, role in get_all_roles()
521                       if name in role_ids]
522        return
523
524    def __call__(self):
525        """Get a list of dictionaries containing ``names`` (the roles to
526        assign) and ``titles`` (some description of the type of user
527        to assign each role to).
528        """
529        list_of_dict = [dict(
530                name=name,
531                title=role.title,
532                description=role.description)
533                for name, role in self._roles]
534        return sorted(list_of_dict, key=lambda x: x['name'])
535
536def get_all_users():
537    """Get a list of dictionaries.
538    """
539    users = sorted(grok.getSite()['users'].items(), key=lambda x: x[1].title)
540    for key, val in users:
541        yield(dict(name=key, val=val))
542
543def get_users_with_local_roles(context):
544    """Get a list of dicts representing the local roles set for `context`.
545
546    Each dict returns `user_name`, `user_title`, `local_role`,
547    `local_role_title`, and `setting` for each entry in the local
548    roles map of the `context` object.
549    """
550    try:
551        role_map = IPrincipalRoleMap(context)
552    except TypeError:
553        # no map no roles.
554        raise StopIteration
555    for local_role, user_name, setting in role_map.getPrincipalsAndRoles():
556        user = grok.getSite()['users'].get(user_name,None)
557        user_title = getattr(user, 'title', user_name)
558        local_role_title = getattr(
559            dict(get_all_roles()).get(local_role, None), 'title', None)
560        yield dict(user_name = user_name,
561                   user_title = user_title,
562                   local_role = local_role,
563                   local_role_title = local_role_title,
564                   setting = setting)
565
566def get_users_with_role(role, context):
567    """Get a list of dicts representing the usres who have been granted
568    a role for `context`.
569    """
570    try:
571        role_map = IPrincipalRoleMap(context)
572    except TypeError:
573        # no map no roles.
574        raise StopIteration
575    for user_name, setting in role_map.getPrincipalsForRole(role):
576        user = grok.getSite()['users'].get(user_name,None)
577        user_title = getattr(user, 'title', user_name)
578        user_email = getattr(user, 'email', None)
579        yield dict(user_name = user_name,
580                   user_title = user_title,
581                   user_email = user_email,
582                   setting = setting)
Note: See TracBrowser for help on using the repository browser.