Commit 06aee0c2 authored by Vincent Pelletier's avatar Vincent Pelletier

CMFActivity.ActivityTool: Use uid for identity check instead of oid.

uids are a way one can signal that different objects (from a ZODB point of
view, and hence an oid point of view) are actually to be considered as the
same objet (from a higher abstration point of view). For example, another
variant of the same object, as imported over an older variant.
In turn, this allows extending the protection to activities spawned from
brains, and not just from live objects.
parent 4c981a55
...@@ -194,13 +194,13 @@ class Message(BaseMessage): ...@@ -194,13 +194,13 @@ class Message(BaseMessage):
exc_type = None exc_type = None
is_executed = MESSAGE_NOT_EXECUTED is_executed = MESSAGE_NOT_EXECUTED
traceback = None traceback = None
oid = None document_uid = None
is_registered = False is_registered = False
def __init__( def __init__(
self, self,
url, url,
oid, document_uid,
active_process, active_process,
active_process_uid, active_process_uid,
activity_kw, activity_kw,
...@@ -210,7 +210,7 @@ class Message(BaseMessage): ...@@ -210,7 +210,7 @@ class Message(BaseMessage):
portal_activities=None, portal_activities=None,
): ):
self.object_path = url self.object_path = url
self.oid = oid self.document_uid = document_uid
self.active_process = active_process self.active_process = active_process
self.active_process_uid = active_process_uid self.active_process_uid = active_process_uid
self.activity_kw = activity_kw self.activity_kw = activity_kw
...@@ -266,10 +266,8 @@ class Message(BaseMessage): ...@@ -266,10 +266,8 @@ class Message(BaseMessage):
% (self.object_path,), error=True) % (self.object_path,), error=True)
self.setExecutionState(MESSAGE_NOT_EXECUTABLE) self.setExecutionState(MESSAGE_NOT_EXECUTABLE)
else: else:
if (self.oid and self.oid != getattr(aq_base(obj), '_p_oid', None) and if self.document_uid and self.document_uid != getattr(aq_base(obj), 'uid', None):
# XXX: BusinessTemplate must be fixed to preserve OID raise ValueError("UID mismatch for %r" % obj)
'portal_workflow' not in self.object_path):
raise ValueError("OID mismatch for %r" % obj)
return obj return obj
def getObjectList(self, activity_tool): def getObjectList(self, activity_tool):
...@@ -506,7 +504,7 @@ class Method(object): ...@@ -506,7 +504,7 @@ class Method(object):
__slots__ = ( __slots__ = (
'_portal_activities', '_portal_activities',
'_passive_url', '_passive_url',
'_passive_oid', '_passive_uid',
'_activity', '_activity',
'_active_process', '_active_process',
'_active_process_uid', '_active_process_uid',
...@@ -515,11 +513,11 @@ class Method(object): ...@@ -515,11 +513,11 @@ class Method(object):
'_request', '_request',
) )
def __init__(self, portal_activities, passive_url, passive_oid, activity, def __init__(self, portal_activities, passive_url, passive_uid, activity,
active_process, active_process_uid, kw, method_id, request): active_process, active_process_uid, kw, method_id, request):
self._portal_activities = portal_activities self._portal_activities = portal_activities
self._passive_url = passive_url self._passive_url = passive_url
self._passive_oid = passive_oid self._passive_uid = passive_uid
self._activity = activity self._activity = activity
self._active_process = active_process self._active_process = active_process
self._active_process_uid = active_process_uid self._active_process_uid = active_process_uid
...@@ -531,7 +529,7 @@ class Method(object): ...@@ -531,7 +529,7 @@ class Method(object):
portal_activities = self._portal_activities portal_activities = self._portal_activities
m = Message( m = Message(
url=self._passive_url, url=self._passive_url,
oid=self._passive_oid, document_uid=self._passive_uid,
active_process=self._active_process, active_process=self._active_process,
active_process_uid=self._active_process_uid, active_process_uid=self._active_process_uid,
activity_kw=self._kw, activity_kw=self._kw,
...@@ -552,7 +550,7 @@ class ActiveWrapper(object): ...@@ -552,7 +550,7 @@ class ActiveWrapper(object):
__slots__ = ( __slots__ = (
'__portal_activities', '__portal_activities',
'__passive_url', '__passive_url',
'__passive_oid', '__passive_uid',
'__activity', '__activity',
'__active_process', '__active_process',
'__active_process_uid', '__active_process_uid',
...@@ -562,12 +560,12 @@ class ActiveWrapper(object): ...@@ -562,12 +560,12 @@ class ActiveWrapper(object):
# Shortcut security lookup (avoid calling __getattr__) # Shortcut security lookup (avoid calling __getattr__)
__parent__ = None __parent__ = None
def __init__(self, portal_activities, url, oid, activity, active_process, def __init__(self, portal_activities, url, uid, activity, active_process,
active_process_uid, kw, request): active_process_uid, kw, request):
# second parameter can be an object or an object's path # second parameter can be an object or an object's path
self.__portal_activities = portal_activities self.__portal_activities = portal_activities
self.__passive_url = url self.__passive_url = url
self.__passive_oid = oid self.__passive_uid = uid
self.__activity = activity self.__activity = activity
self.__active_process = active_process self.__active_process = active_process
self.__active_process_uid = active_process_uid self.__active_process_uid = active_process_uid
...@@ -578,7 +576,7 @@ class ActiveWrapper(object): ...@@ -578,7 +576,7 @@ class ActiveWrapper(object):
return Method( return Method(
self.__portal_activities, self.__portal_activities,
self.__passive_url, self.__passive_url,
self.__passive_oid, self.__passive_uid,
self.__activity, self.__activity,
self.__active_process, self.__active_process,
self.__active_process_uid, self.__active_process_uid,
...@@ -1396,7 +1394,7 @@ class ActivityTool (BaseTool): ...@@ -1396,7 +1394,7 @@ class ActivityTool (BaseTool):
def activateObject(self, object, activity=DEFAULT_ACTIVITY, def activateObject(self, object, activity=DEFAULT_ACTIVITY,
active_process=None, serialization_tag=None, active_process=None, serialization_tag=None,
node=None, **kw): node=None, uid=None, **kw):
if active_process is None: if active_process is None:
active_process_uid = None active_process_uid = None
elif isinstance(active_process, str): elif isinstance(active_process, str):
...@@ -1406,15 +1404,11 @@ class ActivityTool (BaseTool): ...@@ -1406,15 +1404,11 @@ class ActivityTool (BaseTool):
active_process_uid = active_process.getUid() active_process_uid = active_process.getUid()
active_process = active_process.getPhysicalPath() active_process = active_process.getPhysicalPath()
if isinstance(object, str): if isinstance(object, str):
oid = None
url = tuple(object.split('/')) url = tuple(object.split('/'))
else: else:
try: if uid is not None:
oid = aq_base(object)._p_oid raise ValueError
# Note that it's too early to get the OID of a newly created object, uid = getattr(aq_base(object), 'uid', None)
# so at this point, self.oid may still be None.
except AttributeError:
pass
url = object.getPhysicalPath() url = object.getPhysicalPath()
if serialization_tag is not None: if serialization_tag is not None:
kw['serialization_tag'] = serialization_tag kw['serialization_tag'] = serialization_tag
...@@ -1438,7 +1432,7 @@ class ActivityTool (BaseTool): ...@@ -1438,7 +1432,7 @@ class ActivityTool (BaseTool):
except ValueError: except ValueError:
pass pass
break break
return ActiveWrapper(self, url, oid, activity, return ActiveWrapper(self, url, uid, activity,
active_process, active_process_uid, kw, active_process, active_process_uid, kw,
getattr(self, 'REQUEST', None)) getattr(self, 'REQUEST', None))
......
...@@ -2342,7 +2342,7 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor): ...@@ -2342,7 +2342,7 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor):
self.assertEqual(1, activity_tool.countMessage()) self.assertEqual(1, activity_tool.countMessage())
self.flushAllActivities() self.flushAllActivities()
sender, recipients, mail = message_list.pop() sender, recipients, mail = message_list.pop()
self.assertIn('OID mismatch', mail) self.assertIn('UID mismatch', mail)
m, = activity_tool.getMessageList() m, = activity_tool.getMessageList()
self.assertEqual(m.processing_node, INVOKE_ERROR_STATE) self.assertEqual(m.processing_node, INVOKE_ERROR_STATE)
obj.flushActivity() obj.flushActivity()
......
...@@ -498,6 +498,20 @@ class CopyContainer: ...@@ -498,6 +498,20 @@ class CopyContainer:
new_ob.setDefaultReindexParameterDict(reindex_kw) new_ob.setDefaultReindexParameterDict(reindex_kw)
if is_indexable is not None and not is_indexable: if is_indexable is not None and not is_indexable:
new_ob._setNonIndexable() new_ob._setNonIndexable()
if is_clone:
# Clear uids before spawning indexation activities, so the activity does
# not do an uid check (as the uid is still the old one, and a new one
# will be allocated by _postDuplicate, which must run after object gets
# a parent).
# Note: do not use __recurse as it only iterates over immediate content,
# and then stop instead of calling itself into them. It relies on called
# methods to call it back, and we do not want that for _setUid .
todo_list = [new_ob]
while todo_list:
document = todo_list.pop()
todo_list.extend(document.objectValues())
todo_list.extend(document.opaqueValues())
document._setUid(None)
self._setObject(new_id, new_ob, set_owner=set_owner) self._setObject(new_id, new_ob, set_owner=set_owner)
new_ob = self._getOb(new_id) new_ob = self._getOb(new_id)
new_ob._postCopy(self, op=op) new_ob._postCopy(self, op=op)
......
...@@ -137,7 +137,7 @@ class ZSQLBrain(Acquisition.Implicit): ...@@ -137,7 +137,7 @@ class ZSQLBrain(Acquisition.Implicit):
# a queue can be provided as well as extra parameters # a queue can be provided as well as extra parameters
# which can be used for example to define deferred tasks # which can be used for example to define deferred tasks
return activity_tool.activateObject( return activity_tool.activateObject(
self.getPath(), activity, active_process, **new_kw) self.getPath(), activity, active_process, uid=self.getUid(), **new_kw)
allow_class(ZSQLBrain) allow_class(ZSQLBrain)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment