def test_force_unlock_clears_lock(self, browser): self.login(self.regular_user, browser) with freeze(FREEZE_DATE): oc_url = self.fetch_document_checkout_oc_url( browser, self.document) expected_token = { u'action': u'checkout', u'documents': [u'createtreatydossiers000000000002'], u'exp': 4121033100, u'sub': u'kathi.barfuss', u'url': u'http://nohost/plone/oc_checkout', } raw_token = oc_url.split(':')[-1] token = jwt.decode(raw_token, JWT_SIGNING_SECRET_PLONE, algorithms=('HS256', )) self.assertEqual(expected_token, token) lockable = ILockable(self.document) self.lock_document(browser, raw_token, self.document) self.assertTrue(lockable.locked()) self.login(self.manager, browser) browser.open(self.document) browser.click_on("Unlock") self.assertFalse(lockable.locked())
def remove_spacesobject_fromsite(portal,logger): from plone.app.linkintegrity.interfaces import ILinkIntegrityNotificationException portal_properties=getToolByName(portal, 'portal_properties') is_link_integrity = portal_properties.site_properties.enable_link_integrity_checks if is_link_integrity: portal_properties.site_properties.manage_changeProperties(enable_link_integrity_checks=False) spaces = None try: spaces = getToolByName(portal,'spaces') if spaces.portal_type != 'SpacesFolder': spaces = None except AttributeError: pass spacesid = 'spaces' try: if spaces <> None: if callable(spaces.id): o_id = spaces.id() else: o_id = spaces.id spacesid = o_id from plone.locking.interfaces import ILockable lockable = ILockable(spaces) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() portal.manage_delObjects(ids=[o_id]) logger.info("Deleted spaces object from site.") transaction.savepoint() except ILinkIntegrityNotificationException: pass recyclebin = getToolByName(portal,'recyclebin') if recyclebin <> None: try: objspaces = getattr(portal,spacesid) if objspaces.portal_type == 'SpacesFolder': from plone.locking.interfaces import ILockable lockable = ILockable(objspaces) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() recyclebin.manage_delObjects(ids=[spacesid]) logger.info("Deleting spaces object from global recyclebin.") except AttributeError: pass if is_link_integrity: portal_properties.site_properties.manage_changeProperties(enable_link_integrity_checks=True)
def test_clear_locks_remove_all_locks_on_the_object(self): lockable = ILockable(self.wrapper) lockable.lock() self.assertTrue(lockable.locked()) lockable.clear_locks() self.assertFalse(lockable.locked())
def test_atct_not_lockable(self): portal = self.layer['portal'] setRoles(portal, TEST_USER_ID, ['Contributor']) portal.invokeFactory('Document', 'adoc', title='A title', description='Some description', text='Some text') doc = portal['adoc'] lockable = ILockable(doc) self.assertEqual(False, lockable.locked()) lockable.lock() self.assertEqual(False, lockable.locked())
def test_atct_not_lockable(self): portal = self.layer['portal'] setRoles(portal, TEST_USER_ID, ['Contributor']) portal.invokeFactory('Document', 'adoc', title='A title', description='Some description', text='Some text') doc = portal['adoc'] lockable = ILockable(doc) self.assertEqual(False, lockable.locked()) lockable.lock() self.assertEqual(False, lockable.locked())
def test_force_unlock_clears_lock(self, browser): self.login(self.regular_user, browser) oc_url = self.fetch_document_checkout_oc_url(browser, self.document) tokens = self.validate_checkout_token(self.regular_user, oc_url, self.document) lockable = ILockable(self.document) self.lock_document(browser, tokens, self.document) self.assertTrue(lockable.locked()) self.login(self.manager, browser) browser.open(self.document) browser.click_on("Unlock") self.assertFalse(lockable.locked())
def test_decide_agenda_item_creates_locked_excerpt_in_dossier(self, browser): self.setup_excerpt_template() proposal = self.setup_proposal() # schedule view = 'unscheduled_proposals/{}/schedule'.format( proposal.load_model().proposal_id) browser.login().open(self.meeting_wrapper, view=view) agenda_item = AgendaItem.query.first() browser.login().open( self.meeting_wrapper, view='agenda_items/{}/decide'.format(agenda_item.agenda_item_id), data={'_authenticator': createToken()}) agenda_item = AgendaItem.query.first() # refresh proposal = agenda_item.proposal excerpt_in_dossier = proposal.excerpt_document.resolve_document() lockable = ILockable(excerpt_in_dossier) self.assertTrue(lockable.locked()) self.assertTrue(lockable.can_safely_unlock(MEETING_EXCERPT_LOCK)) browser.open(excerpt_in_dossier) self.assertEqual(u'This document is a copy of the excerpt Fooo - ' u'C\xf6mmunity meeting from the meeting C\xf6mmunity ' u'meeting and cannot be edited directly.', info_messages()[0]) message_links = browser.css('.portalMessage.info a') self.assertEqual( 'http://nohost/plone/opengever-meeting-committeecontainer/committee-1/submitted-proposal-1/document-3', message_links[0].get('href')) self.assertEqual( 'http://nohost/plone/opengever-meeting-committeecontainer/committee-1/meeting-1/view', message_links[1].get('href'))
def handleCancelCheckout(event): lockable = ILockable(event.object) if lockable.locked(): # unlock working copy if it was auto-locked, or this will fail lockable.clear_locks() lock.unlockContext(event.baseline) event.baseline.reindexObject(idxs=['review_state'])
def handleCancelCheckout(event): lockable = ILockable(event.object) if lockable.locked(): # unlock working copy if it was auto-locked, or this will fail lockable.clear_locks() lock.unlockContext(event.baseline) event.baseline.reindexObject(idxs=['review_state'])
def delete_unwanted_objects_from_memberfolder(portal,memberfolder,logger): ct = getToolByName(portal,'portal_catalog') strURL = "/".join(memberfolder.getPhysicalPath()) query = {'path':{'query':strURL},'portal_type':('Space','RecycleBin')} objMemSpaces = [b.getObject() for b in ct(query)] for o in objMemSpaces: if callable(o.id): o_id = o.id() else: o_id = o.id try: from plone.locking.interfaces import ILockable lockable = ILockable(o) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() parentItem = o.getParentNode() parentItem.manage_delObjects(ids=[o_id]) transaction.savepoint() except ComponentLookupError: pass logger.info("Deleted %s object from %s member folder." % (o_id, memberfolder.getId(),)) transaction.savepoint()
def test_submit_additional_document_creates_new_locked_document(self): committee = create(Builder('committee').titled('My committee')) document = create(Builder('document') .within(self.dossier) .titled(u'A Document') .with_dummy_content()) proposal = create(Builder('proposal') .within(self.dossier) .titled(u'My Proposal') .as_submitted() .having(committee=committee.load_model())) proposal.submit_additional_document(document) submitted_proposal = api.portal.get().restrictedTraverse( proposal.load_model().submitted_physical_path.encode('utf-8')) docs = submitted_proposal.listFolderContents() self.assertEqual(1, len(docs)) submitted_document = docs.pop() self.assertEqual(document.Title(), submitted_document.Title()) self.assertEqual(document.file.filename, submitted_document.file.filename) # submitted document should be locked by custom lock lockable = ILockable(submitted_document) self.assertTrue(lockable.locked()) self.assertTrue(lockable.can_safely_unlock(MEETING_SUBMITTED_LOCK)) self.assertSubmittedDocumentCreated(proposal, document, submitted_document)
def migrate(self, unittest=0): """Migrates the object """ beforeChange, afterChange = self.getMigrationMethods() # Unlock according to plone.locking: lockable = ILockable(self.old, None) if lockable and lockable.locked(): lockable.unlock() # Unlock according to webdav: if self.old.wl_isLocked(): self.old.wl_clearLocks() for method in beforeChange: __traceback_info__ = (self, method, self.old, self.orig_id) # may raise an exception, catch it later method() # preserve position on rename self.need_order = IOrderedContainer.providedBy(self.parent) if self.need_order: self._position = self.parent.getObjectPosition(self.orig_id) self.renameOld() self.createNew() for method in afterChange: __traceback_info__ = (self, method, self.old, self.orig_id) # may raise an exception, catch it later method() self.reorder() self.remove()
def test_decide_agenda_item_creates_locked_excerpt_in_dossier( self, browser): self.setup_excerpt_template() proposal = self.setup_proposal() # schedule view = 'unscheduled_proposals/{}/schedule'.format( proposal.load_model().proposal_id) browser.login().open(self.meeting_wrapper, view=view) agenda_item = AgendaItem.query.first() browser.login().open(self.meeting_wrapper, view='agenda_items/{}/decide'.format( agenda_item.agenda_item_id), data={'_authenticator': createToken()}) agenda_item = AgendaItem.query.first() # refresh proposal = agenda_item.proposal excerpt_in_dossier = proposal.excerpt_document.resolve_document() lockable = ILockable(excerpt_in_dossier) self.assertTrue(lockable.locked()) self.assertTrue(lockable.can_safely_unlock(MEETING_EXCERPT_LOCK)) browser.open(excerpt_in_dossier) self.assertEqual( u'This document is a copy of the excerpt Fooo - ' u'C\xf6mmunity meeting from the meeting C\xf6mmunity ' u'meeting and cannot be edited directly.', info_messages()[0]) message_links = browser.css('.portalMessage.info a') self.assertEqual( 'http://nohost/plone/opengever-meeting-committeecontainer/committee-1/submitted-proposal-1/document-3', message_links[0].get('href')) self.assertEqual( 'http://nohost/plone/opengever-meeting-committeecontainer/committee-1/meeting-1/view', message_links[1].get('href'))
def test_submit_additional_document_creates_new_locked_document(self): committee = create(Builder('committee').titled('My committee')) document = create(Builder('document') .within(self.dossier) .titled(u'A Document') .with_dummy_content()) proposal = create(Builder('proposal') .within(self.dossier) .titled(u'My Proposal') .as_submitted() .having(committee=committee.load_model())) proposal.submit_additional_document(document) submitted_proposal = api.portal.get().restrictedTraverse( proposal.load_model().submitted_physical_path.encode('utf-8')) docs = submitted_proposal.listFolderContents() self.assertEqual(1, len(docs)) submitted_document = docs.pop() self.assertEqual(document.Title(), submitted_document.Title()) self.assertEqual(document.file.filename, submitted_document.file.filename) # submitted document should be locked by custom lock lockable = ILockable(submitted_document) self.assertTrue(lockable.locked()) self.assertTrue(lockable.can_safely_unlock(MEETING_SUBMITTED_LOCK)) self.assertSubmittedDocumentCreated(proposal, document, submitted_document)
def test_locked_is_false_if_lock_is_invalid(self): create(Builder('lock') .of_obj(self.wrapper) .having(time=utcnow_tz_aware() - timedelta(seconds=800))) lockable = ILockable(self.wrapper) self.assertFalse(lockable.locked())
def _set_id(self, value): """ """ context = aq_inner(self.context) parent = aq_parent(context) if not value: # plone.dexterity.fti.DexterityFTI factory_info = context.getTypeInfo() new_id = generate_content_id(factory_info.getId()) # else add prefix/suffix with user provided value? else: new_id = value if parent is None: # Object hasn't been added to graph yet; just set directly context.id = value return if getattr(aq_base(context), 'id', None): transaction.savepoint() locked = False lockable = ILockable(context, None) if lockable is not None and lockable.locked(): locked = True lockable.unlock() parent.manage_renameObject(context.getId(), new_id) if locked: lockable.lock() else: context.id = new_id
def migrate(self, unittest=0): """Migrates the object """ beforeChange, afterChange = self.getMigrationMethods() lockable = ILockable(self.old, None) if lockable and lockable.locked(): lockable.unlock() for method in beforeChange: __traceback_info__ = (self, method, self.old, self.orig_id) # may raise an exception, catch it later method() # preserve position on rename self.need_order = IOrderedContainer.providedBy(self.parent) if self.need_order: self._position = self.parent.getObjectPosition(self.orig_id) self.renameOld() self.createNew() for method in afterChange: __traceback_info__ = (self, method, self.old, self.orig_id) # may raise an exception, catch it later method() self.reorder() self.remove()
def test_unlock_object(self): lockable = ILockable(self.doc) lockable.lock() transaction.commit() response = self.api_session.delete("/@lock") transaction.commit() self.assertEqual(response.status_code, 200) self.assertFalse(lockable.locked())
def test_unlock_does_not_check_if_lock_is_stealable_when_stealable_only_is_false(self): lockable = ILockable(self.wrapper) lockable.lock() # manually change lock creator lock = Lock.query.first() lock.creator = 'other-user' lockable.unlock() self.assertFalse(lockable.locked())
def unlockPerson(self): obj = self.context.aq_inner try: from plone.locking.interfaces import ILockable HAS_LOCKING = True except ImportError: HAS_LOCKING = False if HAS_LOCKING: lockable = ILockable(obj) if lockable.locked(): lockable.unlock() return self.render()
def test_protocol_document_is_unlocked_when_meeting_is_closed(self, browser): self.setup_generated_protocol(browser) browser.find('Close meeting').click() browser.open(self.meeting.get_url()) browser.find('Protocol-My meeting').click() document = browser.context lockable = ILockable(document) self.assertFalse(lockable.locked())
def unlockPerson(self): obj = self.context.aq_inner try: from plone.locking.interfaces import ILockable HAS_LOCKING = True except ImportError: HAS_LOCKING = False if HAS_LOCKING: lockable = ILockable(obj) if lockable.locked(): lockable.unlock() return self.render()
def test_protocol_document_is_locked_by_system_once_generated(self, browser): self.setup_generated_protocol(browser) browser.find('Protocol-My meeting').click() document = browser.context lockable = ILockable(document) self.assertTrue(lockable.locked()) self.assertTrue(lockable.can_safely_unlock(SYS_LOCK)) self.assertFalse(lockable.can_safely_unlock(STEALABLE_LOCK)) lock_info = lockable.lock_info()[0] self.assertEqual(u'sys.lock', lock_info['type'].__name__)
def action(self, obj): parent = obj.aq_inner.aq_parent lockable = ILockable(obj, None) if lockable and lockable.locked(): lockable.clear_locks() try: parent.manage_delObjects(obj.getId(), self.request) except Unauthorized: self.errors.append( _(u'You are not authorized to delete ${title}.', mapping={u'title': self.objectTitle(self.dest)}))
def test_protocol_document_is_unlocked_when_meeting_is_closed( self, browser): self.setup_generated_protocol(browser) browser.find('Close meeting').click() browser.open(self.meeting.get_url()) browser.find('Protocol-My meeting').click() document = browser.context lockable = ILockable(document) self.assertFalse(lockable.locked())
def is_locked(obj, request): """Returns true if the object is locked and the request doesn't contain the lock token. """ lockable = ILockable(obj, None) if lockable is None: return False if lockable.locked(): token = request.getHeader("Lock-Token", "") lock_info = lockable.lock_info() if len(lock_info) > 0 and lock_info[0]["token"] == token: return False return True return False
def test_protocol_document_is_locked_by_system_once_generated( self, browser): self.setup_generated_protocol(browser) browser.find('Protocol-My meeting').click() document = browser.context lockable = ILockable(document) self.assertTrue(lockable.locked()) self.assertTrue(lockable.can_safely_unlock(SYS_LOCK)) self.assertFalse(lockable.can_safely_unlock(STEALABLE_LOCK)) lock_info = lockable.lock_info()[0] self.assertEqual(u'sys.lock', lock_info['type'].__name__)
def test_force_unlock_clears_lock(self, browser): self.login(self.regular_user, browser) with freeze(FREEZE_DATE): oc_url = self.fetch_document_checkout_oc_url(browser, self.document) expected_token = { u'action': u'checkout', u'documents': [u'createtreatydossiers000000000002'], u'exp': 4121033100, u'sub': u'kathi.barfuss', u'url': u'http://nohost/plone/oc_checkout', } raw_token = oc_url.split(':')[-1] token = jwt.decode(raw_token, JWT_SIGNING_SECRET_PLONE, algorithms=('HS256',)) self.assertEqual(expected_token, token) lockable = ILockable(self.document) self.lock_document(browser, raw_token, self.document) self.assertTrue(lockable.locked()) self.login(self.manager, browser) browser.open(self.document) browser.click_on("Unlock") self.assertFalse(lockable.locked())
def move_all_items_totarget(portal,sourcespace,targetspace,logger): ct = getToolByName(portal,'portal_catalog') logger.info("Moving items from %s to %s" % (sourcespace,targetspace,)) if sourcespace <> None: #impersonate owner of the space #print >> out, "impersonating owner of space: %s" % (sourcespace.Title(),) #impersonateOwner(portal,sourcespace) strPath = sourcespace.getPhysicalPath() strURL = "/".join(strPath) query = {'path': {'query': strURL},'portal_type':spacesdefaultaddablenonfolderishtypes} objects = [b.getObject() for b in ct(query)] logger.info("Moving %s items from space : %s" % (len(objects), sourcespace,)) for o in objects: if callable(o.id): o_id = o.id() else: o_id = o.id try: from plone.locking.interfaces import ILockable lockable = ILockable(o) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() parentobject = o.getParentNode() cb = parentobject.manage_cutObjects(ids=[o_id]) targetspace.manage_pasteObjects(cb) if was_locked: lockable.lock() transaction.savepoint() except ComponentLookupError: pass #impersonateAdminUser(portal) query1 = query = {'path': {'query': "/".join(targetspace.getPhysicalPath()),'depth':1},'portal_type':spacesdefaultaddablenonfolderishtypes} movedobjects = ct(query1) logger.info("Moved %s items to space : %s" % (len(movedobjects), targetspace,))
def kss_obj_delete(self, selector='.kssDeletionRegion'): obj = self.context.aq_inner if obj.getPortalTypeName() == 'Discussion Item': parent = obj.inReplyTo() if parent is not None: portal_discussion = getUtility(IDiscussionTool) talkback = portal_discussion.getDiscussionFor(parent) else: talkback = obj.aq_parent # remove the discussion item talkback.deleteReply(str(obj.getId())) else: # 被锁定时先解锁 if HAS_LOCKING: lockable = ILockable(obj) if lockable.locked(): lockable.unlock() parent = obj.aq_parent # archetypes的manage_delObjects会检查每个item的删除权限 originalSecurityManager = SecurityManagement.getSecurityManager() SecurityManagement.newSecurityManager( None, User.SimpleUser('admin', '', ('Manager', ), '')) parent.manage_delObjects(str(obj.getId())) SecurityManagement.setSecurityManager(originalSecurityManager) if selector.startswith('redirect2'): # 跳转到某个地址 # 需要定义 # class="kssattr-delSelector-redirect2http://test.everydo.com" redirect2url = selector[len('redirect2'):] self.getCommandSet('zopen').redirect(url=redirect2url) else: core = self.getCommandSet('core') effects = self.getCommandSet('effects') selector = core.getParentNodeSelector(selector) # effects.effect(selector, 'fade') core.deleteNode(selector) self.getCommandSet('plone').issuePortalMessage( translate(_(u'Deleted.'), default="Deleted.", context=self.request), translate(_(u'Info'), default="Info", context=self.request)) return self.render()
def lock_info(obj): """Returns lock information about the given object.""" lockable = ILockable(obj, None) if lockable is not None: info = {"locked": lockable.locked(), "stealable": lockable.stealable()} lock_info = lockable.lock_info() if len(lock_info) > 0: info["creator"] = lock_info[0]["creator"] info["time"] = lock_info[0]["time"] info["token"] = lock_info[0]["token"] lock_type = lock_info[0]["type"] if lock_type: info["name"] = lock_info[0]["type"].__name__ lock_item = webdav_lock(obj) if lock_item: info["timeout"] = lock_item.getTimeout() return info
def autoSetID(day, event): if not hasattr(day, 'date') or day.date is None: return title = day.date.strftime('%d.%m.%Y') normalizer = getUtility(IIDNormalizer) newId = normalizer.normalize(title) if title != day.title or newId != day.id: lockable = ILockable(day) if lockable.locked(): if not lockable.can_safely_unlock(): # can not modify locked object return lockable.unlock() day.title = title api.content.rename(obj=day, new_id=newId, safe_id=True) day.reindexObject()
def autoSetID(timeslot, event): if timeslot.startTime is None or timeslot.endTime is None: return title = timeslot.getTimeRange() normalizer = getUtility(IIDNormalizer) newId = normalizer.normalize(title) if title != timeslot.title or newId != timeslot.id: lockable = ILockable(timeslot) if lockable.locked(): if not lockable.can_safely_unlock(): # can not modify locked object return lockable.unlock() timeslot.title = title api.content.rename(obj=timeslot, new_id=newId, safe_id=True) timeslot.reindexObject()
def kss_obj_delete(self, selector='.kssDeletionRegion'): obj = self.context.aq_inner if obj.getPortalTypeName() == 'Discussion Item': parent = obj.inReplyTo() if parent is not None: portal_discussion = getUtility(IDiscussionTool) talkback = portal_discussion.getDiscussionFor(parent) else: talkback = obj.aq_parent # remove the discussion item talkback.deleteReply( str(obj.getId()) ) else: # 被锁定时先解锁 if HAS_LOCKING: lockable = ILockable(obj) if lockable.locked(): lockable.unlock() parent = obj.aq_parent # archetypes的manage_delObjects会检查每个item的删除权限 originalSecurityManager = SecurityManagement.getSecurityManager() SecurityManagement.newSecurityManager(None, User.SimpleUser('admin','',('Manager',), '')) parent.manage_delObjects(str(obj.getId())) SecurityManagement.setSecurityManager(originalSecurityManager) if selector.startswith('redirect2'): # 跳转到某个地址 # 需要定义 # class="kssattr-delSelector-redirect2http://test.everydo.com" redirect2url = selector[len('redirect2'):] self.getCommandSet('zopen').redirect(url=redirect2url) else: core = self.getCommandSet('core') effects = self.getCommandSet('effects') selector = core.getParentNodeSelector(selector) # effects.effect(selector, 'fade') core.deleteNode(selector) self.getCommandSet('plone').issuePortalMessage( translate(_(u'Deleted.'), default="Deleted.", context=self.request), translate(_(u'Info'), default="Info", context=self.request)) return self.render()
def delete(self): obj = self.get_by_uid(self.request.get('uid')) lockable = ILockable(obj, None) if lockable and lockable.locked(): lockable.clear_locks() try: api.content.delete(obj) api.portal.show_message( 'Successfully deleted "%s" located at: %s' % (unidecode(obj.Title()), self.get_path(obj)), self.request, type='warning') except LinkIntegrityNotificationException: api.portal.show_message( 'Can not delete "%s" located at: %s because it is still linked.' % (unidecode(obj.Title()), self.get_path(obj)), self.request, type='warning')
def test_submit_additional_document(self): self.login(self.administrator) ori_document = self.subdocument with self.observe_children(self.submitted_proposal) as children: with self.login(self.dossier_responsible): self.proposal.submit_additional_document(ori_document) self.assertEquals(1, len(children['added'])) submitted_document, = children['added'] self.assertEqual(ori_document.Title(), submitted_document.Title()) self.assertEqual(ori_document.file.filename, submitted_document.file.filename) self.assertSubmittedDocumentCreated(self.proposal, ori_document) # submitted document should be locked by custom lock lockable = ILockable(submitted_document) self.assertTrue(lockable.locked()) self.assertFalse(lockable.can_safely_unlock(MEETING_SUBMITTED_LOCK))
def update(self): if (getattr(self.context, "collective_immediatecreate", None) != "initial" # noqa: W503 ): url = self.context.absolute_url() + "/edit" url = addTokenToUrl(url) raise Redirect(url) self.portal_type = self.context.portal_type if ILocking.providedBy(self.context): lockable = ILockable(self.context) if lockable.locked(): lockable.unlock() super().update() # fire the edit begun only if no action was executed if len(self.actions.executedActions) == 0: notify(EditBegunEvent(self.context))
def move_project_advisory(obj, event=None): """Move advisory to other theme if project changes its theme. This event is called everytime an object with a theme is updated. After the initial migration to the new theme folders, some projects will need to be linked to a different theme. When an advisory is linked to this project, the theme of the advisory must be updated as well. This means we need to move the advisory to a different theme folder. """ # Be defensive in case we are called on an object that is not a Project. advisory_getter = getattr(obj, 'get_public_advisory', None) if advisory_getter is None: return advisory = advisory_getter() if advisory is None: return project_theme = obj.getThemeTitle() advisory_theme = advisory.getThemeTitle() if project_theme == advisory_theme: return target = obj.getThemeObject() lockable = ILockable(advisory) if lockable.locked(): # During migration, we always want to unlock. During daily use, we # want to be a bit more careful. if event is not None: lock_info = lockable.lock_info()[0] lock_age = time.time() - lock_info.get('time', 0) if lock_age < (5 * 60): IStatusMessage(obj.REQUEST).addStatusMessage( u'Gelinkt advies kon niet verplaatst worden naar nieuw ' u'thema: het wordt nu bewerkt door %s.' % lock_info.get('creator'), type='warning') return lockable.unlock() logger.info("Unlocked advisory %s", advisory.title) logger.info("Moving advisory %s from %r to %r", advisory.title, advisory_theme, project_theme) api.content.move(source=advisory, target=target)
def lock_info(obj): """Returns lock information about the given object.""" lockable = ILockable(obj, None) if lockable is not None: info = { 'locked': lockable.locked(), 'stealable': lockable.stealable(), } lock_info = lockable.lock_info() if len(lock_info) > 0: info['creator'] = lock_info[0]['creator'] info['time'] = lock_info[0]['time'] info['token'] = lock_info[0]['token'] lock_type = lock_info[0]['type'] if lock_type: info['name'] = lock_info[0]['type'].__name__ lock_item = webdav_lock(obj) if lock_item: info['timeout'] = lock_item.getTimeout() return info
def empty(self): for item in [ i for i in self.catalog(trashed=True, object_provides=ITrashed.__identifier__) ]: obj = item.getObject() lockable = ILockable(obj, None) if lockable and lockable.locked(): lockable.clear_locks() try: api.content.delete(obj, check_linkintegrity=False) except LinkIntegrityNotificationException: # could be a folder that has been deleted api.portal.show_message( 'Some content could not be removed because it is still linked ' 'to other content on the site.', self.request, type='warning') api.portal.show_message('Trash emptied', self.request, type='warning')
def autoSetID(person, event): # only managers are allowed to create / modify persons via forms if not api.user.has_permission('cmf.ModifyPortalContent', obj=person): return if person.email is None \ or person.prename is None \ or person.surname is None: return title = u'{0} {1}'.format(person.prename, person.surname) newId = emailToPersonId(person.email) if title != person.title or newId != person.id: lockable = ILockable(person) if lockable.locked(): if not lockable.can_safely_unlock(): # can not modify locked object return lockable.unlock() person.title = title api.content.rename(obj=person, new_id=newId, safe_id=True) person.reindexObject()
def setId(self, value): """Sets the object id. """ if value != self.getId(): parent = aq_parent(aq_inner(self)) if parent is not None: # See Referenceable, keep refs on what is a move/rename self._v_cp_refs = 1 # We can't rename if the object is locked if HAS_LOCKING: lockable = ILockable(self) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() parent.manage_renameObject(self.id, value) if was_locked: lockable.lock() else: parent.manage_renameObject(self.id, value) self._setId(value)
def _set_id(self, value): if not value: return context = aq_inner(self.context) parent = aq_parent(context) if parent is None: # Object hasn't been added to graph yet; just set directly context.id = value return new_id = INameChooser(parent).chooseName(value, context) if getattr(aq_base(context), 'id', None): transaction.savepoint() locked = False lockable = ILockable(context, None) if lockable is not None and lockable.locked(): locked = True lockable.unlock() parent.manage_renameObject(context.getId(), new_id) if locked: lockable.lock() else: context.id = new_id
def _set_id(self, value): if not value: return context = aq_inner(self.context) parent = aq_parent(context) if parent is None: # Object hasn't been added to graph yet; just set directly context.id = value return new_id = INameChooser(parent).chooseName(value, context) if getattr(aq_base(context), 'id', None): transaction.savepoint() locked = False lockable = ILockable(context, None) if lockable is not None and lockable.locked(): locked = True lockable.unlock() parent.manage_renameObject(context.getId(), new_id) if locked: lockable.lock() else: context.id = new_id
def setId(self, value): # Sets the object id. # avoid CopyError in OFS.CopySupport.manage_renameObject(), # see http://dev.plone.org/ticket/8338 value = value.strip() if value != self.getId(): parent = aq_parent(aq_inner(self)) if parent is not None: # See Referenceable, keep refs on what is a move/rename self._v_cp_refs = 1 # We can't rename if the object is locked if HAS_LOCKING: lockable = ILockable(self) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() parent.manage_renameObject(self.id, value) if was_locked: lockable.lock() else: parent.manage_renameObject(self.id, value) self._setId(value)
def setId(self, value): # Sets the object id. # avoid CopyError in OFS.CopySupport.manage_renameObject(), # see http://dev.plone.org/ticket/8338 value = value.strip() if value != self.getId(): parent = aq_parent(aq_inner(self)) if parent is not None: # See Referenceable, keep refs on what is a move/rename self._v_cp_refs = 1 # We can't rename if the object is locked if HAS_LOCKING: lockable = ILockable(self) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() parent.manage_renameObject(self.id, value) if was_locked: lockable.lock() else: parent.manage_renameObject(self.id, value) self._setId(value)
def empty(site): setSite(site) catalog = api.portal.get_tool('portal_catalog') end = DateTime() - 30 query = dict(modified={ 'query': (DateTime('1999/09/09'), end), 'range': 'min:max' }, trashed=True) count = 0 for brain in catalog(**query): count += 1 ob = brain.getObject() lockable = ILockable(ob, None) if lockable and lockable.locked(): lockable.clear_locks() try: api.content.delete(ob) except LinkIntegrityNotificationException: # quietly ignore for now pass if count % 20 == 0: transaction.commit() transaction.commit()
def test_unlock_delete_lock_if_a_lock_existsts(self): lockable = ILockable(self.wrapper) lockable.lock() lockable.unlock() self.assertFalse(lockable.locked()) self.assertEquals(0, Lock.query.count())
def handleCheckin(event): lockable = ILockable(event.object) if lockable.locked(): # unlock working copy if it was auto-locked, or this will fail lockable.clear_locks()
def lock(self): lockable = ILockable(self.context) if not lockable.locked(): lockable.lock()
def test_locked_is_false_if_no_lock_exists(self): lockable = ILockable(self.wrapper) self.assertFalse(lockable.locked())
def isLocked(context): lockable = ILockable(context) lockable.locked()
def is_locked(self): lockable = ILockable(aq_inner(self.context)) return lockable.locked()
def migrateFolderToMemberSpace(portal,memberfolder,logger): from ubify.coretypes.content import MemberSpace new_base_folder = { 'MemberSpace' : MemberSpace, } ct = getToolByName(portal,'portal_catalog') strURL = "/".join(memberfolder.getPhysicalPath()) query = {'path':{'query':strURL},'portal_type':('StatuslogItem',)} statusmessages = [b.getObject() for b in ct(query)] logger.info("Count of status messages for %s are : %s" % (memberfolder.Title(),len(statusmessages),)) if memberfolder <> None: from plone.locking.interfaces import ILockable lockable = ILockable(memberfolder) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() parent_member = memberfolder.getParentNode() #rename old user folder and create new memberspace object and move status log items to #newly created userfolder and Delete old folder. old_id = memberfolder.getId() new_id = old_id + '_old' try: parent_member.manage_renameObject(old_id,new_id) except ComponentLookupError: pass impersonateOwner(portal,memberfolder) new_memberfolder = getOrCreateType(portal,parent_member,old_id,"MemberSpace") if new_memberfolder <> None and new_memberfolder.title == '': new_memberfolder.title = memberfolder.Title() new_memberfolder.reindexObject() impersonateAdminUser(portal) for message in statusmessages: if callable(message.id): o_id = message.id() else: o_id = message.id try: from plone.locking.interfaces import ILockable lockable = ILockable(message) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() parentItem = message.getParentNode() cb = parentItem.manage_cutObjects(ids = [o_id]) new_memberfolder.manage_pasteObjects(cb) if was_locked: lockable.lock() transaction.savepoint() except ComponentLookupError: pass #delete statuslog folder query1 = {'path':{'query':"/".join(memberfolder.getPhysicalPath())},'portal_type':('StatuslogFolder',)} logFolders = [b.getObject() for b in ct(query1)] for lFolder in logFolders: if callable(lFolder.id): o_id = lFolder.id() else: o_id = lFolder.id try: from plone.locking.interfaces import ILockable lockable = ILockable(lFolder) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() parentItem = lFolder.getParentNode() parentItem.manage_delObjects(ids=[o_id]) if was_locked: lockable.lock() transaction.savepoint() except ComponentLookupError: pass logger.info("Deleted member status log folder for %s" % (parentItem.Title(),)) try: from plone.locking.interfaces import ILockable lockable = ILockable(memberfolder) was_locked = False if lockable.locked(): was_locked = True lockable.unlock() parentItem = memberfolder.getParentNode() parentItem.manage_delObjects(ids=[memberfolder.getId()]) if was_locked: lockable.lock() transaction.savepoint() except ComponentLookupError: pass new_memberfolder.reindexObject() statusmessages = [b.getObject() for b in ct(query)] logger.info("After Migration Count of status messages for %s are : %s" % (memberfolder.Title(),len(statusmessages),))
def test_locked(self): lockable = ILockable(self.wrapper) lockable.lock() self.assertTrue(lockable.locked())
def test_locked_is_true_if_a_valid_lock_exists(self): create(Builder('lock') .of_obj(self.wrapper) .having(time=utcnow_tz_aware() - timedelta(seconds=100))) lockable = ILockable(self.wrapper) self.assertTrue(lockable.locked())
def lockOnEditBegins(obj, event): """Lock the object when a user start working on the object """ lockable = ILockable(obj) if not lockable.locked(): lockable.lock()