[Zope] recursion problem with newer security machinery

Christopher N. Deckard cnd at ecn.purdue.edu
Wed Jan 19 08:50:13 EST 2005


Howdy,
We recently upgraded to 2.6.4, and are now having a problem with our 
custom UserFolder Product.  I've narrowed everything down to a few 
methods, but am at a loss on how to fix it.

In our UserFolder User class, we have overridden getRolesInContext to 
look for a Python Script (we call it an "authorize script"), in parent 
folders of the published object.  It then calls each script to 
programatically add roles at runtime.  This works great with Zope 2.6.2. 
  I have noticed that in Zope 2.6.4 the method Bindings._getContext in 
Shared/DC/Scripts/Bindings.py has new validate code in it.  I believe 
this is what is causing the problem for us.

What is strange is that this is only a problem when using 
ExternalEditor, and when the container of the object we are trying to 
edit contains an "authorize script".  From the ZMI there are no 
problems, and from folders under the folder with the "authorize script" 
there are no problems editing with ExternalEditor.

Any help would be appreciated.  Below is our code, and the two 
_getContext implementations for quicker reference.

Thanks,
-Chris

This is our User.getRolesInContext:

   def getRolesInContext(self, object):
     """Return the list of roles assigned to the user,
        including local roles assigned in context of
        the passed in object."""
     name=self.getUserName()
     roles={}
     additional_roles = self.getRoles()
     local={}
     authorize={}
     object=getattr(object, 'aq_inner', object)

     # Get local roles and roles assigned dynamically from
     # the auth_meth methods
     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 r in dict.get(name, []):
           local[r]=1

       # This adds roles from authorize scripts
       # in all acquisition parents, much like
       # local roles are added

       # Check to make sure that the auth_meth
       # that we are calling is an actual method
       # in the container and not part of the
       # product
       objects = getattr(object, 'objectIds', None)
       if objects:
         if callable(objects):
           if self.folder.auth_meth in object.objectIds():
             authorize_roles = getattr(object,
                                   self.folder.auth_meth, None)
             if authorize_roles:
               if callable(authorize_roles):
                 try:
                 authorize_roles=authorize_roles(directory=self.directory)

                   list=authorize_roles or []
                   for r in list:
                     authorize[r]=1
                 except:
                   pass

       inner = getattr(object, 'aq_inner', object)
       parent = getattr(inner, 'aq_parent', None)
       if parent is not None:
         object = parent
         continue
       if hasattr(object, 'im_self'):
         object=object.im_self
         object=getattr(object, 'aq_inner', object)
         continue
       break

     # Add additional roles
     # the roles object here is different from the
     # BasicUser roles object because it is a list of roles
     # and not a method.  I'm not sure why.
     #
     # Here we add all the roles to the local ditionary
     # and then return the keys of that dictionary as
     # the roles
     for r in additional_roles:
       roles[r] = 1
     for r in local.keys():
       roles[r] = 1
     for r in authorize.keys():
       roles[r] = 1

     roles = roles.keys()
     return roles


Zope 2.6.4 Bindings._getContext:

     def _getContext(self):
         # Utility for bindcode.
         while 1:
             self = self.aq_parent
             if not getattr(self, '_is_wrapperish', None):
                 parent = getattr(self, 'aq_parent', None)
                 inner = getattr(self, 'aq_inner', None)
                 container = getattr(inner, 'aq_parent', None)
                 try: getSecurityManager().validate(parent, container, 
'', self)
                 except Unauthorized:
                     return UnauthorizedBinding('context', self)
                 return self

Zope 2.6.2 Bindings._getContext:

     def _getContext(self):
         # Utility for bindcode.
         while 1:
             self = self.aq_parent
             if not getattr(self, '_is_wrapperish', None):
                 return self

-- 
--------------------------------------------------------------------
     Christopher N. Deckard      |     Lead Web Systems Developer
       cnd at ecn.purdue.edu        |    Engineering Computer Network
   http://eng.purdue.edu/ECN/    |         Purdue University
---- zlib.decompress('x\234K\316Kq((-J)M\325KM)\005\000)"\005w') ---


More information about the Zope mailing list