[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() <= 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