def set_new_proposal_workflow_state(self, proposal): oguid = Oguid.for_object(proposal) row = self.execute(proposals_table.select().where( proposals_table.c.admin_unit_id == oguid.admin_unit_id).where( proposals_table.c.int_id == oguid.int_id)).fetchone() model_state = row.workflow_state state_before = self.wf_tool.getStatusOf(wf_id, proposal) new_state = sql_to_plone_state_mapping[model_state] if new_state == state_before: return # The status is changed the same way as by WorkflowChainUpdater. self.wf_tool.setStatusOf( wf_id, proposal, { 'review_state': new_state, 'action': 'systemupdate', 'actor': 'system', 'comments': '', 'time': DateTime() }) proposal.reindexObject(idxs=['review_state']) # If we switch away from or to `proposal-state-active` we must # reindex security. if (state_before == 'proposal-state-active' or new_state == 'proposal-state-active'): update_security_for(proposal, reindex_security=True)
def update_object(self, proposal): model = proposal.load_model() if model.get_state() == model.STATE_PENDING: update_security_for(proposal, reindex_security=False) else: api.content.transition(obj=proposal, to_state='proposal-state-submitted')
def test_removes_rules_unmanaged_by_workflow(self): self.set_workflow_chain(for_type='Folder', to_workflow='plone_workflow') folder = create(Builder('folder')) self.assert_permission_not_acquired('View', folder) self.assert_permission_not_acquired('Modify portal content', folder) self.assert_permission_acquired('List folder contents', folder) folder.manage_permission('Modify portal content', roles=[], acquire=True) folder.manage_permission('List folder contents', roles=[], acquire=False) self.assert_permission_not_acquired('View', folder) self.assert_permission_acquired('Modify portal content', folder) self.assert_permission_not_acquired('List folder contents', folder) update_security_for(folder) self.assert_permission_not_acquired('View', folder) self.assert_permission_not_acquired('Modify portal content', folder) self.assert_permission_acquired('List folder contents', folder)
def update(self, changed_workflows, reindex_security=True, savepoints=None): types = self.get_suspected_types(changed_workflows) objects = SavepointIterator.build(self.lookup_objects(types), savepoints) for obj in objects: if self.obj_has_workflow(obj, changed_workflows): update_security_for(obj, reindex_security=reindex_security)
def update_workflow_states_with_mapping(self): status_before_activation = self.wfs_and_states_before status_after_activation = self.get_workflows_and_states( self.get_objects()) LOG.info('Changing workflow states of objects which were' ' reset to the initial state according to mapping.') portal = getSite() wf_tool = getToolByName(portal, 'portal_workflow') origin_workflows = list( zip(*list(self.review_state_mapping.keys())))[0] title = 'Change workflow states' for path in ProgressLogger(title, status_before_activation): wf_before = status_before_activation[path].get('workflow') review_state_before = status_before_activation[path].get( 'review_state') wf_after = status_after_activation[path].get('workflow') if wf_before not in origin_workflows: # This object has not a workflow which is in the # mapping, thus no migration is needed. continue mapping = self.review_state_mapping.get((wf_before, wf_after), {}) new_review_state = mapping.get(review_state_before) if not new_review_state: LOG.warn('Mapping not defined for old state %s when changing' ' workflow from %s to %s.' % (review_state_before, wf_before, wf_after)) continue obj = portal.unrestrictedTraverse(path) if self.migrate_workflow_history: self._migrate_workflow_history(obj, wf_before, wf_after) else: wf_tool.setStatusOf( wf_after, obj, { 'review_state': new_review_state, 'action': 'systemupdate', 'actor': 'system', 'comments': '', 'time': DateTime() }) if self.update_security: update_security_for(obj, reindex_security=True) obj.reindexObject(idxs=self.indexes)
def update_workflow_states_with_mapping(self): status_before_activation = self.wfs_and_states_before status_after_activation = self.get_workflows_and_states( self.get_objects()) LOG.info('Changing workflow states of objects which were' ' reset to the initial state according to mapping.') portal = getSite() wf_tool = getToolByName(portal, 'portal_workflow') origin_workflows = zip(*self.review_state_mapping.keys())[0] title = 'Change workflow states' for path in ProgressLogger(title, status_before_activation): wf_before = status_before_activation[path].get('workflow') review_state_before = status_before_activation[path].get( 'review_state') wf_after = status_after_activation[path].get('workflow') if wf_before not in origin_workflows: # This object has not a workflow which is in the # mapping, thus no migration is needed. continue mapping = self.review_state_mapping.get( (wf_before, wf_after), {}) new_review_state = mapping.get(review_state_before) if not new_review_state: LOG.warn( 'Mapping not defined for old state %s when changing' ' workflow from %s to %s.' % ( review_state_before, wf_before, wf_after)) continue obj = portal.unrestrictedTraverse(path) if self.migrate_workflow_history: self._migrate_workflow_history(obj, wf_before, wf_after) else: wf_tool.setStatusOf(wf_after, obj, { 'review_state': new_review_state, 'action': 'systemupdate', 'actor': 'system', 'comments': '', 'time': DateTime()}) if self.update_security: update_security_for(obj, reindex_security=True) obj.reindexObject(idxs=['review_state'])
def test_without_reindexing_security(self): self.set_workflow_chain(for_type='Folder', to_workflow='simple_publication_workflow') folder = create(Builder('folder').in_state('published')) self.assertEquals(['Anonymous'], self.get_allowed_roles_and_users(folder)) folder.manage_permission('View', roles=['Reader'], acquire=False) folder.reindexObjectSecurity() self.assertEquals(['Reader'], self.get_allowed_roles_and_users(folder)) update_security_for(folder, reindex_security=False) self.assertEquals(['Reader'], self.get_allowed_roles_and_users(folder))
def object_moved_or_added(context, event): if isinstance(event, ObjectAddedEvent): # Don't consider moving or removing an object a "touch". Mass-moves # would immediately fill up the touched log, and removals should not # be tracked anyway. if should_track_touches(context): notify(ObjectTouchedEvent(context)) if IObjectRemovedEvent.providedBy(event): return # Update object security after moving or copying. # Specifically, this is needed for the case where an object is moved out # of a location where a Placeful Workflow Policy applies to a location # where it doesn't. # # Plone then no longer provides the placeful workflow for that object, # but doesn't automatically update the object's security. # # We use ftw.upgrade's update_security_for() here to correctly # recalculate security, but do the reindexing ourselves because otherwise # Plone will do it recursively (unnecessarily so). changed = update_security_for(context, reindex_security=False) if changed: catalog = api.portal.get_tool('portal_catalog') catalog.reindexObject(context, idxs=CatalogAware._cmf_security_indexes, update_metadata=0)
def object_moved_or_added(context, event): if isinstance(event, ObjectAddedEvent): # Don't consider moving or removing an object a "touch". Mass-moves # would immediately fill up the touched log, and removals should not # be tracked anyway. if should_track_touches(context): notify(ObjectTouchedEvent(context)) # If an object has been copy & pasted, we need to reindex some fields. # The IObjectCopiedEvent is too early to do that though, because at # that point the object doesn't have a full AQ chain yet. We therefore # just mark it during IObjectCopiedEvent, and do the reindexing here. if getattr(context, '_v_object_has_been_copied', False): context.reindexObject(idxs=reindex_after_copy) if IObjectRemovedEvent.providedBy(event): return # Update object security after moving or copying. # Specifically, this is needed for the case where an object is moved out # of a location where a Placeful Workflow Policy applies to a location # where it doesn't. # # Plone then no longer provides the placeful workflow for that object, # but doesn't automatically update the object's security. # # We use ftw.upgrade's update_security_for() here to correctly # recalculate security, but do the reindexing ourselves because otherwise # Plone will do it recursively (unnecessarily so). changed = update_security_for(context, reindex_security=False) if changed: reindex_object_security_without_children(context) # There are several indices that need updating when a dossier is moved. # first make sure obj was actually moved and not created if not event.oldParent or not event.newParent: return # When an object is moved, its containing_dossier needs reindexing. to_reindex = ['containing_dossier'] # containing_subdossier is really only used for documents, # while is_subdossier is only meaningful for dossiers. if IDossierMarker.providedBy(context): was_subdossier = IDossierMarker.providedBy(event.oldParent) is_subdossier = IDossierMarker.providedBy(event.newParent) if was_subdossier != is_subdossier: to_reindex.append('is_subdossier') if context.portal_type in TYPES_WITH_CONTAINING_SUBDOSSIER_INDEX: to_reindex.append('containing_subdossier') context.reindexObject(idxs=to_reindex) # synchronize with model if necessary if ITask.providedBy(context): sync_task(context, event)
def test_without_reindexing_security(self): self.set_workflow_chain(for_type='Folder', to_workflow='simple_publication_workflow') folder = create(Builder('folder') .in_state('published')) self.assertEquals(['Anonymous'], self.get_allowed_roles_and_users(folder)) folder.manage_permission('View', roles=['Reader'], acquire=False) folder.reindexObjectSecurity() self.assertEquals(['Reader'], self.get_allowed_roles_and_users(folder)) update_security_for(folder, reindex_security=False) self.assertEquals(['Reader'], self.get_allowed_roles_and_users(folder))
def test_reindexes_security_indexes(self): self.set_workflow_chain(for_type='Folder', to_workflow='simple_publication_workflow') folder = create(Builder('folder') .in_state('published')) self.assertEqual(['Anonymous'], self.get_allowed_roles_and_users(folder)) folder.reindexObjectSecurity() folder.manage_permission( ALLOWED_ROLES_AND_USERS_PERMISSION, roles=['Reader'], acquire=False) folder.reindexObjectSecurity() self.assertEqual(['Reader'], self.get_allowed_roles_and_users(folder)) update_security_for(folder) self.assertEqual(['Anonymous'], self.get_allowed_roles_and_users(folder))
def object_moved_or_added(context, event): if isinstance(event, ObjectAddedEvent): # Don't consider moving or removing an object a "touch". Mass-moves # would immediately fill up the touched log, and removals should not # be tracked anyway. if should_track_touches(context): notify(ObjectTouchedEvent(context)) if IObjectRemovedEvent.providedBy(event): return # Update object security after moving or copying. # Specifically, this is needed for the case where an object is moved out # of a location where a Placeful Workflow Policy applies to a location # where it doesn't. # # Plone then no longer provides the placeful workflow for that object, # but doesn't automatically update the object's security. # # We use ftw.upgrade's update_security_for() here to correctly # recalculate security, but do the reindexing ourselves because otherwise # Plone will do it recursively (unnecessarily so). changed = update_security_for(context, reindex_security=False) if changed: reindex_object_security_without_children(context) # There are several indices that need updating when a dossier is moved. # first make sure obj was actually moved and not created if not event.oldParent or not event.newParent: return # When an object is moved, its containing_dossier needs reindexing. to_reindex = ['containing_dossier'] # containing_subdossier is really only used for documents, # while is_subdossier is only meaningful for dossiers. if IDossierMarker.providedBy(context): was_subdossier = IDossierMarker.providedBy(event.oldParent) is_subdossier = IDossierMarker.providedBy(event.newParent) if was_subdossier != is_subdossier: to_reindex.append('is_subdossier') if context.portal_type in TYPES_WITH_CONTAINING_SUBDOSSIER_INDEX: to_reindex.append('containing_subdossier') context.reindexObject(idxs=to_reindex) # synchronize with model if necessary if ITask.providedBy(context): sync_task(context, event)
def object_moved_or_added(context, event): if IObjectRemovedEvent.providedBy(event): return # Update object security after moving or copying. # Specifically, this is needed for the case where an object is moved out # of a location where a Placeful Workflow Policy applies to a location # where it doesn't. # # Plone then no longer provides the placeful workflow for that object, # but doesn't automatically update the object's security. # # We use ftw.upgrade's update_security_for() here to correctly # recalculate security, but do the reindexing ourselves because otherwise # Plone will do it recursively (unnecessarily so). changed = update_security_for(context, reindex_security=False) if changed: catalog = api.portal.get_tool('portal_catalog') catalog.reindexObject(context, idxs=CatalogAware._cmf_security_indexes, update_metadata=0)
def update_documents_and_mails_in_commitee_containers(self): for obj in self.get_documents_and_mails_in_committee_containers(): update_security_for(obj, reindex_security=True)
def update_security(self, old_object, new_object): update_security_for(new_object, reindex_security=False)
def update_security(self, obj, reindex_security=True): """Update the object security and reindex the security indexes in the catalog. """ return update_security_for(obj, reindex_security=reindex_security)
def update(self, changed_workflows, reindex_security=True): types = self.get_suspected_types(changed_workflows) for obj in self.lookup_objects(types): if self.obj_has_workflow(obj, changed_workflows): update_security_for(obj, reindex_security=reindex_security)
def update_security_for_workspace_documents(self): for obj in self.workspace_documents(): update_security_for(obj, reindex_security=True)