Back to index

plone3  3.1.7
local_role.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # PlonePAS - Adapt PluggableAuthService for use in Plone
00004 # Copyright (C) 2005 Enfold Systems, Kapil Thangavelu, et al
00005 # Portions Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
00006 #
00007 # This software is subject to the provisions of the Zope Public License,
00008 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this
00009 # distribution.
00010 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00011 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00012 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00013 # FOR A PARTICULAR PURPOSE.
00014 #
00015 ##############################################################################
00016 """
00017 
00018 A Local Roles Plugin Implementation that respects Black Listing markers.
00019 
00020 ie. containers/objects which denote that they do not wish to acquire local
00021 roles from their containment structure.
00022 
00023 """
00024 
00025 from sets import Set
00026 from AccessControl import ClassSecurityInfo
00027 from Acquisition import aq_inner, aq_parent
00028 from Globals import DTMLFile, InitializeClass
00029 
00030 from zope.interface import implementedBy
00031 
00032 from Products.PluggableAuthService.utils import classImplements
00033 from Products.PluggableAuthService.plugins.LocalRolePlugin import LocalRolePlugin
00034 from Products.PlonePAS.interfaces.plugins import ILocalRolesPlugin
00035 
00036 def manage_addLocalRolesManager( dispatcher, id, title=None, RESPONSE=None):
00037     """
00038     add a local roles manager
00039     """
00040 
00041     lrm = LocalRolesManager( id, title )
00042     dispatcher._setObject( lrm.getId(), lrm)
00043 
00044     if RESPONSE is not None:
00045         RESPONSE.redirect('manage_workspace')
00046 
00047 manage_addLocalRolesManagerForm = DTMLFile('../zmi/LocalRolesManagerForm', globals())
00048 
00049 class LocalRolesManager(LocalRolePlugin):
00050     """Class incorporating local role storage with
00051     PlonePAS-specific local role permission checking.
00052     """
00053 
00054     meta_type = "Local Roles Manager"
00055     security = ClassSecurityInfo()
00056 
00057     def __init__(self, id, title=None):
00058         self._id = self.id = id
00059         self.title = title
00060 
00061     #security.declarePrivate( 'getRolesInContext' )
00062     def getRolesInContext( self, user, object):
00063         user_id = user.getId()
00064         group_ids = user.getGroups()
00065 
00066         principal_ids = list( group_ids )
00067         principal_ids.insert( 0, user_id )
00068 
00069         local = {}
00070         object = aq_inner( object )
00071 
00072         while 1:
00073             local_roles = getattr( object, '__ac_local_roles__', None )
00074 
00075             if local_roles and callable( local_roles ):
00076                 local_roles = local_roles()
00077             
00078             if local_roles:
00079                 dict = local_roles
00080 
00081                 for principal_id in principal_ids:
00082                     for role in dict.get( principal_id, [] ):
00083                         local[ role ] = 1
00084 
00085             inner = aq_inner( object )
00086             parent = aq_parent( inner )
00087 
00088             if getattr(object, '__ac_local_roles_block__', None):
00089                 break
00090 
00091             if parent is not None:
00092                 object = parent
00093                 continue
00094 
00095             new = getattr( object, 'im_self', None )
00096 
00097             if new is not None:
00098                 object = aq_inner( new )
00099                 continue
00100 
00101             break
00102 
00103         return local.keys()
00104 
00105     #security.declarePrivate( 'checkLocalRolesAllowed' )
00106     def checkLocalRolesAllowed( self, user, object, object_roles ):
00107         # Still have not found a match, so check local roles. We do
00108         # this manually rather than call getRolesInContext so that
00109         # we can incur only the overhead required to find a match.
00110         inner_obj = aq_inner( object )
00111         user_id = user.getId()
00112         # [ x.getId() for x in user.getGroups() ]
00113         group_ids = user.getGroups()
00114 
00115         principal_ids = list( group_ids )
00116         principal_ids.insert( 0, user_id )
00117 
00118         while 1:
00119 
00120             local_roles = getattr( inner_obj, '__ac_local_roles__', None )
00121 
00122             if local_roles and callable( local_roles ):
00123                 local_roles = local_roles()
00124 
00125             if local_roles:
00126                 dict = local_roles
00127 
00128                 for principal_id in principal_ids:
00129                     local_roles = dict.get( principal_id, [] )
00130 
00131                     # local_roles is empty most of the time, where as
00132                     # object_roles is usually not.
00133                     if not local_roles:
00134                         continue
00135 
00136                     for role in object_roles:
00137                         if role in local_roles:
00138                             if user._check_context( object ):
00139                                 return 1
00140                             return 0
00141 
00142             inner = aq_inner( inner_obj )
00143             parent = aq_parent( inner )
00144 
00145             if getattr(inner_obj, '__ac_local_roles_block__', None):
00146                 break
00147 
00148             if parent is not None:
00149                 inner_obj = parent
00150                 continue
00151 
00152             new = getattr( inner_obj, 'im_self', None )
00153 
00154             if new is not None:
00155                 inner_obj = aq_inner( new )
00156                 continue
00157 
00158             break
00159 
00160         return None
00161 
00162     def getAllLocalRolesInContext(self, context):
00163         roles = {}
00164         object = aq_inner( context )
00165 
00166         while True:
00167 
00168             local_roles = getattr(object, '__ac_local_roles__', None)
00169 
00170             if local_roles and callable( local_roles ):
00171                 local_roles = local_roles()
00172 
00173             if local_roles:
00174                     
00175                 dict = local_roles
00176 
00177                 for principal, localroles in dict.items():
00178                     if not principal in roles:
00179                         roles[principal] = Set()
00180 
00181                     roles[principal].update(localroles)
00182 
00183             inner = aq_inner( object )
00184             parent = aq_parent( inner )
00185 
00186             if getattr(object, '__ac_local_roles_block__', None):
00187                 break
00188 
00189             if parent is not None:
00190                 object = parent
00191                 continue
00192 
00193             new = getattr( object, 'im_self', None )
00194 
00195             if new is not None:
00196                 object = aq_inner( new )
00197                 continue
00198 
00199             break
00200 
00201         return roles
00202 
00203 classImplements(LocalRolesManager,
00204                 ILocalRolesPlugin, *implementedBy(LocalRolePlugin))
00205 
00206 InitializeClass(LocalRolesManager)