source: main/waeup.sirp/trunk/src/waeup/sirp/applicants/securitypolicy.py @ 7142

Last change on this file since 7142 was 7137, checked in by Henrik Bettermann, 13 years ago

Set value Id for property svn:keywords in all Python files.

  • Property svn:keywords set to Id
File size: 4.6 KB
Line 
1##
2## securitypolicy.py
3## Login : <uli@pu.smp.net>
4## Started on  Mon Nov 14 09:37:10 2011 Uli Fouquet
5## $Id: securitypolicy.py 7137 2011-11-19 08:37:08Z henrik $
6##
7## Copyright (C) 2011 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""Security policy components for applicants.
23
24Applicants need special security policy treatment, as officers with
25local roles for departments and faculties might have additional
26permissions (local roles on depts/faculties) here.
27"""
28import grok
29from zope.securitypolicy.interfaces import (
30    IPrincipalRoleManager, IPrincipalPermissionManager,)
31from zope.securitypolicy.principalrole import AnnotationPrincipalRoleManager
32from zope.securitypolicy.principalpermission import (
33    AnnotationPrincipalPermissionManager,)
34from zope.securitypolicy.settings import Allow, Deny, Unset
35from waeup.sirp.applicants.interfaces import IApplicant
36
37# All components in here have the same context: Applicant instances
38grok.context(IApplicant)
39
40class ApplicantPrincipalRoleManager(AnnotationPrincipalRoleManager,
41                                    grok.Adapter):
42    grok.provides(IPrincipalRoleManager)
43
44    #: The attribute name to lookup for additional roles
45    extra_attrib = 'course1'
46
47    #: List of role names to look for in `extra_attrib` and parents.
48    external_rolenames = ['waeup.local.ClearanceOfficer',]
49
50    #: Role to add in case one of the above roles was found.
51    additional_rolename = 'waeup.ApplicationsOfficer'
52
53    def getRolesForPrincipal(self, principal_id):
54        """Get roles for principal with id `principal_id`.
55
56        Different to the default implementation, this method also
57        takes into account local roles set on any department connected
58        to the context applicant.
59
60        If the given principal has at least one of the
61        `external_rolenames` roles granted for the external object, it
62        additionally gets `additional_rolename` role for the context
63        applicant.
64
65        For the additional roles the `extra_attrib` and all its parent
66        objects are looked up, because 'role inheritance' does not
67        work on that basic level of permission handling.
68
69        Some advantages of this approach:
70
71        - we don't have to store extra local roles for clearance
72          officers in ZODB for each applicant
73
74        - when local roles on a department change, we don't have to
75          update thousands of applicants; the local role is assigned
76          dynamically.
77
78        Disadvantage:
79
80        - More expensive role lookups when a clearance officer wants
81          to see an applicant form.
82
83        This implementation is designed to be usable also for other
84        contexts than applicants. You can inherit from it and set
85        different role names to lookup/set easily via the static class
86        attributes.
87        """
88        result = super(ApplicantPrincipalRoleManager, self
89                     ).getRolesForPrincipal(principal_id)
90        if result != []:
91            # If there are local roles defined here, no additional
92            # lookup is done.
93            return result
94        # The principal has no local roles yet. Let's lookup the
95        # connected course, dept, etc.
96        obj = getattr(self._context, self.extra_attrib, None)
97        # lookup local roles for connected course and all parent
98        # objects. This way we fake 'role inheritance'.
99        while obj is not None:
100            extra_roles = IPrincipalRoleManager(obj).getRolesForPrincipal(
101                principal_id)
102            for role_id, setting in extra_roles:
103                if role_id in self.external_rolenames:
104                    # Found role in external attribute or parent
105                    # thereof. 'Grant' additional role
106                    # permissions (allow, deny or unset) for the
107                    # passed in principal id.
108                    result.append(
109                        (self.additional_rolename, setting))
110                    return result
111            obj = getattr(obj, '__parent__', None)
112        return result
Note: See TracBrowser for help on using the repository browser.