[Checkins] SVN: Products.DCWorkflow/trunk/Products/DCWorkflow/ - exportimport: Support for instance creation guards and manager

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


Log message for revision 99879:
  - exportimport: Support for instance creation guards and manager
    bypass added.
    (https://bugs.launchpad.net/zope-cmf/+bug/308947)
  

Changed:
  U   Products.DCWorkflow/trunk/Products/DCWorkflow/CHANGES.txt
  U   Products.DCWorkflow/trunk/Products/DCWorkflow/exportimport.py
  U   Products.DCWorkflow/trunk/Products/DCWorkflow/profiles/revision2/workflows/default_workflow/definition.xml
  U   Products.DCWorkflow/trunk/Products/DCWorkflow/tests/test_exportimport.py
  U   Products.DCWorkflow/trunk/Products/DCWorkflow/xml/wtcWorkflowExport.xml

-=-
Modified: Products.DCWorkflow/trunk/Products/DCWorkflow/CHANGES.txt
===================================================================
--- Products.DCWorkflow/trunk/Products/DCWorkflow/CHANGES.txt	2009-05-12 16:12:01 UTC (rev 99878)
+++ Products.DCWorkflow/trunk/Products/DCWorkflow/CHANGES.txt	2009-05-12 16:28:56 UTC (rev 99879)
@@ -4,6 +4,10 @@
 2.2.0 (unreleased)
 ------------------
 
+- exportimport: Support for instance creation guards and manager 
+  bypass added.
+  (https://bugs.launchpad.net/zope-cmf/+bug/308947)
+
 - Cleaned up / normalized imports:
 
   o Don't import from Globals;  instead, use real locations.

Modified: Products.DCWorkflow/trunk/Products/DCWorkflow/exportimport.py
===================================================================
--- Products.DCWorkflow/trunk/Products/DCWorkflow/exportimport.py	2009-05-12 16:12:01 UTC (rev 99878)
+++ Products.DCWorkflow/trunk/Products/DCWorkflow/exportimport.py	2009-05-12 16:28:56 UTC (rev 99879)
@@ -27,6 +27,7 @@
 
 from Products.CMFCore.Expression import Expression
 from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
+from Products.DCWorkflow.Guard import Guard
 from Products.DCWorkflow.interfaces import IDCWorkflowDefinition
 from Products.DCWorkflow.permissions import ManagePortal
 from Products.DCWorkflow.utils import _xmldir
@@ -67,11 +68,15 @@
         , permissions
         , scripts
         , description
+        , manager_bypass
+        , creation_guard
         ) = wfdc.parseWorkflowXML(body, encoding)
 
         _initDCWorkflow( self.context
                        , title
                        , description
+                       , manager_bypass
+                       , creation_guard
                        , state_variable
                        , initial_state
                        , states
@@ -157,6 +162,8 @@
         except ValueError:
             # Don't fail on export files that do not have the description field!
             description = ''
+        manager_bypass = _getNodeAttributeBoolean(root, 'manager_bypass')
+        creation_guard = _extractCreationGuard(root, encoding)
         state_variable = _getNodeAttribute( root, 'state_variable', encoding )
         initial_state = _getNodeAttribute( root, 'initial_state', encoding )
 
@@ -178,6 +185,8 @@
                , permissions
                , scripts
                , description
+               , manager_bypass
+               , creation_guard
                )
 
     security.declarePrivate( '_workflowConfig' )
@@ -197,9 +206,11 @@
 
         o The following keys will be added to 'workflow_info':
 
+          'creation_guard' -- the guard of 'Instance creation conditions'
+
           'permissions' -- a list of names of permissions managed
             by the workflow
-
+            
           'state_variable' -- the name of the workflow's "main"
             state variable
 
@@ -221,6 +232,8 @@
           'script_info' -- a list of mappings describing the scripts which
             provide added business logic (see '_extractScripts').
         """
+        workflow_info[ 'manager_bypass' ] = workflow.manager_bypass
+        workflow_info[ 'creation_guard' ] = self._extractCreationGuard(workflow)
         workflow_info[ 'state_variable' ] = workflow.state_var
         workflow_info[ 'initial_state' ] = workflow.initial_state
         workflow_info[ 'permissions' ] = workflow.permissions
@@ -231,6 +244,20 @@
         workflow_info[ 'worklist_info' ] = self._extractWorklists( workflow )
         workflow_info[ 'script_info' ] = self._extractScripts( workflow )
 
+    security.declarePrivate('_extractCreationGuard')
+    def _extractCreationGuard(self, workflow):
+        """ Return a mapping describing 'Instance creation conditions'
+            if 'creation_guard' is initialized or None
+        """
+        guard = workflow.creation_guard
+        if guard is not None :
+            info = { 'guard_permissions'    : guard.permissions
+                   , 'guard_roles'          : guard.roles
+                   , 'guard_groups'         : guard.groups
+                   , 'guard_expr'           : guard.getExprText()
+                   }
+            return info
+
     security.declarePrivate( '_extractVariables' )
     def _extractVariables( self, workflow ):
 
@@ -621,6 +648,15 @@
 
     return 'workflows/%s/scripts/%s.%s' % ( wf_dir, script_id, suffix )
 
+def _extractCreationGuard(root, encoding=None) :
+    icc = root.getElementsByTagName('instance-creation-conditions')
+    assert len(icc) <= 1
+    if icc :
+        parent = icc[0]
+        return _extractGuardNode(parent, encoding)
+    else :
+        return None
+
 def _extractStateNodes( root, encoding=None ):
 
     result = []
@@ -959,6 +995,8 @@
 def _initDCWorkflow( workflow
                    , title
                    , description
+                   , manager_bypass
+                   , creation_guard
                    , state_variable
                    , initial_state
                    , states
@@ -973,6 +1011,7 @@
     """
     workflow.title = title
     workflow.description = description
+    workflow.manager_bypass = manager_bypass
     workflow.state_var = state_variable
     workflow.initial_state = initial_state
 
@@ -980,6 +1019,7 @@
     permissions.sort()
     workflow.permissions = tuple(permissions)
 
+    _initDCWorkflowCreationGuard( workflow, creation_guard )
     _initDCWorkflowVariables( workflow, variables )
     _initDCWorkflowStates( workflow, states )
     _initDCWorkflowTransitions( workflow, transitions )
@@ -987,6 +1027,21 @@
     _initDCWorkflowScripts( workflow, scripts, context )
 
 
+def _initDCWorkflowCreationGuard( workflow, guard ):
+    """Initialize Instance creation conditions guard
+    """
+    if guard is None :
+        workflow.creation_guard = None
+    else :
+        props = { 'guard_roles' : ';'.join( guard[ 'roles' ] )
+                , 'guard_permissions' : ';'.join( guard[ 'permissions' ] )
+                , 'guard_groups' : ';'.join( guard[ 'groups' ] )
+                , 'guard_expr' : guard[ 'expression' ]
+                }
+        g = Guard()
+        g.changeFromProperties(props)
+        workflow.creation_guard = g
+
 def _initDCWorkflowVariables( workflow, variables ):
 
     """ Initialize DCWorkflow variables

Modified: Products.DCWorkflow/trunk/Products/DCWorkflow/profiles/revision2/workflows/default_workflow/definition.xml
===================================================================
--- Products.DCWorkflow/trunk/Products/DCWorkflow/profiles/revision2/workflows/default_workflow/definition.xml	2009-05-12 16:12:01 UTC (rev 99878)
+++ Products.DCWorkflow/trunk/Products/DCWorkflow/profiles/revision2/workflows/default_workflow/definition.xml	2009-05-12 16:28:56 UTC (rev 99879)
@@ -2,7 +2,8 @@
 <dc-workflow workflow_id="default_workflow"
              title="CMF default workflow [Revision 2]"
              state_variable="review_state"
-             initial_state="visible">
+             initial_state="visible" 
+             manager_bypass="False">
  <permission>Access contents information</permission>
  <permission>Modify portal content</permission>
  <permission>View</permission>

Modified: Products.DCWorkflow/trunk/Products/DCWorkflow/tests/test_exportimport.py
===================================================================
--- Products.DCWorkflow/trunk/Products/DCWorkflow/tests/test_exportimport.py	2009-05-12 16:12:01 UTC (rev 99878)
+++ Products.DCWorkflow/trunk/Products/DCWorkflow/tests/test_exportimport.py	2009-05-12 16:28:56 UTC (rev 99879)
@@ -29,6 +29,7 @@
         import _WorkflowSetup as WorkflowSetupBase
 from Products.CMFCore.testing import DummyWorkflow
 from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
+from Products.DCWorkflow.Guard import Guard
 from Products.DCWorkflow.testing import ExportImportZCMLLayer
 from Products.DCWorkflow.Transitions import TRIGGER_USER_ACTION
 from Products.DCWorkflow.Transitions import TRIGGER_AUTOMATIC
@@ -189,6 +190,12 @@
                 raise ValueError, 'Unknown script type: %s' % v[ 0 ]
 
             dcworkflow.scripts._setObject( k, script )
+    
+    def _initCreationGuard(self, dcworkflow) :
+        props = self._genGuardProps(*_CREATION_GUARD)
+        g = Guard()
+        g.changeFromProperties(props)
+        dcworkflow.creation_guard = g
 
 
 class WorkflowDefinitionConfiguratorTests( _WorkflowSetup, _GuardChecker ):
@@ -465,7 +472,14 @@
                                 , expected[ 2 ] % WF_ID )
             else:
                 self.assertEqual( info[ 'filename' ], expected[ 2 ] )
+    
+    def test_getWorkflowInfo_dcworkflow_creation_guard(self) :
+        WF_ID = 'dcworkflow_creation_guard'
 
+        site = self._initSite()
+        dcworkflow = self._initDCWorkflow( WF_ID )
+        self._initCreationGuard(dcworkflow)
+
     def test_generateXML_empty( self ):
 
         WF_ID = 'empty'
@@ -596,6 +610,8 @@
         , permissions
         , scripts
         , description
+        , manager_bypass
+        , creation_guard
         ) = configurator.parseWorkflowXML( _EMPTY_WORKFLOW_EXPORT
                                          % ( WF_ID
                                            , WF_TITLE
@@ -633,6 +649,8 @@
         , permissions
         , scripts
         , description
+        , manager_bypass
+        , creation_guard
         ) = configurator.parseWorkflowXML(
                           _NORMAL_WORKFLOW_EXPORT
                           % { 'workflow_id' : WF_ID
@@ -670,6 +688,8 @@
         , permissions
         , scripts
         , description
+        , manager_bypass
+        , creation_guard
         ) = configurator.parseWorkflowXML(
                           _NORMAL_WORKFLOW_EXPORT
                           % { 'workflow_id' : WF_ID
@@ -736,6 +756,8 @@
         , permissions
         , scripts
         , description 
+        , manager_bypass
+        , creation_guard
         ) = configurator.parseWorkflowXML(
                           _NORMAL_WORKFLOW_EXPORT
                           % { 'workflow_id' : WF_ID
@@ -805,6 +827,8 @@
         , permissions
         , scripts
         , description
+        , manager_bypass
+        , creation_guard
         ) = configurator.parseWorkflowXML(
                           _NORMAL_WORKFLOW_EXPORT
                           % { 'workflow_id' : WF_ID
@@ -883,6 +907,8 @@
         , permissions
         , scripts
         , description
+        , manager_bypass
+        , creation_guard
         ) = configurator.parseWorkflowXML(
                           _NORMAL_WORKFLOW_EXPORT
                           % { 'workflow_id' : WF_ID
@@ -946,6 +972,8 @@
         , permissions
         , scripts
         , description
+        , manager_bypass
+        , creation_guard
         ) = configurator.parseWorkflowXML(
                           _NORMAL_WORKFLOW_EXPORT
                           % { 'workflow_id' : WF_ID
@@ -983,6 +1011,8 @@
         , permissions
         , scripts
         , description
+        , manager_bypass
+        , creation_guard
         ) = configurator.parseWorkflowXML(
                           _NORMAL_WORKFLOW_EXPORT
                           % { 'workflow_id' : WF_ID
@@ -1251,6 +1281,13 @@
                    )
 }
 
+_CREATION_GUARD = \
+(('Add portal content', 'Manage portal')
+,('Owner', 'Manager')
+,('group_readers', 'group_members')
+,'python:len(here.objectIds() <= 10)'
+)
+
 _NORMAL_TOOL_EXPORT = """\
 <?xml version="1.0"?>
 <object name="portal_workflow" meta_type="Dummy Workflow Tool">
@@ -1293,7 +1330,8 @@
     title="%s"
     description="%s"
     state_variable="state"
-    initial_state="%s">
+    initial_state="%s"
+    manager_bypass="0">
 </dc-workflow>
 """
 
@@ -1305,7 +1343,8 @@
     workflow_id="%(workflow_id)s"
     title="%(title)s"
     state_variable="state"
-    initial_state="%(initial_state)s">
+    initial_state="%(initial_state)s"
+    manager_bypass="0">
  <permission>Open content for modifications</permission>
  <permission>Modify content</permission>
  <permission>Query history</permission>
@@ -1549,7 +1588,8 @@
     title="%(title)s"
     description="%(description)s"
     state_variable="state"
-    initial_state="%(initial_state)s">
+    initial_state="%(initial_state)s"
+    manager_bypass="0">
  <permission>Open content for modifications</permission>
  <permission>Modify content</permission>
  <permission>Query history</permission>
@@ -1791,7 +1831,27 @@
 </dc-workflow>
 """
 
+_CREATION_GUARD_WORKFLOW_EXPORT = """\
+<?xml version="1.0"?>
+<dc-workflow
+    workflow_id="%s"
+    title="%s"
+    description="%s"
+    state_variable="state"
+    initial_state="%s"
+    manager_bypass="1">
+ <instance-creation-conditions>
+  <guard>
+   <guard-permission>Add portal content</guard-permission>
+   <guard-role>Owner</guard-role>
+   <guard-group>group_members</guard-group>
+   <guard-expression>python:len(here.objectIds() &lt;= 10)</guard-expression>
+  </guard>
+ </instance-creation-conditions>
+</dc-workflow>
+"""
 
+
 class Test_exportWorkflow(_WorkflowSetup, _GuardChecker):
 
     layer = ExportImportZCMLLayer

Modified: Products.DCWorkflow/trunk/Products/DCWorkflow/xml/wtcWorkflowExport.xml
===================================================================
--- Products.DCWorkflow/trunk/Products/DCWorkflow/xml/wtcWorkflowExport.xml	2009-05-12 16:12:01 UTC (rev 99878)
+++ Products.DCWorkflow/trunk/Products/DCWorkflow/xml/wtcWorkflowExport.xml	2009-05-12 16:28:56 UTC (rev 99879)
@@ -11,8 +11,29 @@
         tal:attributes="workflow_id info/id;
                         title info/title;
                         description info/description;
+                        manager_bypass info/manager_bypass;
                         state_variable info/state_variable;
                         initial_state info/initial_state">
+ <instance-creation-conditions tal:define="creation_guard info/creation_guard" tal:condition="creation_guard">
+   <guard
+   ><tal:case tal:condition="creation_guard/guard_permissions">
+    <guard-permission
+        tal:repeat="permission creation_guard/guard_permissions"
+        tal:content="permission">PERMISSION</guard-permission></tal:case
+   ><tal:case tal:condition="creation_guard/guard_roles">
+    <guard-role
+        tal:repeat="role creation_guard/guard_roles"
+        tal:content="role">ROLE</guard-role></tal:case
+   ><tal:case tal:condition="creation_guard/guard_groups">
+    <guard-group
+        tal:repeat="group creation_guard/guard_groups"
+        tal:content="group">GROUP</guard-group></tal:case
+   ><tal:case tal:condition="creation_guard/guard_expr">
+    <guard-expression
+        tal:content="creation_guard/guard_expr">EXPRESSION</guard-expression
+   ></tal:case>
+   </guard>
+ </instance-creation-conditions>
  <permission
         tal:repeat="permission info/permissions"
         tal:content="permission">PERMISSION</permission>



More information about the Checkins mailing list