[Zope-CVS] CVS: Products/Hotfix-20040807 - __init__.py:1.2

Tres Seaver tseaver at zope.com
Sat Aug 7 19:52:11 EDT 2004


Update of /cvs-repository/Products/Hotfix-20040807
In directory cvs.zope.org:/tmp/cvs-serv18895

Modified Files:
	__init__.py 
Log Message:


  - Fix missing imports (thanks again to Benoit, the original reporter!)

  - Patch CMFCore.PortalFolder._verifyObjectPaste (which has to do
    everything, because of multi-factories).


=== Products/Hotfix-20040807/__init__.py 1.1.1.1 => 1.2 ===
--- Products/Hotfix-20040807/__init__.py:1.1.1.1	Sat Aug  7 14:46:25 2004
+++ Products/Hotfix-20040807/__init__.py	Sat Aug  7 19:52:11 2004
@@ -2,13 +2,29 @@
 
 $Id$
 """
+from cgi import escape
+
+from AccessControl import getSecurityManager
 from AccessControl.Permissions import delete_objects as DeleteObjects
-from OFS.CopySupport import CopyContainer
+from Acquisition import aq_base, aq_inner, aq_parent
+from App.Dialogs import MessageDialog
 from OFS.CopySupport import CopyError
 from OFS.CopySupport import eInvalid
 from OFS.CopySupport import eNoData
 from OFS.CopySupport import eNotFound
 from OFS.CopySupport import eNotSupported
+from OFS.CopySupport import _cb_decode
+from OFS.CopySupport import sanity_check
+from OFS.CopySupport import cookie_path
+from OFS.CopySupport import absattr
+from OFS.Moniker import  loadMoniker
+from zExceptions import Unauthorized
+
+try:
+    from Products.CMFCore.PortalFolder import PortalFolder
+except ImportError:
+    PortalFolder = None
+
 
 def _patched_manage_pasteObjects(self, cb_copy_data=None, REQUEST=None):
     """Paste previously copied objects into the current object.
@@ -35,7 +51,7 @@
     result = []
 
     for mdata in cp[1]:
-        m = Moniker.loadMoniker(mdata)
+        m = loadMoniker(mdata)
         try: ob = m.bind(app)
         except: raise CopyError, eNotFound
         self._verifyObjectPaste(ob, validate_src=op+1)
@@ -105,100 +121,172 @@
                                     cb_dataValid=0)
     return result
 
-def _patched_verifyObjectPaste(self, object, validate_src=1):
-        # Verify whether the current user is allowed to paste the
-        # passed object into self. This is determined by checking
-        # to see if the user could create a new object of the same
-        # meta_type of the object passed in and checking that the
-        # user actually is allowed to access the passed in object
-        # in its existing context.
-        #
-        # Passing a false value for the validate_src argument will skip
-        # checking the passed in object in its existing context. This is
-        # mainly useful for situations where the passed in object has no
-        # existing context, such as checking an object during an import
-        # (the object will not yet have been connected to the acquisition
-        # heirarchy).
+def _patched_CopySupport_verifyObjectPaste(self, object, validate_src=1):
+    # Verify whether the current user is allowed to paste the
+    # passed object into self. This is determined by checking
+    # to see if the user could create a new object of the same
+    # meta_type of the object passed in and checking that the
+    # user actually is allowed to access the passed in object
+    # in its existing context.
+    #
+    # Passing a false value for the validate_src argument will skip
+    # checking the passed in object in its existing context. This is
+    # mainly useful for situations where the passed in object has no
+    # existing context, such as checking an object during an import
+    # (the object will not yet have been connected to the acquisition
+    # heirarchy).
+    if not hasattr(object, 'meta_type'):
+        raise CopyError, MessageDialog(
+                title   = 'Not Supported',
+                message = ('The object <EM>%s</EM> does not support this' \
+                            ' operation' % object_id),
+                action  = 'manage_main')
+
+    if not hasattr(self, 'all_meta_types'):
+        raise CopyError, MessageDialog(
+                title   = 'Not Supported',
+                message = 'Cannot paste into this object.',
+                action  = 'manage_main')
+
+    parent = aq_parent(aq_inner(object))
+    object_id = escape(absattr(object.id))
+    method_name = None
+    mt_permission = None
+    meta_types = absattr(self.all_meta_types)
+
+    for d in meta_types:
+        if d['name'] == object.meta_type:
+            method_name = d['action']
+            mt_permission = d.get('permission')
+            break
+
+    if method_name:
+        try:
+            method = self.restrictedTraverse(method_name)
+            # method_name is e.g.
+            # "manage_addProduct/PageTemplates/manage_addPageTemplateForm".
+            # restrictedTraverse will raise Unauthorized if it
+            # can't obtain the factory method by name due to a
+            # security restriction.  We depend on this side effect
+            # here!  Note that we use restrictedTraverse as
+            # opposed to checkPermission to take into account the
+            # special security circumstances related to proxy
+            # roles.  See collector #78.
+
+        except Unauthorized:
+            if mt_permission:
+                message = ('You do not possess the %s permission in the '
+                            'context of the container into which you are '
+                            'pasting, thus you are not able to perform '
+                            'this operation.' % mt_permission)
+            else:
+                message = ('You do not possess the permission required '
+                            'to call %s in the context of the container '
+                            'into which you are pasting, thus you are not '
+                            'able to perform this operation.' % method_name)
 
-        if not hasattr(object, 'meta_type'):
             raise CopyError, MessageDialog(
-                  title   = 'Not Supported',
-                  message = ('The object <EM>%s</EM> does not support this' \
-                             ' operation' % escape(absattr(object.id))),
-                  action  = 'manage_main')
+                title = 'Insufficient Privileges',
+                message = message,
+                action = 'manage_main')
+
+        if validate_src:
+
+            sm = getSecurityManager()
+
+            # Ensure the user is allowed to access the object on the
+            # clipboard.
+            if not sm.validate(None,parent,None,object):
+                raise Unauthorized, object_id
+
+            if validate_src == 2: # moving
+                if not sm.checkPermission(DeleteObjects, parent):
+                    raise Unauthorized, 'Delete not allowed.'
+
+    else: # /if method_name
+        raise CopyError, MessageDialog(
+                title   = 'Not Supported',
+                message = ('The object <EM>%s</EM> does not support this '
+                            'operation.' % object_id),
+                action  = 'manage_main')
+
+def _patched_PortalFolder_verifyObjectPaste(self, object, validate_src=1):
+
+    # This assists the version in OFS.CopySupport.
+    # It enables the clipboard to function correctly
+    # with objects created by a multi-factory.
+    sm = getSecurityManager()
+    object_id = escape(object.getId())
+    parent = aq_parent(aq_inner(object))
 
-        if not hasattr(self, 'all_meta_types'):
-            raise CopyError, MessageDialog(
-                  title   = 'Not Supported',
-                  message = 'Cannot paste into this object.',
-                  action  = 'manage_main')
+    mt = getattr(object, '__factory_meta_type__', None)
+    meta_types = getattr(self, 'all_meta_types', None)
+
+    if mt is not None and meta_types is not None:
 
         method_name = None
-        mt_permission = None
-        meta_types = absattr(self.all_meta_types)
+        permission_name = None
+
+        if callable(meta_types):
+            meta_types = meta_types()
 
         for d in meta_types:
-            if d['name'] == object.meta_type:
+            if d['name'] == mt:
                 method_name = d['action']
-                mt_permission = d.get('permission')
+                permission_name = d.get('permission', None)
                 break
 
-        if method_name:
+        if permission_name is not None:
+
+            if not sm.checkPermission(permission_name, self):
+                raise Unauthorized, object_id
+
+            if not validate_src:
+               # We don't want to check the object on the clipboard
+               return
+
+            if not sm.validate(None, parent, None, object):
+                raise Unauthorized, object_id
+
+            if validate_src > 1 : # on move
+                if not sm.checkPermission(DeleteObjects, parent) :
+                    raise Unauthorized, object_id
+
+        # Old validation for objects that may not have registered 
+        # themselves in the proper fashion.
+        #
+        elif method_name is not None:
+
+            meth = self.unrestrictedTraverse(method_name)
+
             try:
-                method = self.restrictedTraverse(method_name)
-                # method_name is e.g.
-                # "manage_addProduct/PageTemplates/manage_addPageTemplateForm".
-                # restrictedTraverse will raise Unauthorized if it
-                # can't obtain the factory method by name due to a
-                # security restriction.  We depend on this side effect
-                # here!  Note that we use restrictedTraverse as
-                # opposed to checkPermission to take into account the
-                # special security circumstances related to proxy
-                # roles.  See collector #78.
-
-            except Unauthorized:
-                if mt_permission:
-                    message = ('You do not possess the %s permission in the '
-                               'context of the container into which you are '
-                               'pasting, thus you are not able to perform '
-                               'this operation.' % mt_permission)
-                else:
-                    message = ('You do not possess the permission required '
-                               'to call %s in the context of the container '
-                               'into which you are pasting, thus you are not '
-                               'able to perform this operation.' % method_name)
-
-                raise CopyError, MessageDialog(
-                  title = 'Insufficient Privileges',
-                  message = message,
-                  action = 'manage_main')
-
-            if validate_src:
-
-                sm = getSecurityManager()
-
-                # Ensure the user is allowed to access the object on the
-                # clipboard.
-                try:
-                    parent = aq_parent(aq_inner(object))
-                except:
-                    parent = None
-
-                if not sm.validate(None,parent,None,object):
-                    raise Unauthorized, absattr(object.id)
-
-                if validate_src == 2: # moving
-                    if not sm.checkPermission(DeleteObjects, parent):
-                        raise Unauthorized, 'Delete not allowed.'
+                factory = getattr(meth, 'im_self')
+            except AttributeError:
+                factory = aq_parent(aq_inner(meth))
+
+            if not getSecurityManager().validate(None, factory, None, meth):
+                raise Unauthorized, method_name
+
+            # Ensure the user is allowed to access the object on the
+            # clipboard.
+            if not validate_src:
+                return
+
+            if not sm.validate(None, parent, None, object):
+                raise Unauthorized, object_id
+
+            if validate_src > 1 : # on move
+                if not sm.checkPermission(DeleteObjects, parent) :
+                    raise Unauthorized, object_id
 
-        else: # /if method_name
-            raise CopyError, MessageDialog(
-                  title   = 'Not Supported',
-                  message = ('The object <EM>%s</EM> does not support this '
-                             'operation.' % escape(absattr(object.id))),
-                  action  = 'manage_main')
 
 def initialize(context):
 
+    from OFS.CopySupport import CopyContainer
     CopyContainer.manage_pasteObjects = _patched_manage_pasteObjects
-    CopyContainer._verifyObjectPaste = _patched_verifyObjectPaste
+    CopyContainer._verifyObjectPaste = _patched_CopySupport_verifyObjectPaste
+
+    if PortalFolder is not None:
+
+        PortalFolder._verifyObjectPaste = \
+            _patched_PortalFolder_verifyObjectPaste



More information about the Zope-CVS mailing list