[Zope-Checkins] CVS: Zope3/lib/python/Zope/App/Security - AttributePrincipalPermissionManager.py:1.1.2.2.2.1 AttributePrincipalRoleManager.py:1.1.2.2.2.1 AttributeRolePermissionManager.py:1.1.2.4.2.2 IPrincipalPermissionManager.py:1.1.2.4.2.1 IPrincipalPermissionMap.py:1.1.2.3.2.1 IPrincipalRoleManager.py:1.1.2.4.2.1 IPrincipalRoleMap.py:1.1.2.4.2.1 IRolePermissionManager.py:1.1.2.4.2.1 IRolePermissionMap.py:1.1.2.5.2.1 PrincipalPermissionManager.py:1.1.2.8.2.1 PrincipalRoleManager.py:1.1.2.5.2.1 RolePermissionManager.py:1.1.2.7.2.1 ZopeSecurityPolicy.py:1.1.2.13.2.4

Casey Duncan casey_duncan@yahoo.com
Mon, 11 Feb 2002 17:03:20 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/App/Security
In directory cvs.zope.org:/tmp/cvs-serv27523

Modified Files:
      Tag: Zope-3x-security_defactor-branch
	AttributePrincipalPermissionManager.py 
	AttributePrincipalRoleManager.py 
	AttributeRolePermissionManager.py 
	IPrincipalPermissionManager.py IPrincipalPermissionMap.py 
	IPrincipalRoleManager.py IPrincipalRoleMap.py 
	IRolePermissionManager.py IRolePermissionMap.py 
	PrincipalPermissionManager.py PrincipalRoleManager.py 
	RolePermissionManager.py ZopeSecurityPolicy.py 
Log Message:
Fixed security behavior on cascades between placeful and global settings for principal permissions and roles. Added tests for this behavior. Fixed permission adapter APIs to reflect the use of ids instead of objects for security settings.


=== Zope3/lib/python/Zope/App/Security/AttributePrincipalPermissionManager.py 1.1.2.2 => 1.1.2.2.2.1 ===
         self._context = context
 
-    def grantPermissionToPrincipal( self, permission, principal ):
+    def grantPermissionToPrincipal( self, permission_id, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
         pp = self._getPrincipalPermissions(create=1)
-        pp.addCell( permission, principal, Allow )
+        pp.addCell( permission_id, principal_id, Allow )
         self._context._p_changed = 1
 
-    def denyPermissionToPrincipal( self, permission, principal ):
+    def denyPermissionToPrincipal( self, permission_id, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
         pp = self._getPrincipalPermissions(create=1)
-        pp.addCell( permission, principal, Deny )
+        pp.addCell( permission_id, principal_id, Deny )
         self._context._p_changed = 1
 
-    def unsetPermissionForPrincipal( self, permission, principal ):
+    def unsetPermissionForPrincipal( self, permission_id, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
         pp = self._getPrincipalPermissions()
         # Only unset if there is a security map, otherwise, we're done
         if pp:
-            pp.delCell( permission, principal )
+            pp.delCell( permission_id, principal_id )
             self._context._p_changed = 1
 
-    def getPrincipalsForPermission( self, permission ):
+    def getPrincipalsForPermission( self, permission_id ):
         ''' See the interface IPrincipalPermissionManager '''
         pp = self._getPrincipalPermissions()
         if pp: 
-            return pp.getRow( permission )
+            return pp.getRow( permission_id )
         return []
 
-    def getPermissionsForPrincipal( self, principal ):
+    def getPermissionsForPrincipal( self, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
         pp = self._getPrincipalPermissions()
         if pp: 
-            return pp.getCol( principal )
+            return pp.getCol( principal_id )
         return []
 
-    def getSetting( self, permission, principal ):
+    def getSetting( self, permission_id, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
         pp = self._getPrincipalPermissions()
         if pp: 
-            return pp.getCell( permission, principal, default=Unset )
+            return pp.getCell( permission_id, principal_id, default=Unset )
         return []
 
     def getPrincipalsAndPermissions( self ):


=== Zope3/lib/python/Zope/App/Security/AttributePrincipalRoleManager.py 1.1.2.2 => 1.1.2.2.2.1 ===
         self._context = context
 
-    def assignRoleToPrincipal( self, role, principal ):
+    def assignRoleToPrincipal( self, role_id, principal_id ):
         ''' See the interface IPrincipalRoleManager '''
         pp = self._getPrincipalRoles(create=1)
-        pp.addCell( role, principal, Assign )
+        pp.addCell( role_id, principal_id, Assign )
         self._context._p_changed = 1
 
-    def removeRoleFromPrincipal( self, role, principal ):
+    def removeRoleFromPrincipal( self, role_id, principal_id ):
         ''' See the interface IPrincipalRoleManager '''
         pp = self._getPrincipalRoles(create=1)
-        pp.addCell( role, principal, Remove )
+        pp.addCell( role_id, principal_id, Remove )
         self._context._p_changed = 1
 
-    def unsetRoleForPrincipal( self, role, principal ):
+    def unsetRoleForPrincipal( self, role_id, principal_id ):
         ''' See the interface IPrincipalRoleManager '''
         pp = self._getPrincipalRoles()
         # Only unset if there is a security map, otherwise, we're done
         if pp:
-            pp.delCell( role, principal )
+            pp.delCell( role_id, principal_id )
             self._context._p_changed = 1
 
-    def getPrincipalsForRole( self, role ):
+    def getPrincipalsForRole( self, role_id ):
         ''' See the interface IPrincipalRoleManager '''
         pp = self._getPrincipalRoles()
         if pp: 
-            return pp.getRow( role )
+            return pp.getRow( role_id )
         return []
 
-    def getRolesForPrincipal( self, principal ):
+    def getRolesForPrincipal( self, principal_id ):
         ''' See the interface IPrincipalRoleManager '''
         pp = self._getPrincipalRoles()
         if pp: 
-            return pp.getCol( principal )
+            return pp.getCol( principal_id )
         return []
 
-    def getSetting( self, role, principal ):
+    def getSetting( self, role_id, principal_id ):
         ''' See the interface IPrincipalRoleManager '''
         pp = self._getPrincipalRoles()
         if pp: 
-            return pp.getCell( role, principal, default=Unset )
+            return pp.getCell( role_id, principal_id, default=Unset )
         return Unset
 
     def getPrincipalsAndRoles( self ):


=== Zope3/lib/python/Zope/App/Security/AttributeRolePermissionManager.py 1.1.2.4.2.1 => 1.1.2.4.2.2 ===
         self._context = context
 
-    def grantPermissionToRole( self, permission, role ):
+    def grantPermissionToRole( self, permission_id, role_id ):
         ''' See the interface IRolePermissionManager '''
         pp = self._getRolePermissions(create=1)
-        pp.addCell( permission, role, Allow )
+        pp.addCell( permission_id, role_id, Allow )
         self._context._p_changed = 1
 
-    def denyPermissionToRole( self, permission, role ):
+    def denyPermissionToRole( self, permission_id, role_id ):
         ''' See the interface IRolePermissionManager '''
         pp = self._getRolePermissions(create=1)
-        pp.addCell( permission, role, Deny )
+        pp.addCell( permission_id, role_id, Deny )
         self._context._p_changed = 1
 
-    def unsetPermissionForRole( self, permission, role ):
+    def unsetPermissionForRole( self, permission_id, role_id ):
         ''' See the interface IRolePermissionManager '''
         pp = self._getRolePermissions()
         # Only unset if there is a security map, otherwise, we're done
         if pp:
-            pp.delCell( permission, role )
+            pp.delCell( permission_id, role_id )
             self._context._p_changed = 1
 
-    def getRolesForPermission( self, permission ):
+    def getRolesForPermission( self, permission_id ):
         '''See interface IRolePermissionMap'''
         pp = self._getRolePermissions()
         if pp:
-            return pp.getRow( permission )
+            return pp.getRow( permission_id )
         else:
             return []
 
-    def getPermissionsForRole( self, role ):
+    def getPermissionsForRole( self, role_id ):
         '''See interface IRolePermissionMap'''
         pp = self._getRolePermissions()
         if pp:
-            return pp.getCol( role )
+            return pp.getCol( role_id )
         else:
             return []
 
@@ -71,15 +71,15 @@
         '''See interface IRolePermissionMap'''
         pp = self._getRolePermissions()
         if pp:
-            return pp.getAllCells( role )
+            return pp.getAllCells( role_id )
         else:
             return []
 
-    def getSetting( self, permission, role ):
+    def getSetting( self, permission_id, role_id ):
         '''See interface IRolePermissionMap'''
         pp = self._getRolePermissions()
         if pp:
-            return pp.getCell( permission, role )
+            return pp.getCell( permission_id, role_id )
         else:
             return Unset
 


=== Zope3/lib/python/Zope/App/Security/IPrincipalPermissionManager.py 1.1.2.4 => 1.1.2.4.2.1 ===
     """Management interface for mappings between principals and permissions."""
 
-    def grantPermissionToPrincipal(permission, principal):
+    def grantPermissionToPrincipal(permission_id, principal_id):
         """Assert that the permission is allowed for the principal.
-
-        permission must be an IPermission
-        principal must be an IPrincipal
         """
 
-    def denyPermissionToPrincipal(permission, principal):
+    def denyPermissionToPrincipal(permission_id, principal_id):
         """Assert that the permission is denied to the principal.
-
-        permission must be an IPermission
-        principal must be an IPrincipal
         """
 
-    def unsetPermissionForPrincipal(permission, principal):
+    def unsetPermissionForPrincipal(permission_id, principal_id):
         """Remove the permission (either denied or allowed) from the
         principal.
-
-        permission must be an IPermission
-        principal must be an IPrincipal
         """


=== Zope3/lib/python/Zope/App/Security/IPrincipalPermissionMap.py 1.1.2.3 => 1.1.2.3.2.1 ===
     """Mappings between principals and permissions."""
 
-    def getPrincipalsForPermission(permission):
-        """Return the list of (principal, setting) tuples that describe
+    def getPrincipalsForPermission(permission_id):
+        """Return the list of (principal_id, setting) tuples that describe
         security assertions for this permission.
 
-        permission must be an IPermission.  If no principals have been
-        set for this permission, then the empty list is returned.
+        If no principals have been set for this permission, then the empty
+        list is returned. 
         """
 
-    def getPermissionsForPrincipal(principal):
+    def getPermissionsForPrincipal(principal_id):
         """Return the list of (permission, setting) tuples that describe
         security assertions for this principal.
 
-        principal must be an IPrincipal.  If no permissions have been set for
-        this principal, then the empty list is returned.  """
+        If no permissions have been set for this principal, then the empty
+        list is returned. 
+        """
         
-    def getSetting(permission, principal):
-        """Get the setting (Allow/Deny/Unset) for a given permission
-        and principal.
-
-        permission must be an IPermission
-        principal must be an IPrincipal
+    def getSetting(permission_id, principal_id): 
+        """Get the setting (Allow/Deny/Unset) for a given permission and
+        principal. 
         """
 
     def getPrincipalsAndPermissions():
         """Get the principal security assertions here in the form
-        of a list of three tuple containing (permission, principal, setting)"""
+        of a list of three tuple containing 
+        (permission id, principal id, setting)
+        """


=== Zope3/lib/python/Zope/App/Security/IPrincipalRoleManager.py 1.1.2.4 => 1.1.2.4.2.1 ===
     """Management interface for mappings between principals and roles."""
 
-    def assignRoleToPrincipal(role, principal):
+    def assignRoleToPrincipal(role_id, principal_id):
         """Assign the role to the principal.
-
-        role must be an IRole
-        principal must be an IPrincipal
         """
 
-    def removeRoleFromPrincipal(role, principal):
+    def removeRoleFromPrincipal(role_id, principal_id):
         """ remove a role from the principal """
 
-    def unsetRoleForPrincipal(role, principal):
+    def unsetRoleForPrincipal(role_id, principal_id):
         """ unset the role for the principal 
-
-        role must be an IRole
-        principal must be an IPrincipal
         """ 


=== Zope3/lib/python/Zope/App/Security/IPrincipalRoleMap.py 1.1.2.4 => 1.1.2.4.2.1 ===
     """Mappings between principals and roles."""
 
-    def getPrincipalsForRole(role):
+    def getPrincipalsForRole(role_id):
         """Return the list of (principal, setting) who have been assigned or 
         removed from a role.
 
-        role must be an IRole.  If no principals have been assigned this role,
+        If no principals have been assigned this role,
         then the empty list is returned.
         """
 
-    def getRolesForPrincipal(principal):
+    def getRolesForPrincipal(principal_id):
         """Return the list of (role, setting) assigned or removed from 
         this principal.
 
-        principal must be an IPrincipal.  If no roles have been assigned to
+        If no roles have been assigned to
         this principal, then the empty list is returned.
         """
 
-    def getSetting(role, principal):
+    def getSetting(role_id, principal_id):
         """Return the setting for this principal, role combination
-
-        principal must be an IPrincipal.  role must be an IRole.
         """
 
     def getPrincipalsAndRoles():
         """Return all the principal/role combinations along with the
-
         setting for each combination.
         """
         


=== Zope3/lib/python/Zope/App/Security/IRolePermissionManager.py 1.1.2.4 => 1.1.2.4.2.1 ===
     """Management interface for mappings between roles and permissions."""
 
-    def grantPermissionToRole(permission, role):
+    def grantPermissionToRole(permission_id, role_id):
         """Bind the permission to the role.
-
-        permission must be an IPermission
-        role must be an IRole
         """
 
-    def denyPermissionToRole(permission, role):
+    def denyPermissionToRole(permission_id, role_id):
         """Deny the permission to the role
-
-        permission must be an IPermission
-        role must be an IRole
         """
 
-    def unsetPermissionFromRole(permission, role):
+    def unsetPermissionFromRole(permission_id, role_id):
         """Clear the setting of the permission to the role.
-
-        permission must be an IPermission
-        role must be an IRole
         """


=== Zope3/lib/python/Zope/App/Security/IRolePermissionMap.py 1.1.2.5 => 1.1.2.5.2.1 ===
     """Mappings between roles and permissions."""
 
-    def getPermissionsForRole(role):
+    def getPermissionsForRole(role_id):
         """Return a sequence of permissions for the given role.
 
-        role must be an IRole.  If no permissions have been granted to this
+        If no permissions have been granted to this
         role, then the empty list is returned.
         """
 
-    def getRolesForPermission(permission):
+    def getRolesForPermission(permission_id):
         """Return a sequence of roles for the given permission.
 
-        permission must be an IPermission.  If no roles have been granted
-        this permission, then the empty list is returned.
+        If no roles have been granted this permission, then the empty list is
+        returned.  
         """
 
-    def getSetting(permission, role):
+    def getSetting(permission_id, role_id):
         """Return a sequence of roles for the given permission.
 
-        permission must be an IPermission.  role must be an IRole.
-        If no roles have been granted this permission, then the empty 
-        list is returned.
+        If no roles have been granted this 
+        permission, then the empty list is returned.  
         """
 
     def getPrincipalsAndRoles():
-        """Return a sequence of (principals, role, setting) here.
+        """Return a sequence of (principal_id, role_id, setting) here.
 
         If no principal/role assertions have been made here, then the empty 
         list is returned.


=== Zope3/lib/python/Zope/App/Security/PrincipalPermissionManager.py 1.1.2.8 => 1.1.2.8.2.1 ===
     __implements__ = IPrincipalPermissionManager
 
-    def grantPermissionToPrincipal( self, permission, principal ):
+    def grantPermissionToPrincipal( self, permission_id, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
-        self.addCell( permission, principal, Allow )
+        self.addCell( permission_id, principal_id, Allow )
 
-    def denyPermissionToPrincipal( self, permission, principal ):
+    def denyPermissionToPrincipal( self, permission_id, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
-        self.addCell( permission, principal, Deny )
+        self.addCell( permission_id, principal_id, Deny )
 
-    def unsetPermissionForPrincipal( self, permission, principal ):
+    def unsetPermissionForPrincipal( self, permission_id, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
-        self.delCell( permission, principal )
+        self.delCell( permission_id, principal_id )
 
-    def getPrincipalsForPermission( self, permission ):
+    def getPrincipalsForPermission( self, permission_id ):
         ''' See the interface IPrincipalPermissionManager '''
-        return self.getRow( permission )
+        return self.getRow( permission_id )
 
-    def getPermissionsForPrincipal( self, principal ):
+    def getPermissionsForPrincipal( self, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
-        return self.getCol( principal )
+        return self.getCol( principal_id )
 
-    def getSetting( self, permission, principal ):
+    def getSetting( self, permission_id, principal_id ):
         ''' See the interface IPrincipalPermissionManager '''
-        return self.getCell( permission, principal, default=Unset )
+        return self.getCell( permission_id, principal_id, default=Unset )
 
     def getPrincipalsAndPermissions( self ):
         ''' See the interface IPrincipalPermissionManager '''


=== Zope3/lib/python/Zope/App/Security/PrincipalRoleManager.py 1.1.2.5 => 1.1.2.5.2.1 ===
     __implements__ = ( IPrincipalRoleManager, IPrincipalRoleMap )
 
-    def assignRoleToPrincipal( self, role, principal ):
+    def assignRoleToPrincipal( self, role_id, principal_id ):
         ''' See the interface IPrincipalRoleManager '''
-        self.addCell( role, principal, Assign )
+        self.addCell( role_id, principal_id, Assign )
 
-    def removeRoleFromPrincipal( self, role, principal ):
+    def removeRoleFromPrincipal( self, role_id, principal_id ):
         ''' See the interface IPrincipalRoleManager '''
-        self.addCell( role, principal, Remove )
+        self.addCell( role_id, principal_id, Remove )
 
-    def unsetRoleForPrincipal( self, role, principal ):
+    def unsetRoleForPrincipal( self, role_id, principal_id ):
         ''' See the interface IPrincipalRoleManager '''
-        self.delCell( role, principal )
+        self.delCell( role_id, principal_id )
 
-    def getPrincipalsForRole( self, role ):
+    def getPrincipalsForRole( self, role_id ):
         ''' See the interface IPrincipalRoleMap '''
-        return self.getRow( role )
+        return self.getRow( role_id )
 
-    def getRolesForPrincipal( self, principal ):
+    def getRolesForPrincipal( self, principal_id ):
         ''' See the interface IPrincipalRoleMap '''
-        return self.getCol( principal )
+        return self.getCol( principal_id )
 
-    def getSetting( self, role, principal ):
+    def getSetting( self, role_id, principal_id ):
         ''' See the interface IPrincipalRoleMap '''
-        return self.getCell( role, principal, default=Unset )
+        return self.getCell( role_id, principal_id, default=Unset )
 
     def getPrincipalsAndRoles( self ):
         ''' See the interface IPrincipalRoleMap '''


=== Zope3/lib/python/Zope/App/Security/RolePermissionManager.py 1.1.2.7 => 1.1.2.7.2.1 ===
     # Zope.App.Security.IRolePermissionManager
 
-    def grantPermissionToRole( self, permission, role ):
+    def grantPermissionToRole( self, permission_id, role_id ):
         '''See interface IRolePermissionMap'''
-        self.addCell( permission, role, Allow )
+        self.addCell( permission_id, role_id, Allow )
 
-    def denyPermissionToRole( self, permission, role ):
+    def denyPermissionToRole( self, permission_id, role_id ):
         '''See interface IRolePermissionMap'''
-        self.addCell( permission, role, Deny )
+        self.addCell( permission_id, role_id, Deny )
 
-    def unsetPermissionForRole( self, permission, role ):
+    def unsetPermissionForRole( self, permission_id, role_id ):
         '''See interface IRolePermissionMap'''
-        self.delCell( permission, role )
+        self.delCell( permission_id, role_id )
 
-    def getRolesForPermission( self, permission ):
+    def getRolesForPermission( self, permission_id ):
         '''See interface IRolePermissionMap'''
-        return self.getRow( permission )
+        return self.getRow( permission_id )
 
-    def getPermissionsForRole( self, role ):
+    def getPermissionsForRole( self, role_id ):
         '''See interface IRolePermissionMap'''
-        return self.getCol( role )
+        return self.getCol( role_id )
 
-    def getSetting( self, permission, role ):
+    def getSetting( self, permission_id, role_id ):
         '''See interface IRolePermissionMap'''
-        return self.getCell( permission, role )
+        return self.getCell( permission_id, role_id )
 
     def getRolesAndPermissions( self ):
         '''See interface IRolePermissionMap'''


=== Zope3/lib/python/Zope/App/Security/ZopeSecurityPolicy.py 1.1.2.13.2.3 => 1.1.2.13.2.4 ===
 from Zope.App.Security.RolePermissionManager import rolePermissionManager 
 from Zope.App.Security.PrincipalRoleManager import principalRoleManager
-from Zope.App.Security.Settings import Allow, Deny, Assign, Remove
+from Zope.App.Security.Settings import Allow, Deny, Assign, Remove, Unset
 
 getPermissionsForPrincipal = principalPermissionManager.getPermissionsForPrincipal
 getPermissionsForRole      = rolePermissionManager.getPermissionsForRole
@@ -90,44 +90,51 @@
 
         principals = { context.user : 1 }
         roles      = {}
-        seen_allowed = 0
+        placeful_setting = None
         all_roles = self._listAllRoles(object, context)
 
         # XXX We aren't really handling multiple principals below
-        for c in ContainmentIterator(object):
-            ppm = getAdapter(c, IPrincipalPermissionManager, None)
-            if ppm is not None: 
-                for principal in principals.keys():
-                    setting = ppm.getSetting(permission, principal)
-                    if setting is Allow:
-                        seen_allowed = 1
-                    elif setting is Deny:
-                        return 0 # Explicit deny on principal
-                if seen_allowed:
-                    return 1 # If I'm allowed here... forget the rest.
-            rpm = getAdapter(c, IRolePermissionManager, None)
-            if rpm is not None:
-                for role in all_roles:
-                    setting = rpm.getSetting(permission, role)
-                    if setting == Allow:
-                        seen_allowed = 1
-                    if setting == Deny:
-                        return 0 # Explicit Deny on role.
-                if seen_allowed:
-                    return 1 # I'm allowed by a role on the principal
+        
+        # Check the placeful permissions settings first
+        try:
+            for c in ContainmentIterator(object):
+                ppm = getAdapter(c, IPrincipalPermissionManager, None)
+                if ppm is not None: 
+                    for principal in principals.keys():
+                        setting = ppm.getSetting(permission, principal)
+                        if setting is Deny:
+                            return 0 # Explicit deny on principal
+                        elif setting is Allow:
+                            return 1 # Explicit allow on principal
+                        
+                rpm = getAdapter(c, IRolePermissionManager, None)
+                if rpm is not None:
+                    for role in all_roles:
+                        placeful_setting = rpm.getSetting(permission, role)
+                        if placeful_setting and \
+                            placeful_setting is not Unset:
+                            raise 'BreakOut' 
+        except 'BreakOut':
+            pass
 
-        # now check the dour interfaces - maybe they've got settings
-        ppm = principalPermissionManager
+        # now check the global principal permissions
+        getSetting = principalPermissionManager.getSetting
         for principal in principals.keys():
-            setting = ppm.getSetting(permission, principal)
+            setting = getSetting(permission, principal)
             if setting is Allow:
-                seen_allowed = 1
+                return 1 # Explicit allow on global principal
             elif setting is Deny:
-                return 0 # Explicit deny on principal
-        if seen_allowed:
-            return 1 # If I'm allowed here... forget the rest.
+                return 0 # Explicit deny on global principal
+
+        # See if the placeful role permission checks yielded an answer
+        if placeful_setting is Allow:
+            return 1 # Allow on placeful role
+        elif placeful_setting is Deny:
+            return 0 # deny on placeful role
 
-        rpm = rolePermissionManager
+        # Last, check if there are any global role settings
+        seen_allowed = 0
+        getSetting = rolePermissionManager.getSetting
         getGlobalRoles = principalRoleManager.getRolesForPrincipal
         for principal in principals.keys():
             # Get the global roles for this principal always checking
@@ -135,14 +142,13 @@
             all_roles = [('Anonymous', Assign)] + getGlobalRoles(principal)
             for role, role_setting in all_roles:
                 if role_setting is Assign:
-                    setting = rpm.getSetting(permission, role)
+                    setting = getSetting(permission, role)
                     if setting == Allow:
                         seen_allowed = 1
-                    if setting == Deny:
-                        return 0 # Explicit Deny on role.
+                    elif setting == Deny:
+                        return 0 # Deny on global role
             if seen_allowed:
-                return 1 # I'm allowed by a role on the principal
-
+                return 1 # Allow on global role
 
         return 0 # Deny by default