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

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

Add ReportsManager? role.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 23.7 KB
Line 
1## $Id: permissions.py 12844 2015-04-02 06:11:59Z 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 Public or everyone-can-do-this-permission is being applied
26    to views/pages that are used by everyone.
27    """
28    grok.name('waeup.Public')
29
30class Anonymous(grok.Permission):
31    """The Anonymous permission is applied to
32    views/pages which are dedicated to anonymous users only.
33    Logged-in users can't access these views.
34    """
35    grok.name('waeup.Anonymous')
36
37class Authenticated(grok.Permission):
38    """The 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 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 ManageAcademics permission is applied to all edit/manage
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 ManagePortal permission is used for very few pages
59    (e.g. the DatacenterSettings page). Only PortalManagers have this
60    permission. It is furthermore used to control delete methods of container
61    pages in the Academic Section. The 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 ManagePortal permission too to remove
65    entire containers.
66    """
67    grok.name('waeup.managePortal')
68
69class ManageUsers(grok.Permission):
70    """The 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
75    permissions.
76    """
77    grok.name('waeup.manageUsers')
78
79class ShowStudents(grok.Permission):
80    """Users with this permission do not neccessarily see the 'Students' tab
81    but they can search for students at department, certificate or course
82    level. If they additionally have the ExportData permission they can
83    export the data as csv files.
84
85    Bursary or Department Officers don't have the ExportData
86    permission (see Roles section) and are only allowed to export bursary
87    or payments overview data respectively.
88    """
89    grok.name('waeup.showStudents')
90
91class ClearAllStudents(grok.Permission):
92    """The ClearAllStudents permission allows to clear all students
93    in a department at one sweep.
94    """
95    grok.name('waeup.clearAllStudents')
96
97class EditScores(grok.Permission):
98    """The EditScores permission allows to edit scores in course tickets.
99    """
100    grok.name('waeup.editScores')
101
102class TriggerTransition(grok.Permission):
103    """The TriggerTransition permission allows to trigger workflow transitions
104    of student and document objects.
105    """
106    grok.name('waeup.triggerTransition')
107
108class EditUser(grok.Permission):
109    """The EditUser permission is required for editing
110    single user accounts.
111    """
112    grok.name('waeup.editUser')
113
114class ManageDataCenter(grok.Permission):
115    """The ManageDataCenter permission allows to access all pages
116    in the Data Center and to upload files. It does not automatically
117    allow to process uploaded data.
118    """
119    grok.name('waeup.manageDataCenter')
120
121class ImportData(grok.Permission):
122    """The ImportData permission allows to batch process (import) any kind of
123    portal data except for user data. This User Data processor
124    requires also the ManageUsers permission.
125    """
126    grok.name('waeup.importData')
127
128class ExportData(grok.Permission):
129    """The ExportData permission allows to export any kind of portal data.
130    """
131    grok.name('waeup.exportData')
132
133class ExportPaymentsOverview(grok.Permission):
134    grok.name('waeup.exportPaymentsOverview')
135
136class ExportBursaryData(grok.Permission):
137    grok.name('waeup.exportBursaryData')
138
139class ViewTranscript(grok.Permission):
140    grok.name('waeup.viewTranscript')
141
142class ManagePortalConfiguration(grok.Permission):
143    """The ManagePortalConfiguration permission allows to
144    edit global and sessional portal configuration data.
145    """
146    grok.name('waeup.managePortalConfiguration')
147
148class ManageACBatches(grok.Permission):
149    """The ManageACBatches permission allows to view and
150    manage accesscodes.
151    """
152    grok.name('waeup.manageACBatches')
153
154class PutBiometricDataPermission(grok.Permission):
155    """This permission allows to upload/change biometric data.
156    """
157    grok.name('waeup.putBiometricData')
158
159class GetBiometricDataPermission(grok.Permission):
160    """This permission allows to read biometric data.
161    """
162    grok.name('waeup.getBiometricData')
163
164
165# Local Roles
166class ApplicationsManager(grok.Role):
167    """
168    """
169    grok.name('waeup.local.ApplicationsManager')
170    grok.title(u'Applications Manager')
171    grok.permissions('waeup.viewAcademics')
172
173class DepartmentManager(grok.Role):
174    """
175    """
176    grok.name('waeup.local.DepartmentManager')
177    grok.title(u'Department Manager')
178    grok.permissions('waeup.manageAcademics',
179                     'waeup.showStudents',
180                     'waeup.exportData')
181
182class DepartmentOfficer(grok.Role):
183    """
184    """
185    grok.name('waeup.local.DepartmentOfficer')
186    grok.title(u'Department Officer')
187    grok.permissions('waeup.showStudents',
188                     'waeup.viewAcademics',
189                     'waeup.exportPaymentsOverview')
190
191class ClearanceOfficer(grok.Role):
192    """The clearance officer role is meant for the
193    assignment of dynamic roles only.
194    """
195    grok.name('waeup.local.ClearanceOfficer')
196    grok.title(u'Clearance Officer')
197    grok.permissions('waeup.showStudents',
198                     'waeup.viewAcademics',
199                     'waeup.exportData',
200                     'waeup.clearAllStudents')
201
202class LocalStudentsManager(grok.Role):
203    """The local students manager role is meant for the
204    assignment of dynamic roles only.
205    """
206    grok.name('waeup.local.LocalStudentsManager')
207    grok.title(u'Students Manager')
208    grok.permissions('waeup.showStudents',
209                     'waeup.viewAcademics',
210                     'waeup.exportData')
211
212class LocalWorkflowManager(grok.Role):
213    """The local workflow manager role is meant for the
214    assignment of dynamic roles only.
215    """
216    grok.name('waeup.local.LocalWorkflowManager')
217    grok.title(u'Student Workflow Manager')
218    grok.permissions('waeup.showStudents',
219                     'waeup.viewAcademics',
220                     'waeup.exportData')
221
222class UGClearanceOfficer(grok.Role):
223    """The clearance officer role is meant for the
224    assignment of dynamic roles only.
225    """
226    grok.name('waeup.local.UGClearanceOfficer')
227    grok.title(u'UG Clearance Officer')
228    grok.permissions('waeup.showStudents',
229                     'waeup.viewAcademics',
230                     'waeup.exportData',
231                     'waeup.clearAllStudents')
232
233class PGClearanceOfficer(grok.Role):
234    """The clearance officer role is meant for the
235    assignment of dynamic roles only.
236    """
237    grok.name('waeup.local.PGClearanceOfficer')
238    grok.title(u'PG Clearance Officer')
239    grok.permissions('waeup.showStudents',
240                     'waeup.viewAcademics',
241                     'waeup.exportData',
242                     'waeup.clearAllStudents')
243
244class CourseAdviser100(grok.Role):
245    """The 100 level course adviser role is meant for the
246    assignment of dynamic roles only.
247    """
248    grok.name('waeup.local.CourseAdviser100')
249    grok.title(u'Course Adviser 100L')
250    grok.permissions('waeup.showStudents',
251                     'waeup.viewAcademics',
252                     'waeup.exportData')
253
254class CourseAdviser200(grok.Role):
255    """The course 200 level adviser role is meant for the
256    assignment of dynamic roles only.
257    """
258    grok.name('waeup.local.CourseAdviser200')
259    grok.title(u'Course Adviser 200L')
260    grok.permissions('waeup.showStudents',
261                     'waeup.viewAcademics',
262                     'waeup.exportData')
263
264class CourseAdviser300(grok.Role):
265    """The 300 level course adviser role is meant for the
266    assignment of dynamic roles only.
267    """
268    grok.name('waeup.local.CourseAdviser300')
269    grok.title(u'Course Adviser 300L')
270    grok.permissions('waeup.showStudents',
271                     'waeup.viewAcademics',
272                     'waeup.exportData')
273
274class CourseAdviser400(grok.Role):
275    """The 400 level course adviser role is meant for the
276    assignment of dynamic roles only.
277    """
278    grok.name('waeup.local.CourseAdviser400')
279    grok.title(u'Course Adviser 400L')
280    grok.permissions('waeup.showStudents',
281                     'waeup.viewAcademics',
282                     'waeup.exportData')
283
284class CourseAdviser500(grok.Role):
285    """The 500 level course adviser role is meant for the
286    assignment of dynamic roles only.
287    """
288    grok.name('waeup.local.CourseAdviser500')
289    grok.title(u'Course Adviser 500L')
290    grok.permissions('waeup.showStudents',
291                     'waeup.viewAcademics',
292                     'waeup.exportData')
293
294class CourseAdviser600(grok.Role):
295    """The 600 level course adviser role is meant for the
296    assignment of dynamic roles only.
297    """
298    grok.name('waeup.local.CourseAdviser600')
299    grok.title(u'Course Adviser 600L')
300    grok.permissions('waeup.showStudents',
301                     'waeup.viewAcademics',
302                     'waeup.exportData')
303
304class CourseAdviser700(grok.Role):
305    """The 700 level course adviser role is meant for the
306    assignment of dynamic roles only.
307    """
308    grok.name('waeup.local.CourseAdviser700')
309    grok.title(u'Course Adviser 700L')
310    grok.permissions('waeup.showStudents',
311                     'waeup.viewAcademics',
312                     'waeup.exportData')
313
314class CourseAdviser800(grok.Role):
315    """The 800 level course adviser role is meant for the
316    assignment of dynamic roles only.
317    """
318    grok.name('waeup.local.CourseAdviser800')
319    grok.title(u'Course Adviser 800L')
320    grok.permissions('waeup.showStudents',
321                     'waeup.viewAcademics',
322                     'waeup.exportData')
323
324class Lecturer(grok.Role):
325    """The lecturer role is meant for the
326    assignment of dynamic roles only.
327    """
328    grok.name('waeup.local.Lecturer')
329    grok.title(u'Lecturer')
330    grok.permissions('waeup.showStudents',
331                     'waeup.editScores',
332                     'waeup.viewAcademics',
333                     'waeup.exportData')
334
335class Owner(grok.Role):
336    grok.name('waeup.local.Owner')
337    grok.title(u'Owner')
338    grok.permissions('waeup.editUser')
339
340# Site Roles
341class AcademicsOfficer(grok.Role):
342    """An Academics Officer can view but not edit data in the
343    Academics Section.
344
345    This is the default role which is automatically assigned to all
346    officers of the portal. A user with this role can access all display pages
347    at faculty, department, course, certificate and certificate course level.
348    """
349    grok.name('waeup.AcademicsOfficer')
350    grok.title(u'Academics Officer (view only)')
351    grok.permissions('waeup.viewAcademics')
352
353class AcademicsManager(grok.Role):
354    """An Academics Manager can view and edit all data in the
355    Academics Section, i.e. access all manage pages
356    at faculty, department, course, certificate and certificate course level.
357    """
358    grok.name('waeup.AcademicsManager')
359    grok.title(u'Academics Manager')
360    title = u'Academics Manager'
361    grok.permissions('waeup.viewAcademics',
362                     'waeup.manageAcademics')
363
364class ACManager(grok.Role):
365    """This is the role for Access Code Managers.
366    An ACManager can view and manage the Accesscodes Section, see
367    ManageACBatches permission above.
368    """
369    grok.name('waeup.ACManager')
370    grok.title(u'Access Code Manager')
371    grok.permissions('waeup.manageACBatches')
372
373class DataCenterManager(grok.Role):
374    """This single-permission role is dedicated to those users
375    who are charged with batch processing of portal data.
376    A DataCenterManager manager can access all pages in the Data Center,
377    see ManageDataCenter permission above.
378    """
379    grok.name('waeup.DataCenterManager')
380    grok.title(u'Datacenter Manager')
381    grok.permissions('waeup.manageDataCenter')
382
383class ImportManager(grok.Role):
384    """An ImportManager is a DataCenterManager who is also allowed
385    to batch process (import) data. All batch processors (importers) are
386    available except for the User Processor. This processor requires the
387    UsersManager role too. The ImportManager role includes the
388    DataCenterManager role but not vice versa.
389    """
390    grok.name('waeup.ImportManager')
391    grok.title(u'Import Manager')
392    grok.permissions('waeup.manageDataCenter',
393                     'waeup.importData')
394
395class ExportManager(grok.Role):
396    """An ExportManager is a DataCenterManager who is also allowed
397    to export all kind of portal data. The ExportManager role includes the
398    DataCenterManager role but not vice versa.
399    """
400    grok.name('waeup.ExportManager')
401    grok.title(u'Export Manager')
402    grok.permissions('waeup.manageDataCenter',
403                     'waeup.exportData')
404
405class BursaryOfficer(grok.Role):
406    """BursaryOfficers can export bursary data. They can't access the
407    Data Center but see student data export buttons in the Academic Section.
408    """
409    grok.name('waeup.BursaryOfficer')
410    grok.title(u'Bursary Officer')
411    grok.permissions('waeup.showStudents',
412                     'waeup.viewAcademics',
413                     'waeup.exportBursaryData')
414
415class UsersManager(grok.Role):
416    """A UsersManager can add, remove or edit
417    user accounts, see ManageUsers permission for further information.
418    Be very careful with this role.
419    """
420    grok.name('waeup.UsersManager')
421    grok.title(u'Users Manager')
422    grok.permissions('waeup.manageUsers',
423                     'waeup.editUser')
424
425class WorkflowManager(grok.Role):
426    """The WorkflowManager can trigger workflow transitions
427    of student and document objects, see TriggerTransition permission
428    for further information.
429    """
430    grok.name('waeup.WorkflowManager')
431    grok.title(u'Workflow Manager')
432    grok.permissions('waeup.triggerTransition')
433
434class PortalManager(grok.Role):
435    """The portal manager role is the maximum set of Kofa permissions
436    which are needed to manage the entire portal. This set must not
437    be customized. It is recommended to assign this role only
438    to a few certified Kofa administrators.
439    A less dangerous manager role is the CCOfficer role described below.
440    For the most tasks the CCOfficer role is sufficient.
441    """
442    grok.name('waeup.PortalManager')
443    grok.title(u'Portal Manager')
444    grok.permissions('waeup.managePortal',
445                     'waeup.manageUsers',
446                     'waeup.viewAcademics', 'waeup.manageAcademics',
447                     'waeup.manageACBatches',
448                     'waeup.manageDataCenter',
449                     'waeup.importData',
450                     'waeup.exportData',
451                     'waeup.viewTranscript',
452                     'waeup.viewDocuments', 'waeup.manageDocuments',
453                     'waeup.managePortalConfiguration', 'waeup.viewApplication',
454                     'waeup.manageApplication', 'waeup.handleApplication',
455                     'waeup.viewApplicantsTab', 'waeup.payApplicant',
456                     'waeup.viewApplicationStatistics',
457                     'waeup.viewStudent', 'waeup.manageStudent',
458                     'waeup.clearStudent', 'waeup.payStudent',
459                     'waeup.uploadStudentFile', 'waeup.showStudents',
460                     'waeup.clearAllStudents',
461                     'waeup.editScores',
462                     'waeup.triggerTransition',
463                     'waeup.viewStudentsContainer',
464                     'waeup.handleAccommodation',
465                     'waeup.viewHostels', 'waeup.manageHostels',
466                     'waeup.editUser',
467                     'waeup.loginAsStudent',
468                     'waeup.manageReports',
469                     'waeup.manageJobs',
470                     )
471
472class CCOfficer(grok.Role):
473    """The role of the Computer Center Officer is basically a copy
474    of the the PortalManager role. Some 'dangerous' permissions are excluded
475    by commenting them out (see source code). If officers need to gain more
476    access rights than defined in this role, do not hastily switch to the
477    PortalManager role but add further manager roles instead. Additional
478    roles could be: UsersManager, ACManager, ImportManager, WorkflowManager
479    or StudentImpersonator.
480
481    CCOfficer is a base class which means that this role is subject to
482    customization. It is not used in the ``waeup.kofa`` base package.
483    """
484    grok.baseclass()
485    grok.name('waeup.CCOfficer')
486    grok.title(u'Computer Center Officer')
487    grok.permissions(#'waeup.managePortal',
488                     #'waeup.manageUsers',
489                     'waeup.viewAcademics', 'waeup.manageAcademics',
490                     #'waeup.manageACBatches',
491                     'waeup.manageDataCenter',
492                     #'waeup.importData',
493                     'waeup.exportData',
494                     'waeup.viewTranscript',
495                     'waeup.viewDocuments', 'waeup.manageDocuments',
496                     'waeup.managePortalConfiguration', 'waeup.viewApplication',
497                     'waeup.manageApplication', 'waeup.handleApplication',
498                     'waeup.viewApplicantsTab', 'waeup.payApplicant',
499                     'waeup.viewApplicationStatistics',
500                     'waeup.viewStudent', 'waeup.manageStudent',
501                     'waeup.clearStudent', 'waeup.payStudent',
502                     'waeup.uploadStudentFile', 'waeup.showStudents',
503                     'waeup.clearAllStudents',
504                     'waeup.editScores',
505                     #'waeup.triggerTransition',
506                     'waeup.viewStudentsContainer',
507                     'waeup.handleAccommodation',
508                     'waeup.viewHostels', 'waeup.manageHostels',
509                     #'waeup.editUser',
510                     #'waeup.loginAsStudent',
511                     'waeup.manageReports',
512                     #'waeup.manageJobs',
513                     )
514
515def get_all_roles():
516    """Return a list of tuples ``<ROLE-NAME>, <ROLE>``.
517    """
518    return getUtilitiesFor(IRole)
519
520def get_waeup_roles(also_local=False):
521    """Get all Kofa roles.
522
523    Kofa roles are ordinary roles whose id by convention starts with
524    a ``waeup.`` prefix.
525
526    If `also_local` is ``True`` (``False`` by default), also local
527    roles are returned. Local Kofa roles are such whose id starts
528    with ``waeup.local.`` prefix (this is also a convention).
529
530    Returns a generator of the found roles.
531    """
532    for name, item in get_all_roles():
533        if not name.startswith('waeup.'):
534            # Ignore non-Kofa roles...
535            continue
536        if not also_local and name.startswith('waeup.local.'):
537            # Ignore local roles...
538            continue
539        yield item
540
541def get_waeup_role_names():
542    """Get the ids of all Kofa roles.
543
544    See :func:`get_waeup_roles` for what a 'KofaRole' is.
545
546    This function returns a sorted list of Kofa role names.
547    """
548    return sorted([x.id for x in get_waeup_roles()])
549
550class LocalRolesAssignable(grok.Adapter):
551    """Default implementation for `ILocalRolesAssignable`.
552
553    This adapter returns a list for dictionaries for objects for which
554    we want to know the roles assignable to them locally.
555
556    The returned dicts contain a ``name`` and a ``title`` entry which
557    give a role (``name``) and a description, for which kind of users
558    the permission is meant to be used (``title``).
559
560    Having this adapter registered we make sure, that for each normal
561    object we get a valid `ILocalRolesAssignable` adapter.
562
563    Objects that want to offer certain local roles, can do so by
564    setting a (preferably class-) attribute to a list of role ids.
565
566    You can also define different adapters for different contexts to
567    have different role lookup mechanisms become available. But in
568    normal cases it should be sufficient to use this basic adapter.
569    """
570    grok.context(Interface)
571    grok.provides(ILocalRolesAssignable)
572
573    _roles = []
574
575    def __init__(self, context):
576        self.context = context
577        role_ids = getattr(context, 'local_roles', self._roles)
578        self._roles = [(name, role) for name, role in get_all_roles()
579                       if name in role_ids]
580        return
581
582    def __call__(self):
583        """Get a list of dictionaries containing ``names`` (the roles to
584        assign) and ``titles`` (some description of the type of user
585        to assign each role to).
586        """
587        list_of_dict = [dict(
588                name=name,
589                title=role.title,
590                description=role.description)
591                for name, role in self._roles]
592        return sorted(list_of_dict, key=lambda x: x['name'])
593
594def get_all_users():
595    """Get a list of dictionaries.
596    """
597    users = sorted(grok.getSite()['users'].items(), key=lambda x: x[1].title)
598    for key, val in users:
599        yield(dict(name=key, val=val))
600
601def get_users_with_local_roles(context):
602    """Get a list of dicts representing the local roles set for `context`.
603
604    Each dict returns `user_name`, `user_title`, `local_role`,
605    `local_role_title`, and `setting` for each entry in the local
606    roles map of the `context` object.
607    """
608    try:
609        role_map = IPrincipalRoleMap(context)
610    except TypeError:
611        # no map no roles.
612        raise StopIteration
613    for local_role, user_name, setting in role_map.getPrincipalsAndRoles():
614        user = grok.getSite()['users'].get(user_name,None)
615        user_title = getattr(user, 'title', user_name)
616        local_role_title = getattr(
617            dict(get_all_roles()).get(local_role, None), 'title', None)
618        yield dict(user_name = user_name,
619                   user_title = user_title,
620                   local_role = local_role,
621                   local_role_title = local_role_title,
622                   setting = setting)
623
624def get_users_with_role(role, context):
625    """Get a list of dicts representing the usres who have been granted
626    a role for `context`.
627    """
628    try:
629        role_map = IPrincipalRoleMap(context)
630    except TypeError:
631        # no map no roles.
632        raise StopIteration
633    for user_name, setting in role_map.getPrincipalsForRole(role):
634        user = grok.getSite()['users'].get(user_name,None)
635        user_title = getattr(user, 'title', user_name)
636        user_email = getattr(user, 'email', None)
637        yield dict(user_name = user_name,
638                   user_title = user_title,
639                   user_email = user_email,
640                   setting = setting)
Note: See TracBrowser for help on using the repository browser.