[Erp5-report] r36841 tatuya - /erp5/trunk/products/ERP5/Document/BusinessTemplate.py

nobody at svn.erp5.org nobody at svn.erp5.org
Mon Jul 5 09:05:01 CEST 2010


Author: tatuya
Date: Mon Jul  5 09:04:59 2010
New Revision: 36841

URL: http://svn.erp5.org?rev=36841&view=rev
Log:
Fix a issue that BusinessTemplate unexpectedly removes the skins of another skin folder when upgrading. To fix the issue, (un)restrectedTraverse calling are replaced with the new method, (un)restrictedResolveValue.

Modified:
    erp5/trunk/products/ERP5/Document/BusinessTemplate.py

Modified: erp5/trunk/products/ERP5/Document/BusinessTemplate.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/BusinessTemplate.py?rev=36841&r1=36840&r2=36841&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/BusinessTemplate.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/BusinessTemplate.py [utf8] Mon Jul  5 09:04:59 2010
@@ -32,7 +32,7 @@ from Shared.DC.ZRDB.Connection import Co
 from Products.ERP5Type.DiffUtils import DiffFile
 from Products.ERP5Type.Globals import Persistent, PersistentMapping
 from Acquisition import Implicit, aq_base, aq_inner, aq_parent
-from AccessControl import ClassSecurityInfo
+from AccessControl import ClassSecurityInfo, Unauthorized, getSecurityManager
 from Products.CMFCore.utils import getToolByName
 from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
 from Products.ERP5Type.Base import WorkflowMethod, _aq_reset
@@ -613,6 +613,71 @@ class BaseTemplateItem(Implicit, Persist
     """
     return self.__class__.__name__[:-12]
 
+  def restrictedResolveValue(self, context=None, relative_url=None, default=None):
+    """
+      Get the value with checking the security.
+      This method does not acquire the parent.
+    """
+    def restrictedGetOb(container, key, default):
+      validate = getSecurityManager().validate
+      obj = container._getOb(key, None)
+      if obj is not None:
+        try:
+          if not validate(container, container, key, obj):
+            raise Unauthorized('unauthorized access to element %s' % key)
+        except Unauthorized:
+          # if user can't access object try to return default passed
+          if default is not None:
+            return default
+          else:
+            raise
+      return obj
+    return self._resolveValue(context, relative_url, default, getOb=restrictedGetOb)
+
+  def unrestrictedResolveValue(self, context=None, relative_url=None, default=None):
+    """
+      Get the value without checking the security.
+      This method does not acquire the parent.
+    """
+    def unrestrictedGetOb(container, key, default):
+      return container._getOb(key, None)
+    return self._resolveValue(context, relative_url, default, getOb=unrestrictedGetOb)
+
+  def _resolveValue(self, context, relative_url, default, getOb=None):
+    """
+    Resolve the value without acquire the parent.
+    """
+    if isinstance(relative_url, basestring):
+      stack = relative_url.split('/')
+    else:
+      stack = list(relative_url)
+    stack.reverse()
+    value = None
+    if stack:
+      portal = aq_inner(self.getPortalObject())
+      # It can be passed with the context, so at first, searching from the context.
+      if context is None:
+        container = portal
+      else:
+        container = context
+      key = stack.pop()
+      value = getOb(container, key, default)
+
+      # resolve the value from top to down
+      while value is not None and stack:
+        key = stack.pop()
+        value = value._getOb(key, default)
+    else:
+      # When relative_url is empty, returns the context
+      return context
+
+    if value is None:
+      LOG('BusinessTemplate', WARNING,
+          'Could not access object %s' % relative_url)
+
+    return value
+
+
 class ObjectTemplateItem(BaseTemplateItem):
   """
     This class is used for generic objects and as a subclass.
@@ -933,7 +998,7 @@ class ObjectTemplateItem(BaseTemplateIte
           container_path = path_list[:-1]
           object_id = path_list[-1]
           try:
-            container = portal.unrestrictedTraverse(container_path)
+            container = self.unrestrictedResolveValue(portal, container_path)
           except KeyError:
             # parent object can be set to nothing, in this case just go on
             container_url = '/'.join(container_path)
@@ -1162,7 +1227,7 @@ class ObjectTemplateItem(BaseTemplateIte
         if recursive_path in update_dict:
           action = update_dict[recursive_path]
           if action in ('remove', 'save_and_remove'):
-            document = portal.restrictedTraverse(recursive_path, None)
+            document = self.restrictedResolveValue(portal, recursive_path, None)
             if document is None:
               # It happens if the parent of target path is removed before
               continue
@@ -1212,7 +1277,7 @@ class ObjectTemplateItem(BaseTemplateIte
       container_path = relative_url.split('/')[0:-1]
       object_id = relative_url.split('/')[-1]
       try:
-        container = portal.unrestrictedTraverse(container_path)
+        container = self.unrestrictedResolveValue(portal, container_path)
         object = container._getOb(object_id) # We force access to the object to be sure
                                         # that appropriate exception is thrown
                                         # in case object is already backup and/or removed
@@ -1270,7 +1335,7 @@ class PathTemplateItem(ObjectTemplateIte
         try:
           container_path = relative_url.split('/')[0:-1]
           object_id = relative_url.split('/')[-1]
-          container = portal.unrestrictedTraverse(container_path)
+          container = self.unrestrictedResolveValue(portal, container_path)
           if trash and trashbin is not None:
             self.portal_trash.backupObject(trashbin, container_path,
                                            object_id, save=1,
@@ -1757,7 +1822,7 @@ class WorkflowTemplateItem(ObjectTemplat
           container_path = path.split('/')[:-1]
           object_id = path.split('/')[-1]
           try:
-            container = portal.unrestrictedTraverse(container_path)
+            container = self.unrestrictedResolveValue(portal, container_path)
           except KeyError:
             # parent object can be set to nothing, in this case just go on
             container_url = '/'.join(container_path)




More information about the Erp5-report mailing list