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

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

More docs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 26.1 KB
Line 
1## $Id: permissions.py 13046 2015-06-14 11:33:07Z 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 files.
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. The 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
166
167class ApplicationsManager(grok.Role):
168    """The local ApplicationsManager role can be assigned at department level.
169    Local Applications Managers do not gain further permissions. This role is
170    meant for the assignment of dynamic roles only, see below.
171    """
172    grok.name('waeup.local.ApplicationsManager')
173    grok.title(u'Applications Manager')
174    grok.permissions('waeup.viewAcademics')
175
176class DepartmentManager(grok.Role):
177    """The local DepartmentManager role can be assigned at faculty or
178    department level. The role allows to edit all data within this container.
179    It does not automatically allow to remove sub-containers.
180
181    Department Managers (Dean of Faculty or Head of Department respectively)
182    can also list student data but not access student pages.
183    """
184    grok.name('waeup.local.DepartmentManager')
185    grok.title(u'Department Manager')
186    grok.permissions('waeup.manageAcademics',
187                     'waeup.showStudents',
188                     'waeup.exportData')
189
190class DepartmentOfficer(grok.Role):
191    """The local DepartmentOfficer role can be assigned at faculty or
192    department level. The role allows to list all student data within the
193    faculty/department the local role is assigned.
194
195    Department Managers (Dean of Faculty or Head of Department respectively)
196    can also list student data but not access student pages. They can
197    furthermore export payment overviews.
198    """
199    grok.name('waeup.local.DepartmentOfficer')
200    grok.title(u'Department Officer')
201    grok.permissions('waeup.showStudents',
202                     'waeup.viewAcademics',
203                     'waeup.exportPaymentsOverview')
204
205class ClearanceOfficer(grok.Role):
206    """The local ClearanceOfficer role can be assigned at faculty or
207    department level. The role allows to list or export all student
208    data within the faculty/department the local role is assigned.
209
210    Clearance Officers can furthermore clear all students or reject clearance
211    of all students in their faculty/department. They get the
212    StudentsClearanceOfficer role for this subset of students.
213    """
214    grok.name('waeup.local.ClearanceOfficer')
215    grok.title(u'Clearance Officer')
216    grok.permissions('waeup.showStudents',
217                     'waeup.viewAcademics',
218                     'waeup.exportData',
219                     'waeup.clearAllStudents')
220
221class LocalStudentsManager(grok.Role):
222    """The local LocalStudentsManager role can be assigned at faculty or
223    department level. The role allows to view all data and to view or export
224    all student data within the faculty/department the local role is assigned.
225
226    Local Students Managers can furthermore manage data of students
227    in their faculty/department. They get the StudentsManager role for
228    this subset of students.
229    """
230    grok.name('waeup.local.LocalStudentsManager')
231    grok.title(u'Students Manager')
232    grok.permissions('waeup.showStudents',
233                     'waeup.viewAcademics',
234                     'waeup.exportData')
235
236class LocalWorkflowManager(grok.Role):
237    """The local LocalWorkflowManager role can be assigned at faculty level.
238    The role allows to view all data and to list or export
239    all student data within the faculty the local role is assigned.
240
241    Local Workflow Managers can trigger transition of students in their
242    faculty/department. They get the WorkflowManager role for
243    this subset of students.
244    """
245    grok.name('waeup.local.LocalWorkflowManager')
246    grok.title(u'Student Workflow Manager')
247    grok.permissions('waeup.showStudents',
248                     'waeup.viewAcademics',
249                     'waeup.exportData')
250
251class UGClearanceOfficer(grok.Role):
252    """UG Clearance Officers are regular Clearance Officers with restricted
253    dynamic permission assignment. They can only access undergraduate
254    students.
255    """
256    grok.name('waeup.local.UGClearanceOfficer')
257    grok.title(u'UG Clearance Officer')
258    grok.permissions('waeup.showStudents',
259                     'waeup.viewAcademics',
260                     'waeup.exportData',
261                     'waeup.clearAllStudents')
262
263class PGClearanceOfficer(grok.Role):
264    """PG Clearance Officers are regular Clearance Officers with restricted
265    dynamic permission assignment. They can only access postgraduate
266    students.
267    """
268    grok.name('waeup.local.PGClearanceOfficer')
269    grok.title(u'PG Clearance Officer')
270    grok.permissions('waeup.showStudents',
271                     'waeup.viewAcademics',
272                     'waeup.exportData',
273                     'waeup.clearAllStudents')
274
275class CourseAdviser100(grok.Role):
276    """The local CourseAdviser100 role can be assigned at faculty,
277    department or certificate level. The role allows to view all data and
278    to list or export all student data within the faculty, department
279    or certificate the local role is assigned.
280
281    Local Course Advisers can validate or reject course lists of students
282    in ther faculty/department/certificate at level 100.
283    They get the StudentsCourseAdviser role for this subset of students.
284    """
285    grok.name('waeup.local.CourseAdviser100')
286    grok.title(u'Course Adviser 100L')
287    grok.permissions('waeup.showStudents',
288                     'waeup.viewAcademics',
289                     'waeup.exportData')
290
291class CourseAdviser200(grok.Role):
292    """Same as CourseAdviser100 but for level 200.
293    """
294    grok.name('waeup.local.CourseAdviser200')
295    grok.title(u'Course Adviser 200L')
296    grok.permissions('waeup.showStudents',
297                     'waeup.viewAcademics',
298                     'waeup.exportData')
299
300class CourseAdviser300(grok.Role):
301    """Same as CourseAdviser100 but for level 300.
302    """
303    grok.name('waeup.local.CourseAdviser300')
304    grok.title(u'Course Adviser 300L')
305    grok.permissions('waeup.showStudents',
306                     'waeup.viewAcademics',
307                     'waeup.exportData')
308
309class CourseAdviser400(grok.Role):
310    """Same as CourseAdviser100 but for level 400.
311    """
312    grok.name('waeup.local.CourseAdviser400')
313    grok.title(u'Course Adviser 400L')
314    grok.permissions('waeup.showStudents',
315                     'waeup.viewAcademics',
316                     'waeup.exportData')
317
318class CourseAdviser500(grok.Role):
319    """Same as CourseAdviser100 but for level 500.
320    """
321    grok.name('waeup.local.CourseAdviser500')
322    grok.title(u'Course Adviser 500L')
323    grok.permissions('waeup.showStudents',
324                     'waeup.viewAcademics',
325                     'waeup.exportData')
326
327class CourseAdviser600(grok.Role):
328    """Same as CourseAdviser100 but for level 600.
329    """
330    grok.name('waeup.local.CourseAdviser600')
331    grok.title(u'Course Adviser 600L')
332    grok.permissions('waeup.showStudents',
333                     'waeup.viewAcademics',
334                     'waeup.exportData')
335
336class CourseAdviser700(grok.Role):
337    """Same as CourseAdviser100 but for level 700.
338    """
339    grok.name('waeup.local.CourseAdviser700')
340    grok.title(u'Course Adviser 700L')
341    grok.permissions('waeup.showStudents',
342                     'waeup.viewAcademics',
343                     'waeup.exportData')
344
345class CourseAdviser800(grok.Role):
346    """Same as CourseAdviser100 but for level 800.
347    """
348    grok.name('waeup.local.CourseAdviser800')
349    grok.title(u'Course Adviser 800L')
350    grok.permissions('waeup.showStudents',
351                     'waeup.viewAcademics',
352                     'waeup.exportData')
353
354class Lecturer(grok.Role):
355    """The local Lecturer role can be assigned at course level.
356    The role allows to view all data and to list or export all student
357    data within the course the local role is assigned. Lecturers can't access
358    student data directly but they can edit the scores in course tickets.
359    """
360    grok.name('waeup.local.Lecturer')
361    grok.title(u'Lecturer')
362    grok.permissions('waeup.showStudents',
363                     'waeup.editScores',
364                     'waeup.viewAcademics',
365                     'waeup.exportData')
366
367class Owner(grok.Role):
368    """Each user 'owns' her/his user object and gains permission to edit
369    some of the user attributes.
370    """
371    grok.name('waeup.local.Owner')
372    grok.title(u'Owner')
373    grok.permissions('waeup.editUser')
374
375# Site Roles
376
377class AcademicsOfficer(grok.Role):
378    """An Academics Officer can view but not edit data in the
379    academic section.
380
381    This is the default role which is automatically assigned to all
382    officers of the portal. A user with this role can access all display pages
383    at faculty, department, course, certificate and certificate course level.
384    """
385    grok.name('waeup.AcademicsOfficer')
386    grok.title(u'Academics Officer (view only)')
387    grok.permissions('waeup.viewAcademics')
388
389class AcademicsManager(grok.Role):
390    """An Academics Manager can view and edit all data in the
391    scademic section, i.e. access all manage pages
392    at faculty, department, course, certificate and certificate course level.
393    """
394    grok.name('waeup.AcademicsManager')
395    grok.title(u'Academics Manager')
396    title = u'Academics Manager'
397    grok.permissions('waeup.viewAcademics',
398                     'waeup.manageAcademics')
399
400class ACManager(grok.Role):
401    """This is the role for Access Code Managers.
402    An AC Manager can view and manage the Accesscodes Section, see
403    ManageACBatches permission above.
404    """
405    grok.name('waeup.ACManager')
406    grok.title(u'Access Code Manager')
407    grok.permissions('waeup.manageACBatches')
408
409class DataCenterManager(grok.Role):
410    """This single-permission role is dedicated to those users
411    who are charged with batch processing of portal data.
412    A Data Center Manager can access all pages in the Data Center,
413    see ManageDataCenter permission above.
414    """
415    grok.name('waeup.DataCenterManager')
416    grok.title(u'Datacenter Manager')
417    grok.permissions('waeup.manageDataCenter')
418
419class ImportManager(grok.Role):
420    """An Import Manager is a Data Center Manager who is also allowed
421    to batch process (import) data. All batch processors (importers) are
422    available except for the User Processor. This processor requires the
423    Users Manager role too. The ImportManager role includes the
424    DataCenterManager role but not vice versa.
425    """
426    grok.name('waeup.ImportManager')
427    grok.title(u'Import Manager')
428    grok.permissions('waeup.manageDataCenter',
429                     'waeup.importData')
430
431class ExportManager(grok.Role):
432    """An Export Manager is a Data Center Manager who is also allowed
433    to export all kind of portal data. The ExportManager role includes the
434    DataCenterManager role but not vice versa.
435    """
436    grok.name('waeup.ExportManager')
437    grok.title(u'Export Manager')
438    grok.permissions('waeup.manageDataCenter',
439                     'waeup.exportData')
440
441class BursaryOfficer(grok.Role):
442    """Bursary Officers can export bursary data. They can't access the
443    Data Center but see student data export buttons in the Academic Section.
444    """
445    grok.name('waeup.BursaryOfficer')
446    grok.title(u'Bursary Officer')
447    grok.permissions('waeup.showStudents',
448                     'waeup.viewAcademics',
449                     'waeup.exportBursaryData')
450
451class UsersManager(grok.Role):
452    """A Users Manager can add, remove or edit
453    user accounts, see ManageUsers permission for further information.
454    Be very careful with this role.
455    """
456    grok.name('waeup.UsersManager')
457    grok.title(u'Users Manager')
458    grok.permissions('waeup.manageUsers',
459                     'waeup.editUser')
460
461class WorkflowManager(grok.Role):
462    """The Workflow Manager can trigger workflow transitions
463    of student and document objects, see TriggerTransition permission
464    for further information.
465    """
466    grok.name('waeup.WorkflowManager')
467    grok.title(u'Workflow Manager')
468    grok.permissions('waeup.triggerTransition')
469
470class PortalManager(grok.Role):
471    """The PortalManager role is the maximum set of Kofa permissions
472    which are needed to manage the entire portal. This set must not
473    be customized. It is recommended to assign this role only
474    to a few certified Kofa administrators.
475    A less dangerous manager role is the CCOfficer role described below.
476    For the most tasks the CCOfficer role is sufficient.
477    """
478    grok.name('waeup.PortalManager')
479    grok.title(u'Portal Manager')
480    grok.permissions('waeup.managePortal',
481                     'waeup.manageUsers',
482                     'waeup.viewAcademics', 'waeup.manageAcademics',
483                     'waeup.manageACBatches',
484                     'waeup.manageDataCenter',
485                     'waeup.importData',
486                     'waeup.exportData',
487                     'waeup.viewTranscript',
488                     'waeup.viewDocuments', 'waeup.manageDocuments',
489                     'waeup.managePortalConfiguration', 'waeup.viewApplication',
490                     'waeup.manageApplication', 'waeup.handleApplication',
491                     'waeup.viewApplicantsTab', 'waeup.payApplicant',
492                     'waeup.viewApplicationStatistics',
493                     'waeup.viewStudent', 'waeup.manageStudent',
494                     'waeup.clearStudent', 'waeup.payStudent',
495                     'waeup.uploadStudentFile', 'waeup.showStudents',
496                     'waeup.clearAllStudents',
497                     'waeup.editScores',
498                     'waeup.triggerTransition',
499                     'waeup.viewStudentsContainer',
500                     'waeup.handleAccommodation',
501                     'waeup.viewHostels', 'waeup.manageHostels',
502                     'waeup.editUser',
503                     'waeup.loginAsStudent',
504                     'waeup.handleReports',
505                     'waeup.manageReports',
506                     'waeup.manageJobs',
507                     )
508
509class CCOfficer(grok.Role):
510    """The role of the Computer Center Officer is basically a copy
511    of the the PortalManager role. Some 'dangerous' permissions are excluded
512    by commenting them out (see source code). If officers need to gain more
513    access rights than defined in this role, do not hastily switch to the
514    PortalManager role but add further manager roles instead. Additional
515    roles could be: UsersManager, ACManager, ImportManager, WorkflowManager
516    or StudentImpersonator.
517
518    CCOfficer is a base class which means that this role is subject to
519    customization. It is not used in the ``waeup.kofa`` base package.
520    """
521    grok.baseclass()
522    grok.name('waeup.CCOfficer')
523    grok.title(u'Computer Center Officer')
524    grok.permissions(#'waeup.managePortal',
525                     #'waeup.manageUsers',
526                     'waeup.viewAcademics', 'waeup.manageAcademics',
527                     #'waeup.manageACBatches',
528                     'waeup.manageDataCenter',
529                     #'waeup.importData',
530                     'waeup.exportData',
531                     'waeup.viewTranscript',
532                     'waeup.viewDocuments', 'waeup.manageDocuments',
533                     'waeup.managePortalConfiguration', 'waeup.viewApplication',
534                     'waeup.manageApplication', 'waeup.handleApplication',
535                     'waeup.viewApplicantsTab', 'waeup.payApplicant',
536                     'waeup.viewApplicationStatistics',
537                     'waeup.viewStudent', 'waeup.manageStudent',
538                     'waeup.clearStudent', 'waeup.payStudent',
539                     'waeup.uploadStudentFile', 'waeup.showStudents',
540                     'waeup.clearAllStudents',
541                     'waeup.editScores',
542                     #'waeup.triggerTransition',
543                     'waeup.viewStudentsContainer',
544                     'waeup.handleAccommodation',
545                     'waeup.viewHostels', 'waeup.manageHostels',
546                     #'waeup.editUser',
547                     #'waeup.loginAsStudent',
548                     'waeup.handleReports',
549                     'waeup.manageReports',
550                     #'waeup.manageJobs',
551                     )
552
553def get_all_roles():
554    """Return a list of tuples ``<ROLE-NAME>, <ROLE>``.
555    """
556    return getUtilitiesFor(IRole)
557
558def get_waeup_roles(also_local=False):
559    """Get all Kofa roles.
560
561    Kofa roles are ordinary roles whose id by convention starts with
562    a ``waeup.`` prefix.
563
564    If `also_local` is ``True`` (``False`` by default), also local
565    roles are returned. Local Kofa roles are such whose id starts
566    with ``waeup.local.`` prefix (this is also a convention).
567
568    Returns a generator of the found roles.
569    """
570    for name, item in get_all_roles():
571        if not name.startswith('waeup.'):
572            # Ignore non-Kofa roles...
573            continue
574        if not also_local and name.startswith('waeup.local.'):
575            # Ignore local roles...
576            continue
577        yield item
578
579def get_waeup_role_names():
580    """Get the ids of all Kofa roles.
581
582    See :func:`get_waeup_roles` for what a 'KofaRole' is.
583
584    This function returns a sorted list of Kofa role names.
585    """
586    return sorted([x.id for x in get_waeup_roles()])
587
588class LocalRolesAssignable(grok.Adapter):
589    """Default implementation for `ILocalRolesAssignable`.
590
591    This adapter returns a list for dictionaries for objects for which
592    we want to know the roles assignable to them locally.
593
594    The returned dicts contain a ``name`` and a ``title`` entry which
595    give a role (``name``) and a description, for which kind of users
596    the permission is meant to be used (``title``).
597
598    Having this adapter registered we make sure, that for each normal
599    object we get a valid `ILocalRolesAssignable` adapter.
600
601    Objects that want to offer certain local roles, can do so by
602    setting a (preferably class-) attribute to a list of role ids.
603
604    You can also define different adapters for different contexts to
605    have different role lookup mechanisms become available. But in
606    normal cases it should be sufficient to use this basic adapter.
607    """
608    grok.context(Interface)
609    grok.provides(ILocalRolesAssignable)
610
611    _roles = []
612
613    def __init__(self, context):
614        self.context = context
615        role_ids = getattr(context, 'local_roles', self._roles)
616        self._roles = [(name, role) for name, role in get_all_roles()
617                       if name in role_ids]
618        return
619
620    def __call__(self):
621        """Get a list of dictionaries containing ``names`` (the roles to
622        assign) and ``titles`` (some description of the type of user
623        to assign each role to).
624        """
625        list_of_dict = [dict(
626                name=name,
627                title=role.title,
628                description=role.description)
629                for name, role in self._roles]
630        return sorted(list_of_dict, key=lambda x: x['name'])
631
632def get_all_users():
633    """Get a list of dictionaries.
634    """
635    users = sorted(grok.getSite()['users'].items(), key=lambda x: x[1].title)
636    for key, val in users:
637        yield(dict(name=key, val=val))
638
639def get_users_with_local_roles(context):
640    """Get a list of dicts representing the local roles set for `context`.
641
642    Each dict returns `user_name`, `user_title`, `local_role`,
643    `local_role_title`, and `setting` for each entry in the local
644    roles map of the `context` object.
645    """
646    try:
647        role_map = IPrincipalRoleMap(context)
648    except TypeError:
649        # no map no roles.
650        raise StopIteration
651    for local_role, user_name, setting in role_map.getPrincipalsAndRoles():
652        user = grok.getSite()['users'].get(user_name,None)
653        user_title = getattr(user, 'title', user_name)
654        local_role_title = getattr(
655            dict(get_all_roles()).get(local_role, None), 'title', None)
656        yield dict(user_name = user_name,
657                   user_title = user_title,
658                   local_role = local_role,
659                   local_role_title = local_role_title,
660                   setting = setting)
661
662def get_users_with_role(role, context):
663    """Get a list of dicts representing the usres who have been granted
664    a role for `context`.
665    """
666    try:
667        role_map = IPrincipalRoleMap(context)
668    except TypeError:
669        # no map no roles.
670        raise StopIteration
671    for user_name, setting in role_map.getPrincipalsForRole(role):
672        user = grok.getSite()['users'].get(user_name,None)
673        user_title = getattr(user, 'title', user_name)
674        user_email = getattr(user, 'email', None)
675        yield dict(user_name = user_name,
676                   user_title = user_title,
677                   user_email = user_email,
678                   setting = setting)
Note: See TracBrowser for help on using the repository browser.