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

Last change on this file since 10999 was 10639, checked in by Henrik Bettermann, 11 years ago

Define new local roles (see uniben ticket 900).

Allow the dynamical assignment of multiple local roles.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 17.4 KB
RevLine 
[7193]1## $Id: permissions.py 10639 2013-09-22 08:54:03Z 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##
[3521]18import grok
[6157]19from zope.component import getUtilitiesFor
[6144]20from zope.interface import Interface
[6163]21from zope.securitypolicy.interfaces import IRole, IPrincipalRoleMap
[7811]22from waeup.kofa.interfaces import ILocalRolesAssignable
[3521]23
[4789]24class Public(grok.Permission):
25    """Everyone-can-do-this-permission.
26
27    This permission is meant to be applied to objects/views/pages
28    etc., that should be usable/readable by everyone.
29
30    We need this to be able to tune default permissions more
31    restrictive and open up some dedicated objects like the front
32    page.
33    """
34    grok.name('waeup.Public')
[6142]35
[5433]36class Anonymous(grok.Permission):
37    """Only-anonymous-can-do-this-permission.
38    """
[6142]39    grok.name('waeup.Anonymous')
[4789]40
[7184]41class Authenticated(grok.Permission):
42    """Only-logged-in-users-can-do-this-permission.
43    """
44    grok.name('waeup.Authenticated')
[4789]45
[7184]46class ViewAcademicsPermission(grok.Permission):
47    grok.name('waeup.viewAcademics')
48
[8367]49class ManageAcademicsPermission(grok.Permission):
50    grok.name('waeup.manageAcademics')
[4789]51
[8367]52class ManagePortal(grok.Permission):
53    grok.name('waeup.managePortal')
54
[4789]55class ManageUsers(grok.Permission):
56    grok.name('waeup.manageUsers')
[6142]57
[7205]58class ShowStudents(grok.Permission):
59    grok.name('waeup.showStudents')
60
[10632]61class EditScores(grok.Permission):
62    grok.name('waeup.editScores')
63
[7163]64class EditUser(grok.Permission):
65    grok.name('waeup.editUser')
66
[6127]67class ManageDataCenter(grok.Permission):
68    grok.name('waeup.manageDataCenter')
[6142]69
[8367]70class ImportData(grok.Permission):
71    grok.name('waeup.importData')
72
[10177]73class ExportData(grok.Permission):
74    grok.name('waeup.exportData')
75
[10279]76class ExportPaymentsOverview(grok.Permission):
77    grok.name('waeup.exportPaymentsOverview')
78
79class ExportBursaryData(grok.Permission):
80    grok.name('waeup.exportBursaryData')
81
[10278]82class ViewTranscript(grok.Permission):
83    grok.name('waeup.viewTranscript')
84
[6907]85class ManagePortalConfiguration(grok.Permission):
86    grok.name('waeup.managePortalConfiguration')
[6155]87
[7181]88class ManageACBatches(grok.Permission):
89    grok.name('waeup.manageACBatches')
90
[6125]91# Local Roles
[10226]92class ApplicationsManager(grok.Role):
93    grok.name('waeup.local.ApplicationsManager')
94    grok.title(u'Applications Manager')
95    grok.permissions('waeup.viewAcademics')
96
[7185]97class DepartmentManager(grok.Role):
98    grok.name('waeup.local.DepartmentManager')
99    grok.title(u'Department Manager')
[10248]100    grok.permissions('waeup.manageAcademics',
101                     'waeup.showStudents',
102                     'waeup.exportData')
[6142]103
[10279]104class DepartmentOfficer(grok.Role):
105    grok.name('waeup.local.DepartmentOfficer')
106    grok.title(u'Department Officer')
107    grok.permissions('waeup.showStudents',
108                     'waeup.viewAcademics',
109                     'waeup.exportPaymentsOverview')
110
[6655]111class ClearanceOfficer(grok.Role):
[7168]112    """The clearance officer role is meant for the
113    assignment of dynamic roles only.
114    """
[6655]115    grok.name('waeup.local.ClearanceOfficer')
116    grok.title(u'Clearance Officer')
[10248]117    grok.permissions('waeup.showStudents',
118                     'waeup.viewAcademics',
119                     'waeup.exportData')
[6655]120
[10639]121class LocalStudentsManager(grok.Role):
122    """The local students manager role is meant for the
123    assignment of dynamic roles only.
124    """
125    grok.name('waeup.local.LocalStudentsManager')
126    grok.title(u'Students Manager')
127    grok.permissions('waeup.showStudents',
128                     'waeup.viewAcademics',
129                     'waeup.exportData')
130
131class LocalWorkflowManager(grok.Role):
132    """The local workflow manager role is meant for the
133    assignment of dynamic roles only.
134    """
135    grok.name('waeup.local.LocalWorkflowManager')
136    grok.title(u'Student Workflow Manager')
137    grok.permissions('waeup.showStudents',
138                     'waeup.viewAcademics',
139                     'waeup.exportData')
140
[8962]141class UGClearanceOfficer(grok.Role):
142    """The clearance officer role is meant for the
143    assignment of dynamic roles only.
144    """
145    grok.name('waeup.local.UGClearanceOfficer')
146    grok.title(u'UG Clearance Officer')
[10248]147    grok.permissions('waeup.showStudents',
148                     'waeup.viewAcademics',
149                     'waeup.exportData')
[8962]150
151class PGClearanceOfficer(grok.Role):
152    """The clearance officer role is meant for the
153    assignment of dynamic roles only.
154    """
155    grok.name('waeup.local.PGClearanceOfficer')
156    grok.title(u'PG Clearance Officer')
[10248]157    grok.permissions('waeup.showStudents',
158                     'waeup.viewAcademics',
159                     'waeup.exportData')
[8962]160
[7334]161class CourseAdviser100(grok.Role):
[7335]162    """The 100 level course adviser role is meant for the
[7168]163    assignment of dynamic roles only.
164    """
[7334]165    grok.name('waeup.local.CourseAdviser100')
166    grok.title(u'Course Adviser 100L')
[10248]167    grok.permissions('waeup.showStudents',
168                     'waeup.viewAcademics',
169                     'waeup.exportData')
[6655]170
[7334]171class CourseAdviser200(grok.Role):
[7335]172    """The course 200 level adviser role is meant for the
[7334]173    assignment of dynamic roles only.
174    """
175    grok.name('waeup.local.CourseAdviser200')
176    grok.title(u'Course Adviser 200L')
[10248]177    grok.permissions('waeup.showStudents',
178                     'waeup.viewAcademics',
179                     'waeup.exportData')
[7334]180
181class CourseAdviser300(grok.Role):
[7335]182    """The 300 level course adviser role is meant for the
[7334]183    assignment of dynamic roles only.
184    """
185    grok.name('waeup.local.CourseAdviser300')
186    grok.title(u'Course Adviser 300L')
[10248]187    grok.permissions('waeup.showStudents',
188                     'waeup.viewAcademics',
189                     'waeup.exportData')
[7334]190
191class CourseAdviser400(grok.Role):
[7335]192    """The 400 level course adviser role is meant for the
[7334]193    assignment of dynamic roles only.
194    """
195    grok.name('waeup.local.CourseAdviser400')
196    grok.title(u'Course Adviser 400L')
[10248]197    grok.permissions('waeup.showStudents',
198                     'waeup.viewAcademics',
199                     'waeup.exportData')
[7334]200
201class CourseAdviser500(grok.Role):
[7335]202    """The 500 level course adviser role is meant for the
[7334]203    assignment of dynamic roles only.
204    """
205    grok.name('waeup.local.CourseAdviser500')
206    grok.title(u'Course Adviser 500L')
[10248]207    grok.permissions('waeup.showStudents',
208                     'waeup.viewAcademics',
209                     'waeup.exportData')
[7334]210
211class CourseAdviser600(grok.Role):
[7335]212    """The 600 level course adviser role is meant for the
[7334]213    assignment of dynamic roles only.
214    """
215    grok.name('waeup.local.CourseAdviser600')
216    grok.title(u'Course Adviser 600L')
[10248]217    grok.permissions('waeup.showStudents',
218                     'waeup.viewAcademics',
219                     'waeup.exportData')
[7334]220
[10064]221class CourseAdviser700(grok.Role):
222    """The 700 level course adviser role is meant for the
223    assignment of dynamic roles only.
224    """
225    grok.name('waeup.local.CourseAdviser700')
226    grok.title(u'Course Adviser 700L')
[10248]227    grok.permissions('waeup.showStudents',
228                     'waeup.viewAcademics',
229                     'waeup.exportData')
[10064]230
231class CourseAdviser800(grok.Role):
232    """The 800 level course adviser role is meant for the
233    assignment of dynamic roles only.
234    """
235    grok.name('waeup.local.CourseAdviser800')
236    grok.title(u'Course Adviser 800L')
[10248]237    grok.permissions('waeup.showStudents',
238                     'waeup.viewAcademics',
239                     'waeup.exportData')
[10064]240
[9002]241class Lecturer(grok.Role):
242    """The lecturer role is meant for the
243    assignment of dynamic roles only.
244    """
245    grok.name('waeup.local.Lecturer')
246    grok.title(u'Lecturer')
[10248]247    grok.permissions('waeup.showStudents',
[10632]248                     'waeup.editScores',
[10248]249                     'waeup.viewAcademics',
250                     'waeup.exportData')
[9002]251
[7163]252class Owner(grok.Role):
253    grok.name('waeup.local.Owner')
254    grok.title(u'Owner')
255    grok.permissions('waeup.editUser')
256
[7178]257# Site Roles
[7185]258class AcademicsOfficer(grok.Role):
259    grok.name('waeup.AcademicsOfficer')
[7188]260    grok.title(u'Academics Officer (view only)')
[7184]261    grok.permissions('waeup.viewAcademics')
[3521]262
[8367]263class AcademicsManager(grok.Role):
264    grok.name('waeup.AcademicsManager')
265    grok.title(u'Academics Manager')
266    grok.permissions('waeup.viewAcademics',
267                     'waeup.manageAcademics')
268
[7181]269class ACManager(grok.Role):
270    grok.name('waeup.ACManager')
271    grok.title(u'Access Code Manager')
272    grok.permissions('waeup.manageACBatches')
273
[8367]274class DataCenterManager(grok.Role):
275    grok.name('waeup.DataCenterManager')
276    grok.title(u'Datacenter Manager')
277    grok.permissions('waeup.manageDataCenter')
278
279class ImportManager(grok.Role):
280    grok.name('waeup.ImportManager')
281    grok.title(u'Import Manager')
282    grok.permissions('waeup.manageDataCenter',
283                     'waeup.importData')
284
[10177]285class ExportManager(grok.Role):
286    grok.name('waeup.ExportManager')
287    grok.title(u'Export Manager')
288    grok.permissions('waeup.manageDataCenter',
289                     'waeup.exportData')
290
[10246]291class BursaryOfficer(grok.Role):
292    grok.name('waeup.BursaryOfficer')
293    grok.title(u'Bursary Officer')
[10279]294    grok.permissions('waeup.showStudents',
295                     'waeup.viewAcademics',
296                     'waeup.exportBursaryData')
[10246]297
[8367]298class UsersManager(grok.Role):
299    grok.name('waeup.UsersManager')
300    grok.title(u'Users Manager')
[9259]301    grok.permissions('waeup.manageUsers',
302                     'waeup.editUser')
[8367]303
[9300]304class WorkflowManager(grok.Role):
305    grok.name('waeup.WorkflowManager')
306    grok.title(u'Workflow Manager')
[9299]307    grok.permissions('waeup.triggerTransition')
308
[4789]309class PortalManager(grok.Role):
310    grok.name('waeup.PortalManager')
[6159]311    grok.title(u'Portal Manager')
[9259]312    grok.permissions('waeup.managePortal',
313                     'waeup.manageUsers',
[8374]314                     'waeup.viewAcademics', 'waeup.manageAcademics',
[8367]315                     'waeup.manageACBatches',
[9259]316                     'waeup.manageDataCenter',
317                     'waeup.importData',
[10177]318                     'waeup.exportData',
[10278]319                     'waeup.viewTranscript',
[7184]320                     'waeup.managePortalConfiguration', 'waeup.viewApplication',
321                     'waeup.manageApplication', 'waeup.handleApplication',
[7250]322                     'waeup.viewApplicantsTab', 'waeup.payApplicant',
[8565]323                     'waeup.viewApplicationStatistics',
[7250]324                     'waeup.viewStudent', 'waeup.manageStudent',
325                     'waeup.clearStudent', 'waeup.payStudent',
326                     'waeup.uploadStudentFile', 'waeup.showStudents',
[10632]327                     'waeup.editScores',
[9273]328                     'waeup.triggerTransition',
[7250]329                     'waeup.viewStudentsContainer','waeup.viewStudentsTab',
[9186]330                     'waeup.handleAccommodation',
[7205]331                     'waeup.viewHostels', 'waeup.manageHostels',
[9335]332                     'waeup.editUser',
[9637]333                     'waeup.loginAsStudent',
334                     'waeup.manageReports',
[9645]335                     'waeup.manageJobs',
[7240]336                     )
[4789]337
[9259]338class CCOfficer(grok.Role):
[9303]339    """This is basically a copy of the the PortalManager class. We exclude some
[9262]340    'dangerous' permissions by commenting them out.
[9259]341    """
[10346]342    grok.baseclass()
[9259]343    grok.name('waeup.CCOfficer')
344    grok.title(u'Computer Center Officer')
345    grok.permissions(#'waeup.managePortal',
346                     #'waeup.manageUsers',
347                     'waeup.viewAcademics', 'waeup.manageAcademics',
348                     #'waeup.manageACBatches',
349                     'waeup.manageDataCenter',
350                     #'waeup.importData',
[10243]351                     'waeup.exportData',
[10278]352                     'waeup.viewTranscript',
[9259]353                     'waeup.managePortalConfiguration', 'waeup.viewApplication',
354                     'waeup.manageApplication', 'waeup.handleApplication',
355                     'waeup.viewApplicantsTab', 'waeup.payApplicant',
356                     'waeup.viewApplicationStatistics',
357                     'waeup.viewStudent', 'waeup.manageStudent',
358                     'waeup.clearStudent', 'waeup.payStudent',
359                     'waeup.uploadStudentFile', 'waeup.showStudents',
[10632]360                     'waeup.editScores',
[9273]361                     #'waeup.triggerTransition',
[9259]362                     'waeup.viewStudentsContainer','waeup.viewStudentsTab',
363                     'waeup.handleAccommodation',
364                     'waeup.viewHostels', 'waeup.manageHostels',
[9335]365                     #'waeup.editUser',
[9637]366                     #'waeup.loginAsStudent',
367                     'waeup.manageReports',
[9645]368                     #'waeup.manageJobs',
[9259]369                     )
370
[7186]371def get_all_roles():
[6157]372    """Return a list of tuples ``<ROLE-NAME>, <ROLE>``.
373    """
374    return getUtilitiesFor(IRole)
375
[7186]376def get_waeup_roles(also_local=False):
[7819]377    """Get all Kofa roles.
[6157]378
[7819]379    Kofa roles are ordinary roles whose id by convention starts with
[6157]380    a ``waeup.`` prefix.
381
382    If `also_local` is ``True`` (``False`` by default), also local
[7819]383    roles are returned. Local Kofa roles are such whose id starts
[6157]384    with ``waeup.local.`` prefix (this is also a convention).
385
386    Returns a generator of the found roles.
387    """
[7186]388    for name, item in get_all_roles():
[6157]389        if not name.startswith('waeup.'):
[7819]390            # Ignore non-Kofa roles...
[4789]391            continue
[6157]392        if not also_local and name.startswith('waeup.local.'):
393            # Ignore local roles...
[6045]394            continue
[6157]395        yield item
[4789]396
[7186]397def get_waeup_role_names():
[7819]398    """Get the ids of all Kofa roles.
[6157]399
[7819]400    See :func:`get_waeup_roles` for what a 'KofaRole' is.
[6157]401
[7819]402    This function returns a sorted list of Kofa role names.
[6157]403    """
[7186]404    return sorted([x.id for x in get_waeup_roles()])
[6157]405
[6144]406class LocalRolesAssignable(grok.Adapter):
407    """Default implementation for `ILocalRolesAssignable`.
408
409    This adapter returns a list for dictionaries for objects for which
410    we want to know the roles assignable to them locally.
411
412    The returned dicts contain a ``name`` and a ``title`` entry which
413    give a role (``name``) and a description, for which kind of users
414    the permission is meant to be used (``title``).
415
416    Having this adapter registered we make sure, that for each normal
417    object we get a valid `ILocalRolesAssignable` adapter.
418
419    Objects that want to offer certain local roles, can do so by
[6162]420    setting a (preferably class-) attribute to a list of role ids.
[6144]421
422    You can also define different adapters for different contexts to
423    have different role lookup mechanisms become available. But in
424    normal cases it should be sufficient to use this basic adapter.
425    """
426    grok.context(Interface)
427    grok.provides(ILocalRolesAssignable)
428
429    _roles = []
430
431    def __init__(self, context):
432        self.context = context
[6162]433        role_ids = getattr(context, 'local_roles', self._roles)
[7186]434        self._roles = [(name, role) for name, role in get_all_roles()
[6162]435                       if name in role_ids]
[6144]436        return
437
438    def __call__(self):
439        """Get a list of dictionaries containing ``names`` (the roles to
440        assign) and ``titles`` (some description of the type of user
441        to assign each role to).
442        """
[7334]443        list_of_dict = [dict(
[6162]444                name=name,
445                title=role.title,
[6163]446                description=role.description)
[7334]447                for name, role in self._roles]
448        return sorted(list_of_dict, key=lambda x: x['name'])
[6144]449
[8774]450def get_all_users():
451    """Get a list of dictionaries.
452    """
453    users = sorted(grok.getSite()['users'].items(), key=lambda x: x[1].title)
454    for key, val in users:
455        yield(dict(name=key, val=val))
456
[6163]457def get_users_with_local_roles(context):
458    """Get a list of dicts representing the local roles set for `context`.
459
460    Each dict returns `user_name`, `user_title`, `local_role`,
461    `local_role_title`, and `setting` for each entry in the local
462    roles map of the `context` object.
463    """
[6202]464    try:
465        role_map = IPrincipalRoleMap(context)
466    except TypeError:
467        # no map no roles.
468        raise StopIteration
[6163]469    for local_role, user_name, setting in role_map.getPrincipalsAndRoles():
470        user = grok.getSite()['users'].get(user_name,None)
[7213]471        user_title = getattr(user, 'title', user_name)
[10227]472        local_role_title = getattr(
473            dict(get_all_roles()).get(local_role, None), 'title', None)
[6163]474        yield dict(user_name = user_name,
475                   user_title = user_title,
476                   local_role = local_role,
477                   local_role_title = local_role_title,
[9309]478                   setting = setting)
479
480def get_users_with_role(role, context):
481    """Get a list of dicts representing the usres who have been granted
482    a role for `context`.
483    """
484    try:
485        role_map = IPrincipalRoleMap(context)
486    except TypeError:
487        # no map no roles.
488        raise StopIteration
489    for user_name, setting in role_map.getPrincipalsForRole(role):
490        user = grok.getSite()['users'].get(user_name,None)
491        user_title = getattr(user, 'title', user_name)
492        user_email = getattr(user, 'email', None)
493        yield dict(user_name = user_name,
494                   user_title = user_title,
495                   user_email = user_email,
496                   setting = setting)
Note: See TracBrowser for help on using the repository browser.