[Erp5-report] r12286 - in /erp5/trunk/products: ERP5/ ERP5Security/ ERP5Security/www/ ERP5T...
nobody at svn.erp5.org
nobody at svn.erp5.org
Wed Jan 24 13:12:29 CET 2007
Author: jerome
Date: Wed Jan 24 13:12:25 2007
New Revision: 12286
URL: http://svn.erp5.org?rev=12286&view=rev
Log:
Move local roles bocking code in a dedicated ERP5User class instead of monkey
patching PropertiedUser. Register an UserFactoryPlugin to return ERP5Users.
ERP5Type/patches/PropertiedUser.py is now useless and will disapear soon. To
update your ERP5 instance, you will have to add an ERP5 User Factory in your
acl_users (using the ZMI)
Added:
erp5/trunk/products/ERP5Security/ERP5UserFactory.py
erp5/trunk/products/ERP5Security/www/ERP5Security_addERP5UserFactory.zpt
Modified:
erp5/trunk/products/ERP5/ERP5Site.py
erp5/trunk/products/ERP5Security/__init__.py
erp5/trunk/products/ERP5Type/Base.py
Modified: erp5/trunk/products/ERP5/ERP5Site.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/ERP5Site.py?rev=12286&r1=12285&r2=12286&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/ERP5Site.py (original)
+++ erp5/trunk/products/ERP5/ERP5Site.py Wed Jan 24 13:12:25 2007
@@ -1278,30 +1278,41 @@
if ERP5Security is not None:
# Use Pluggable Auth Service instead of the standard acl_users.
p.manage_addProduct['PluggableAuthService'].addPluggableAuthService()
+ pas_dispatcher = p.acl_users.manage_addProduct['PluggableAuthService']
# Add legacy ZODB support
- p.acl_users.manage_addProduct['PluggableAuthService'].addZODBUserManager('zodb_users')
- p.acl_users.manage_addProduct['PluggableAuthService'].addZODBGroupManager('zodb_groups')
- p.acl_users.manage_addProduct['PluggableAuthService'].addZODBRoleManager('zodb_roles')
+ pas_dispatcher.addZODBUserManager('zodb_users')
+ pas_dispatcher.addZODBGroupManager('zodb_groups')
+ pas_dispatcher.addZODBRoleManager('zodb_roles')
# Add CMF Portal Roles
#XXX Maybe it will be no longer required once PAS is the standard
p.acl_users.zodb_roles.addRole('Member')
p.acl_users.zodb_roles.addRole('Reviewer')
# Register ZODB Interface
- p.acl_users.zodb_users.manage_activateInterfaces(('IAuthenticationPlugin',
- 'IUserEnumerationPlugin','IUserAdderPlugin'))
- p.acl_users.zodb_groups.manage_activateInterfaces(('IGroupsPlugin',
- 'IGroupEnumerationPlugin'))
- p.acl_users.zodb_roles.manage_activateInterfaces(('IRoleEnumerationPlugin',
- 'IRolesPlugin', 'IRoleAssignerPlugin'))
+ p.acl_users.zodb_users.manage_activateInterfaces(
+ ('IAuthenticationPlugin',
+ 'IUserEnumerationPlugin',
+ 'IUserAdderPlugin'))
+ p.acl_users.zodb_groups.manage_activateInterfaces(
+ ('IGroupsPlugin',
+ 'IGroupEnumerationPlugin'))
+ p.acl_users.zodb_roles.manage_activateInterfaces(
+ ('IRoleEnumerationPlugin',
+ 'IRolesPlugin',
+ 'IRoleAssignerPlugin'))
# Add ERP5UserManager
- p.acl_users.manage_addProduct['ERP5Security'].addERP5UserManager('erp5_users')
- p.acl_users.manage_addProduct['ERP5Security'].addERP5GroupManager('erp5_groups')
- p.acl_users.manage_addProduct['ERP5Security'].addERP5RoleManager('erp5_roles')
+ erp5security_dispatcher = p.acl_users.manage_addProduct['ERP5Security']
+ erp5security_dispatcher.addERP5UserManager('erp5_users')
+ erp5security_dispatcher.addERP5GroupManager('erp5_groups')
+ erp5security_dispatcher.addERP5RoleManager('erp5_roles')
+ erp5security_dispatcher.addERP5UserFactory('erp5_user_factory')
# Register ERP5UserManager Interface
- p.acl_users.erp5_users.manage_activateInterfaces(('IAuthenticationPlugin',
- 'IUserEnumerationPlugin',))
+ p.acl_users.erp5_users.manage_activateInterfaces(
+ ('IAuthenticationPlugin',
+ 'IUserEnumerationPlugin',))
p.acl_users.erp5_groups.manage_activateInterfaces(('IGroupsPlugin',))
p.acl_users.erp5_roles.manage_activateInterfaces(('IRolesPlugin',))
+ p.acl_users.erp5_user_factory.manage_activateInterfaces(
+ ('IUserFactoryPlugin',))
elif withnuxgroups:
# NuxUserGroups user folder
p.manage_addProduct['NuxUserGroups'].addUserFolderWithGroups()
Added: erp5/trunk/products/ERP5Security/ERP5UserFactory.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Security/ERP5UserFactory.py?rev=12286&view=auto
==============================================================================
--- erp5/trunk/products/ERP5Security/ERP5UserFactory.py (added)
+++ erp5/trunk/products/ERP5Security/ERP5UserFactory.py Wed Jan 24 13:12:25 2007
@@ -1,0 +1,204 @@
+##############################################################################
+#
+# Copyright (c) 2001 Zope Corporation and Contributors. All Rights
+# Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this
+# distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Classes: ERP5User, ERP5UserFactory
+"""
+
+from Globals import InitializeClass
+from Acquisition import aq_inner, aq_parent
+from AccessControl import ClassSecurityInfo
+from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+
+from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
+from Products.PluggableAuthService.utils import classImplements
+from Products.PluggableAuthService.interfaces.plugins import IUserFactoryPlugin
+from Products.PluggableAuthService.PropertiedUser import PropertiedUser
+from Products.PluggableAuthService.PropertiedUser import \
+ _what_not_even_god_should_do
+
+manage_addERP5UserFactoryForm = PageTemplateFile(
+ 'www/ERP5Security_addERP5UserFactory', globals(),
+ __name__='manage_addERP5UserFactoryForm' )
+
+def addERP5UserFactory( dispatcher, id, title=None, REQUEST=None ):
+ """ Add a ERP5UserFactory to a Pluggable Auth Service. """
+
+ euf = ERP5UserFactory(id, title)
+ dispatcher._setObject(euf.getId(), euf)
+
+ if REQUEST is not None:
+ REQUEST['RESPONSE'].redirect( '%s/manage_workspace'
+ '?manage_tabs_message='
+ 'ERP5UserFactory+added.'
+ % dispatcher.absolute_url())
+
+
+class ERP5User(PropertiedUser):
+ """ User class that checks the object allows acquisition of local roles the
+ ERP5Type way.
+ """
+
+ def getRolesInContext( self, object ):
+ """ Return the list of roles assigned to the user.
+ For ERP5, we check if a _getAcquireLocalRoles is defined on the object.
+ """
+ user_id = self.getId()
+ # [ x.getId() for x in self.getGroups() ]
+ group_ids = self.getGroups()
+
+ principal_ids = list( group_ids )
+ principal_ids.insert( 0, user_id )
+
+ local ={}
+ object = aq_inner( object )
+
+ while 1:
+ local_roles = getattr( object, '__ac_local_roles__', None )
+ if local_roles:
+ if callable( local_roles ):
+ local_roles = local_roles()
+
+ dict = local_roles or {}
+ for principal_id in principal_ids:
+ for role in dict.get( principal_id, [] ):
+ local[ role ] = 1
+
+ # patch by Klaus for LocalRole blocking
+ if getattr(object, '_getAcquireLocalRoles', None) is not None:
+ if not object._getAcquireLocalRoles():
+ break
+
+ inner = aq_inner( object )
+ parent = aq_parent( inner )
+
+ if parent is not None:
+ object = parent
+ continue
+
+ new = getattr( object, 'im_self', None )
+ if new is not None:
+ object = aq_inner( new )
+ continue
+ break
+
+ return list( self.getRoles() ) + local.keys()
+
+ def allowed( self, object, object_roles=None ):
+ """ Check whether the user has access to object.
+ As for getRolesInContext, we take into account _getAcquireLocalRoles for
+ ERP5.
+ """
+ if object_roles is _what_not_even_god_should_do:
+ return 0
+
+ # Short-circuit the common case of anonymous access.
+ if object_roles is None or 'Anonymous' in object_roles:
+ return 1
+
+ # Provide short-cut access if object is protected by 'Authenticated'
+ # role and user is not nobody
+ if 'Authenticated' in object_roles and (
+ self.getUserName() != 'Anonymous User'):
+ return 1
+
+ # Check for ancient role data up front, convert if found.
+ # This should almost never happen, and should probably be
+ # deprecated at some point.
+ if 'Shared' in object_roles:
+ object_roles = self._shared_roles(object)
+ if object_roles is None or 'Anonymous' in object_roles:
+ return 1
+
+ # Check for a role match with the normal roles given to
+ # the user, then with local roles only if necessary. We
+ # want to avoid as much overhead as possible.
+ user_roles = self.getRoles()
+ for role in object_roles:
+ if role in user_roles:
+ if self._check_context(object):
+ return 1
+ return None
+
+ # Still have not found a match, so check local roles. We do
+ # this manually rather than call getRolesInContext so that
+ # we can incur only the overhead required to find a match.
+ inner_obj = aq_inner( object )
+ user_id = self.getId()
+ # [ x.getId() for x in self.getGroups() ]
+ group_ids = self.getGroups()
+
+ principal_ids = list( group_ids )
+ principal_ids.insert( 0, user_id )
+
+ while 1:
+ local_roles = getattr( inner_obj, '__ac_local_roles__', None )
+ if local_roles:
+ if callable( local_roles ):
+ local_roles = local_roles()
+
+ dict = local_roles or {}
+ for principal_id in principal_ids:
+ local_roles = dict.get( principal_id, [] )
+ for role in object_roles:
+ if role in local_roles:
+ if self._check_context( object ):
+ return 1
+ return 0
+
+ # patch by Klaus for LocalRole blocking
+ if getattr(object, '_getAcquireLocalRoles', None) is not None:
+ if not object._getAcquireLocalRoles():
+ break
+
+ inner = aq_inner( inner_obj )
+ parent = aq_parent( inner )
+
+ if parent is not None:
+ inner_obj = parent
+ continue
+
+ new = getattr( inner_obj, 'im_self', None )
+
+ if new is not None:
+ inner_obj = aq_inner( new )
+ continue
+ break
+
+ return None
+
+InitializeClass(ERP5User)
+
+
+class ERP5UserFactory(BasePlugin):
+ """ PAS plugin for creating users that understand local roles blocking based
+ on type information's acquire_local_roles
+ """
+ meta_type = 'ERP5 User Factory'
+ security = ClassSecurityInfo()
+
+ def __init__(self, id, title=None):
+ self._id = self.id = id
+ self.title = title
+
+ def createUser( self, user_id, name ):
+ """ See IUserFactoryPlugin
+ """
+ return ERP5User(user_id, name)
+
+
+classImplements( ERP5UserFactory
+ , IUserFactoryPlugin
+ )
+
+InitializeClass(ERP5UserFactory)
Modified: erp5/trunk/products/ERP5Security/__init__.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Security/__init__.py?rev=12286&r1=12285&r2=12286&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Security/__init__.py (original)
+++ erp5/trunk/products/ERP5Security/__init__.py Wed Jan 24 13:12:25 2007
@@ -24,6 +24,7 @@
import ERP5UserManager
import ERP5GroupManager
import ERP5RoleManager
+import ERP5UserFactory
def mergedLocalRoles(object):
"""Returns a merging of object and its ancestors'
@@ -59,13 +60,14 @@
registerMultiPlugin(ERP5UserManager.ERP5UserManager.meta_type)
registerMultiPlugin(ERP5GroupManager.ERP5GroupManager.meta_type)
registerMultiPlugin(ERP5RoleManager.ERP5RoleManager.meta_type)
+registerMultiPlugin(ERP5UserFactory.ERP5UserFactory.meta_type)
def initialize(context):
context.registerClass( ERP5UserManager.ERP5UserManager
, permission=ManageUsers
, constructors=(
- ERP5UserManager.manage_addERP5UserManagerForm,
+ ERP5UserManager.manage_addERP5UserManagerForm,
ERP5UserManager.addERP5UserManager, )
, visibility=None
, icon='www/portal.gif'
@@ -74,7 +76,7 @@
context.registerClass( ERP5GroupManager.ERP5GroupManager
, permission=ManageGroups
, constructors=(
- ERP5GroupManager.manage_addERP5GroupManagerForm,
+ ERP5GroupManager.manage_addERP5GroupManagerForm,
ERP5GroupManager.addERP5GroupManager, )
, visibility=None
, icon='www/portal.gif'
@@ -88,3 +90,13 @@
, visibility=None
, icon='www/portal.gif'
)
+
+ context.registerClass( ERP5UserFactory.ERP5UserFactory
+ , permission=ManageUsers
+ , constructors=(
+ ERP5UserFactory.manage_addERP5UserFactoryForm,
+ ERP5UserFactory.addERP5UserFactory, )
+ , visibility=None
+ , icon='www/portal.gif'
+ )
+
Added: erp5/trunk/products/ERP5Security/www/ERP5Security_addERP5UserFactory.zpt
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Security/www/ERP5Security_addERP5UserFactory.zpt?rev=12286&view=auto
==============================================================================
--- erp5/trunk/products/ERP5Security/www/ERP5Security_addERP5UserFactory.zpt (added)
+++ erp5/trunk/products/ERP5Security/www/ERP5Security_addERP5UserFactory.zpt Wed Jan 24 13:12:25 2007
@@ -1,0 +1,45 @@
+<h1 tal:replace="structure here/manage_page_header">Header</h1>
+
+<h2 tal:define="form_title string:Add ERP5 User Factory"
+ tal:replace="structure here/manage_form_title">Form Title</h2>
+
+<p class="form-help">
+ERP5 User Factory creates user objects.
+</p>
+
+<form action="addERP5UserFactory" method="post">
+<table cellspacing="0" cellpadding="2" border="0">
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Id
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="id" size="40" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-optional">
+ Title
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="title" size="40" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ </td>
+ <td align="left" valign="top">
+ <div class="form-element">
+ <input class="form-element" type="submit" name="submit"
+ value=" Add " />
+ </div>
+ </td>
+ </tr>
+</table>
+</form>
+
+<h1 tal:replace="structure here/manage_page_footer">Footer</h1>
Modified: erp5/trunk/products/ERP5Type/Base.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Type/Base.py?rev=12286&r1=12285&r2=12286&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Type/Base.py (original)
+++ erp5/trunk/products/ERP5Type/Base.py Wed Jan 24 13:12:25 2007
@@ -2262,8 +2262,8 @@
Zope objects.
- False means that the role acquisition chain is cut.
- The code to support this is in the user folder, see
- patches/PropertiedUser.py
+ The code to support this is on the user class, see
+ ERP5Security.ERP5UserFactory.ERP5User
"""
def cached_getAcquireLocalRoles(portal_type):
ti = self._getTypesTool().getTypeInfo(self)
More information about the Erp5-report
mailing list