[Checkins] SVN: Products.CMFCore/trunk/Products/CMFCore/ - TypeInformation: DCWorkflow instances define a method and a guard

Jens Vagelpohl jens at dataflake.org
Tue May 12 12:12:02 EDT 2009


Log message for revision 99878:
  - TypeInformation: DCWorkflow instances define a method and a guard 
    for vetoing object creation, but it was never used. Now  
    TypeInformation objects will consult these guard conditions during 
    object creation.
    (https://bugs.launchpad.net/zope-cmf/+bug/308947)
  

Changed:
  U   Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
  U   Products.CMFCore/trunk/Products/CMFCore/TypesTool.py
  U   Products.CMFCore/trunk/Products/CMFCore/tests/test_TypesTool.py

-=-
Modified: Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt	2009-05-12 15:21:51 UTC (rev 99877)
+++ Products.CMFCore/trunk/Products/CMFCore/CHANGES.txt	2009-05-12 16:12:01 UTC (rev 99878)
@@ -4,6 +4,12 @@
 2.2.0 (unreleased)
 ------------------
 
+- TypeInformation: DCWorkflow instances define a method and a guard 
+  for vetoing object creation, but it was never used. Now  
+  TypeInformation objects will consult these guard conditions during 
+  object creation.
+  (https://bugs.launchpad.net/zope-cmf/+bug/308947)
+
 - PortalCatalog: Changed to use a multi-adaptor to allow a pluggable
   IndexableObjectWrapper class.  Objects that implement IIndexableObject
   are not wrapped.  The change will assist in integrating with

Modified: Products.CMFCore/trunk/Products/CMFCore/TypesTool.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/TypesTool.py	2009-05-12 15:21:51 UTC (rev 99877)
+++ Products.CMFCore/trunk/Products/CMFCore/TypesTool.py	2009-05-12 16:12:01 UTC (rev 99878)
@@ -52,6 +52,7 @@
 from Products.CMFCore.utils import _checkPermission
 from Products.CMFCore.utils import _dtmldir
 from Products.CMFCore.utils import _wwwdir
+from Products.CMFCore.utils import getToolByName
 from Products.CMFCore.utils import SimpleItemWithProperties
 from Products.CMFCore.utils import UniqueObject
 
@@ -324,7 +325,29 @@
         if isinstance(method_id, tuple):
             method_id = method_id[0]
         return method_id
+    
+    security.declarePrivate('_checkWorkflowAllowed')
+    def _checkWorkflowAllowed(self, container):
+        """ Check if a workflow veto object creation
+        """
+        wtool = getToolByName(self, 'portal_workflow', None)
+        if wtool is None:
+            return True
+        
+        type_id = self.getId()
+        workflows = wtool.getWorkflowsFor(type_id)
+        for workflow in workflows:
+            # DCWorkflow workflows define an instance creation guard
+            guard = getattr(workflow, 'allowCreate', None)
 
+            if guard is None:
+                continue
+
+            if not guard(container, type_id):
+                return False
+        
+        return True        
+
     #
     #   'IAction' interface methods
     #
@@ -459,11 +482,15 @@
 
         c. Does the current user have the permission required in
         order to invoke the factory method?
+        
+        d. Do all workflows authorize the creation?
         """
+        ti_check = False
+
         if self.product:
             # oldstyle factory
             m = self._queryFactoryMethod(container)
-            return (m is not None)
+            ti_check = m is not None
 
         elif container is not None:
             # newstyle factory
@@ -472,9 +499,13 @@
                 for d in container.all_meta_types():
                     if d['name'] == self.content_meta_type:
                         sm = getSecurityManager()
-                        return sm.checkPermission(d['permission'], container)
+                        ti_check = sm.checkPermission(d['permission'], container)
+                        break
 
-        return False
+        if not ti_check:
+            return False
+        else :
+            return self._checkWorkflowAllowed(container)
 
     security.declarePrivate('_constructInstance')
     def _constructInstance(self, container, id, *args, **kw):
@@ -551,7 +582,7 @@
         permission = self.permission
         if permission and not _checkPermission( permission, container ):
             return 0
-        return 1
+        return self._checkWorkflowAllowed(container)
 
     security.declarePrivate('_constructInstance')
     def _constructInstance(self, container, id, *args, **kw):

Modified: Products.CMFCore/trunk/Products/CMFCore/tests/test_TypesTool.py
===================================================================
--- Products.CMFCore/trunk/Products/CMFCore/tests/test_TypesTool.py	2009-05-12 15:21:51 UTC (rev 99877)
+++ Products.CMFCore/trunk/Products/CMFCore/tests/test_TypesTool.py	2009-05-12 16:12:01 UTC (rev 99878)
@@ -40,7 +40,25 @@
         self.ttool = self.site._setObject( 'portal_types', self._makeOne() )
         fti = FTIDATA_DUMMY[0].copy()
         self.ttool._setObject( 'Dummy Content', FTI(**fti) )
+        
+        # setup workflow tool
+        # to test 'Instance creation conditions' of workflows
+        from Products.CMFCore.WorkflowTool import WorkflowTool
+        self.site._setObject( 'portal_workflow', WorkflowTool() )
+        wftool = self.site.portal_workflow
 
+        from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
+        wftool._setObject('wf', DCWorkflowDefinition('wf'))
+        wftool.setDefaultChain('wf')
+        wf = wftool.wf
+        wf.states.addState('initial')
+        wf.states.setInitialState('initial')
+
+        from Products.DCWorkflow.Guard import Guard
+        g = Guard()
+        wf.creation_guard = g
+        
+
     def tearDown(self):
         SecurityTest.tearDown(self)
 
@@ -143,7 +161,22 @@
             self.fail('CMF Collector issue #165 (Ownership bug): '
                       'Unauthorized raised' )
 
+        wf = site.portal_workflow.wf
+        wf.creation_guard.changeFromProperties({'guard_expr':'python:False'})
+        try :
+            ttool.constructContent('Dummy Content', container=f, id='page3')
+        except Unauthorized, e :
+            self.assertEqual(str(e), "Cannot create Dummy Content")
+        else :
+            self.fail("workflow 'Instance creation conditions' does not work")
+        
+        wf.manager_bypass = 1
+        try :
+            ttool.constructContent('Dummy Content', container=f, id='page4')
+        except Unauthorized:
+            self.fail("manager may bypass 'Instance creation conditions'")
 
+
 class TypeInfoTests:
 
     def _makeTypesTool(self):



More information about the Checkins mailing list