Index: /main/waeup.sirp/trunk/src/waeup/sirp/applicants/securitypolicy.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/applicants/securitypolicy.py	(revision 7155)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/applicants/securitypolicy.py	(revision 7156)
@@ -5,5 +5,5 @@
 ## $Id$
 ## 
-## Copyright (C) 2011 Uli Fouquet
+## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
 ## This program is free software; you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
@@ -34,11 +34,10 @@
 from zope.securitypolicy.settings import Allow, Deny, Unset
 from waeup.sirp.applicants.interfaces import IApplicant
-#from waeup.sirp.students.securitypolicy import StudentPrincipalRoleManager
+from waeup.sirp.students.securitypolicy import StudentPrincipalRoleManager
 
 # All components in here have the same context: Applicant instances
 grok.context(IApplicant)
 
-class ApplicantPrincipalRoleManager(AnnotationPrincipalRoleManager,
-                                    grok.Adapter):
+class ApplicantPrincipalRoleManager(StudentPrincipalRoleManager):
 
     grok.provides(IPrincipalRoleManager)
@@ -53,67 +52,2 @@
     #: Role to add in case one of the above roles was found.
     additional_rolename = 'waeup.ApplicationsOfficer'
-
-    def getRolesForPrincipal(self, principal_id):
-        """Get roles for principal with id `principal_id`.
-
-        Different to the default implementation, this method also
-        takes into account local roles set on any department connected
-        to the context applicant.
-
-        If the given principal has at least one of the
-        `external_rolenames` roles granted for the external object, it
-        additionally gets `additional_rolename` role for the context
-        applicant.
-
-        For the additional roles the `extra_attrib` and all its parent
-        objects are looked up, because 'role inheritance' does not
-        work on that basic level of permission handling.
-
-        Some advantages of this approach:
-
-        - we don't have to store extra local roles for clearance
-          officers in ZODB for each applicant
-
-        - when local roles on a department change, we don't have to
-          update thousands of applicants; the local role is assigned
-          dynamically.
-
-        Disadvantage:
-
-        - More expensive role lookups when a clearance officer wants
-          to see an applicant form.
-
-        This implementation is designed to be usable also for other
-        contexts than applicants. You can inherit from it and set
-        different role names to lookup/set easily via the static class
-        attributes.
-        """
-        apr_manager = AnnotationPrincipalRoleManager(self._context)
-        result = apr_manager.getRolesForPrincipal(principal_id)
-        if result != []:
-            # If there are local roles defined here, no additional
-            # lookup is done.
-            return result
-        # The principal has no local roles yet. Let's lookup the
-        # connected course, dept, etc.
-        if self.subcontainer:
-            obj = getattr(
-                self._context[self.subcontainer], self.extra_attrib, None)
-        else:
-            obj = getattr(self._context, self.extra_attrib, None)
-        # lookup local roles for connected course and all parent
-        # objects. This way we fake 'role inheritance'.
-        while obj is not None:
-            extra_roles = IPrincipalRoleManager(obj).getRolesForPrincipal(
-                principal_id)
-            for role_id, setting in extra_roles:
-                if role_id in self.external_rolenames:
-                    # Found role in external attribute or parent
-                    # thereof. 'Grant' additional role
-                    # permissions (allow, deny or unset) for the
-                    # passed in principal id.
-                    result.append(
-                        (self.additional_rolename, setting))
-                    return result
-            obj = getattr(obj, '__parent__', None)
-        return result
Index: /main/waeup.sirp/trunk/src/waeup/sirp/students/securitypolicy.py
===================================================================
--- /main/waeup.sirp/trunk/src/waeup/sirp/students/securitypolicy.py	(revision 7156)
+++ /main/waeup.sirp/trunk/src/waeup/sirp/students/securitypolicy.py	(revision 7156)
@@ -0,0 +1,113 @@
+## $Id$
+## 
+## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+## 
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+## 
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+"""Security policy components for students.
+
+Students need special security policy treatment, as officers with
+local roles for departments and faculties might have additional
+permissions (local roles on depts/faculties) here.
+"""
+import grok
+from zope.securitypolicy.interfaces import (
+    IPrincipalRoleManager, IPrincipalPermissionManager,)
+from zope.securitypolicy.principalrole import AnnotationPrincipalRoleManager
+from zope.securitypolicy.principalpermission import (
+    AnnotationPrincipalPermissionManager,)
+from zope.securitypolicy.settings import Allow, Deny, Unset
+from waeup.sirp.students.interfaces import IStudent
+
+# All components in here have the same context: Student instances
+grok.context(IStudent)
+
+class StudentPrincipalRoleManager(AnnotationPrincipalRoleManager,
+                                    grok.Adapter):
+    grok.provides(IPrincipalRoleManager)
+
+    #: The attribute name to lookup for additional roles
+    extra_attrib = 'certificate'
+    subcontainer = 'studycourse'
+
+    #: List of role names to look for in `extra_attrib` and parents.
+    external_rolenames = ['waeup.local.ClearanceOfficer',]
+
+    #: Role to add in case one of the above roles was found.
+    additional_rolename = 'waeup.StudentsClearanceOfficer'
+
+    def getRolesForPrincipal(self, principal_id):
+        """Get roles for principal with id `principal_id`.
+
+        Different to the default implementation, this method also
+        takes into account local roles set on any department connected
+        to the context student.
+
+        If the given principal has at least one of the
+        `external_rolenames` roles granted for the external object, it
+        additionally gets `additional_rolename` role for the context
+        student.
+
+        For the additional roles the `extra_attrib` and all its parent
+        objects are looked up, because 'role inheritance' does not
+        work on that basic level of permission handling.
+
+        Some advantages of this approach:
+
+        - we don't have to store extra local roles for clearance
+          officers in ZODB for each student
+
+        - when local roles on a department change, we don't have to
+          update thousands of students; the local role is assigned
+          dynamically.
+
+        Disadvantage:
+
+        - More expensive role lookups when a clearance officer wants
+          to see an student form.
+
+        This implementation is designed to be usable also for other
+        contexts than students. You can inherit from it and set
+        different role names to lookup/set easily via the static class
+        attributes.
+        """
+        apr_manager = AnnotationPrincipalRoleManager(self._context)
+        result = apr_manager.getRolesForPrincipal(principal_id)
+        if result != []:
+            # If there are local roles defined here, no additional
+            # lookup is done.
+            return result
+        # The principal has no local roles yet. Let's lookup the
+        # connected course, dept, etc.
+        if self.subcontainer:
+            obj = getattr(
+                self._context[self.subcontainer], self.extra_attrib, None)
+        else:
+            obj = getattr(self._context, self.extra_attrib, None)
+        # lookup local roles for connected course and all parent
+        # objects. This way we fake 'role inheritance'.
+        while obj is not None:
+            extra_roles = IPrincipalRoleManager(obj).getRolesForPrincipal(
+                principal_id)
+            for role_id, setting in extra_roles:
+                if role_id in self.external_rolenames:
+                    # Found role in external attribute or parent
+                    # thereof. 'Grant' additional role
+                    # permissions (allow, deny or unset) for the
+                    # passed in principal id.
+                    result.append(
+                        (self.additional_rolename, setting))
+                    return result
+            obj = getattr(obj, '__parent__', None)
+        return result
