def __init__(self, form, request, context): fti = queryUtility(IDexterityFTI, name=form.portal_type) if IDraftable.__identifier__ in fti.behaviors: draft = getCurrentDraft(request, create=False) target = getattr(draft, '_draftAddFormTarget', createContent(form.portal_type)) if draft is None: IMutableUUID(target).set('++add++%s' % form.portal_type) beginDrafting(target.__of__(context), None) draft = getCurrentDraft(request, create=True) draft._draftAddFormTarget = target # Disable Plone 5 implicit CSRF when no form action if HAS_PLONE_PROTECT: if not ([key for key in request.form if key.startswith('form.buttons.')]): alsoProvides(request, IDisableCSRFProtection) else: current = ICurrentDraftManagement(request) current.mark() context = DraftProxy(draft, target.__of__(context)) alsoProvides(request, IAddFormDrafting) super(DefaultAddFormFieldWidgets, self).__init__(form, request, context) # noqa
def test_getCurrentDraft_draft_details_set_not_in_storage_create(self): request = self.request management = ICurrentDraftManagement(request) management.userId = u'user1' management.targetKey = u'123' management.draftName = u'bogus' draft = getCurrentDraft(request, create=True) inStorage = getUtility(IDraftStorage).getDraft( u'user1', u'123', draft.__name__) self.assertEqual(inStorage, draft) response = request.response self.assertTrue('plone.app.drafts.targetKey' in response.cookies) self.assertTrue('plone.app.drafts.draftName' in response.cookies) self.assertEqual( '123', response.cookies['plone.app.drafts.targetKey']['value'], ) self.assertEqual( draft.__name__, response.cookies['plone.app.drafts.draftName']['value'], )
def test_userId(self): request = self.app.REQUEST current = ICurrentDraftManagement(request) self.assertEquals(ptc.default_user, current.userId) current.userId = u"third-user" self.assertEquals(u"third-user", current.userId)
def test_userId(self): request = self.request current = ICurrentDraftManagement(request) self.assertEquals(TEST_USER_ID, current.userId) current.userId = u"third-user" self.assertEquals(u"third-user", current.userId)
def test_userId(self): request = self.request current = ICurrentDraftManagement(request) self.assertEqual(TEST_USER_ID, current.userId) current.userId = u'third-user' self.assertEqual(u'third-user', current.userId)
def __init__(self, form, request, context): fti = queryUtility(IDexterityFTI, name=context.portal_type) if isDraftable(fti): current = ICurrentDraftManagement(request) if current.targetKey is not None: current.mark() if current.draft: context = DraftProxy(current.draft, context) super(DefaultDisplayFormFieldWidgets, self).__init__(form, request, context) # noqa
def test_draftName(self): request = self.request current = ICurrentDraftManagement(request) self.assertEqual(None, current.draftName) request.set('plone.app.drafts.draftName', u'draft-1') self.assertEqual(u'draft-1', current.draftName) current.draftName = u'draft-2' self.assertEqual(u'draft-2', current.draftName) self.assertEqual(u'draft-1', request.get('plone.app.drafts.draftName'))
def update(self): # Set up draft information if required currentDraft = ICurrentDraftManagement(self.request) currentDraft.mark() # Override to check the tile add/edit permission if not IDeferSecurityCheck.providedBy(self.request): if not checkPermission(self.tileType.add_permission, self.context): raise Unauthorized( "You are not allowed to add this kind of tile") super(TileForm, self).update()
def test_draftName(self): request = self.request current = ICurrentDraftManagement(request) self.assertEquals(None, current.draftName) request.set('plone.app.drafts.draftName', u"draft-1") self.assertEquals(u"draft-1", current.draftName) current.draftName = u"draft-2" self.assertEquals(u"draft-2", current.draftName) self.assertEquals(u"draft-1", request.get('plone.app.drafts.draftName'))
def test_targetKey(self): request = self.request current = ICurrentDraftManagement(request) self.assertEquals(None, current.targetKey) request.set('plone.app.drafts.targetKey', u"123") self.assertEquals(u"123", current.targetKey) current.targetKey = u"234" self.assertEquals(u"234", current.targetKey) self.assertEquals(u"123", request.get('plone.app.drafts.targetKey'))
def test_path(self): request = self.request current = ICurrentDraftManagement(request) self.assertEqual(None, current.path) request.set('plone.app.drafts.path', u'/test') self.assertEqual(u'/test', current.path) current.path = u'/test/test-1' self.assertEqual(u'/test/test-1', current.path) self.assertEqual(u'/test', request.get('plone.app.drafts.path'))
def test_path(self): request = self.request current = ICurrentDraftManagement(request) self.assertEquals(None, current.path) request.set('plone.app.drafts.path', u"/test") self.assertEquals(u"/test", current.path) current.path = u"/test/test-1" self.assertEquals(u"/test/test-1", current.path) self.assertEquals(u"/test", request.get('plone.app.drafts.path'))
def test_targetKey(self): request = self.request current = ICurrentDraftManagement(request) self.assertEqual(None, current.targetKey) request.set('plone.app.drafts.targetKey', u'123') self.assertEqual(u'123', current.targetKey) current.targetKey = u'234' self.assertEqual(u'234', current.targetKey) self.assertEqual(u'123', request.get('plone.app.drafts.targetKey'))
def beginDrafting(context, event): """When we enter the edit screen, set up the target key and draft cookie path. If there is exactly one draft for the given user id and target key, consider that to be the current draft. Also mark the request with IDrafting if applicable. """ storage = queryUtility(IDraftStorage) if storage is None or not storage.enabled: return request = getattr(context, 'REQUEST', None) if request is None: return current = ICurrentDraftManagement(request) # Update target key regardless - we could have a stale cookie current.targetKey = getObjectKey(context) if current.draftName is None: drafts = storage.getDrafts(current.userId, current.targetKey) if len(drafts) == 1: current.draftName = tuple(drafts.keys())[0] # Save the path now so that we can use it again later, even on URLs # (e.g. in AJAX dialogues) that are below this path. current.path = current.defaultPath current.mark() current.save()
def test_draftName(self): request = self.request current = ICurrentDraftManagement(request) self.assertEqual(None, current.draftName) request.set('plone.app.drafts.draftName', u'draft-1') self.assertEqual(u'draft-1', current.draftName) current.draftName = u'draft-2' self.assertEqual(u'draft-2', current.draftName) self.assertEqual( u'draft-1', request.get('plone.app.drafts.draftName'))
def test_getCurrentDraft_draft_details_set_not_in_storage(self): request = self.request management = ICurrentDraftManagement(request) management.userId = u'user1' management.targetKey = u'123' management.draftName = u'bogus' draft = getCurrentDraft(request) self.assertEqual(None, draft) response = request.response self.assertFalse('plone.app.drafts.targetKey' in response.cookies) self.assertFalse('plone.app.drafts.draftName' in response.cookies)
def test_getCurrentDraft_draft_details_set_not_in_storage(self): request = self.request management = ICurrentDraftManagement(request) management.userId = u"user1" management.targetKey = u"123" management.draftName = u"bogus" draft = getCurrentDraft(request) self.assertEquals(None, draft) response = request.response self.failIf('plone.app.drafts.targetKey' in response.cookies) self.failIf('plone.app.drafts.draftName' in response.cookies)
def draftingTileDataContext(context, request, tile): """If we are drafting a content item, record tile data information to the draft, but read existing data from the underlying object. """ # When drafted content with tiles is saved, IDrafting is provided if IDrafting.providedBy(request): if request.method == 'POST': draft = getCurrentDraft(request, create=True) else: draft = getCurrentDraft(request, create=False) if draft is None: return context # When tile is previewed during drafted content is edited, heuristics... else: # Manually configure draft user id, if we are still in traverse if getattr(request, 'PUBLISHED', None) is None: IAnnotations(request)[USERID_KEY] = request.cookies.get(USERID_KEY) # No active draft for the request draft = getCurrentDraft(request) if draft is None: return context # Not referring from an edit form referrer = request.get('HTTP_REFERER', '') path = urlparse(referrer).path if all((not path.endswith('/edit'), not path.endswith('/@@edit'), not path.split('/')[-1].startswith('++add++'))): return context ICurrentDraftManagement(request).mark() return DraftProxy(draft, context)
def test_getCurrentDraft_draft_details_set_in_storage(self): request = self.request inStorage = getUtility(IDraftStorage).createDraft(u'user1', u'123') management = ICurrentDraftManagement(request) management.userId = u'user1' management.targetKey = u'123' management.draftName = inStorage.__name__ draft = getCurrentDraft(request) self.assertEqual(inStorage, draft) response = request.response self.assertFalse('plone.app.drafts.targetKey' in response.cookies) self.assertFalse('plone.app.drafts.draftName' in response.cookies)
def test_getCurrentDraft_draft_details_set_in_storage_create(self): request = self.request inStorage = getUtility(IDraftStorage).createDraft(u'user1', u'123') management = ICurrentDraftManagement(request) management.userId = u'user1' management.targetKey = u'123' management.draftName = inStorage.__name__ draft = getCurrentDraft(request, create=True) self.assertEqual(inStorage, draft) response = request.response self.assertFalse('plone.app.drafts.targetKey' in response.cookies) self.assertFalse('plone.app.drafts.draftName' in response.cookies)
def test_getCurrentDraft_draft_details_set_in_storage_create(self): request = self.request inStorage = getUtility(IDraftStorage).createDraft(u"user1", u"123") management = ICurrentDraftManagement(request) management.userId = u"user1" management.targetKey = u"123" management.draftName = inStorage.__name__ draft = getCurrentDraft(request, create=True) self.assertEquals(inStorage, draft) response = request.response self.failIf('plone.app.drafts.targetKey' in response.cookies) self.failIf('plone.app.drafts.draftName' in response.cookies)
def discardDraftsOnCancel(context, event): """When the edit form is cancelled, discard any unused drafts and remove the drafting cookies. """ storage = queryUtility(IDraftStorage) if storage is None or not storage.enabled: return request = getattr(context, 'REQUEST', None) if request is None: return current = ICurrentDraftManagement(request) if current.userId and current.targetKey: storage.discardDrafts(current.userId, current.targetKey) current.discard()
def test_getCurrentDraft_draft_details_set_not_in_storage_create(self): request = self.request management = ICurrentDraftManagement(request) management.userId = u"user1" management.targetKey = u"123" management.draftName = u"bogus" draft = getCurrentDraft(request, create=True) inStorage = getUtility(IDraftStorage).getDraft(u"user1", u"123", draft.__name__) self.assertEquals(inStorage, draft) response = request.response self.failUnless('plone.app.drafts.targetKey' in response.cookies) self.failUnless('plone.app.drafts.draftName' in response.cookies) self.assertEquals('123', response.cookies['plone.app.drafts.targetKey']['value']) self.assertEquals(draft.__name__, response.cookies['plone.app.drafts.draftName']['value'])
def test_discard(self): request = self.request response = request.response current = ICurrentDraftManagement(request) current.discard() expires = 'Wed, 31-Dec-97 23:59:59 GMT' try: # expires date changed in ZPublisher.HTTPResponse # see https://github.com/zopefoundation/Zope/commit/77f483a22d6b0cb00883006cf38928cda77b75f9 # noqa zope_version = pkg_resources.get_distribution('Zope').version if parse_version(zope_version) >= parse_version('4.0b8'): expires = 'Wed, 31 Dec 1997 23:59:59 GMT' except Exception: pass deletedToken = { 'expires': expires, 'max_age': 0, 'path': '/', 'quoted': True, 'value': 'deleted' } self.assertEqual( deletedToken, response.cookies['plone.app.drafts.targetKey'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.draftName'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.path'], ) current.path = '/test' current.discard() deletedToken['path'] = '/test' self.assertEqual( deletedToken, response.cookies['plone.app.drafts.targetKey'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.draftName'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.path'], )
def test_mark(self): request = self.request current = ICurrentDraftManagement(request) current.mark() self.assertFalse(IDrafting.providedBy(request)) current.targetKey = u'123' current.mark() self.assertTrue(IDrafting.providedBy(request))
def update(self): # Support drafting tile data context if PLONE_APP_DRAFTS: ICurrentDraftManagement(self.request).mark() # Override to check the tile add/edit permission if not IDeferSecurityCheck.providedBy(self.request): if not checkPermission(self.tileType.add_permission, self.context): raise Unauthorized( "You are not allowed to add this kind of tile") super(TileForm, self).update()
def test_getCurrentDraft_draft_set_create(self): request = self.request management = ICurrentDraftManagement(request) management.draft = setDraft = Draft() draft = getCurrentDraft(request, create=True) self.assertEqual(setDraft, draft) response = request.response self.assertFalse('plone.app.drafts.targetKey' in response.cookies) self.assertFalse('plone.app.drafts.draftName' in response.cookies)
def __init__(self, form, request, context): fti = queryUtility(IDexterityFTI, name=form.portal_type) if IDraftable.__identifier__ in fti.behaviors: draft = getCurrentDraft(request, create=False) if draft is None: beginDrafting(context, None) draft = getCurrentDraft(request, create=True) # Disable Plone 5 implicit CSRF when no form action if HAS_PLONE_PROTECT: if not ([key for key in request.form if key.startswith('form.buttons.')]): alsoProvides(request, IDisableCSRFProtection) else: current = ICurrentDraftManagement(request) current.mark() context = DraftProxy(draft, context) alsoProvides(request, IEditFormDrafting) super(DefaultEditFormFieldWidgets, self).__init__(form, request, context) # noqa
def __call__(self): # Set up draft information if required currentDraft = ICurrentDraftManagement(self.request) currentDraft.mark() self.request['disable_border'] = True confirm = self.request.form.get('confirm', False) self.tileTypeName = self.request.form.get('type', None) self.tileId = self.request.form.get('id', None) self.deleted = False if confirm and self.tileTypeName and self.tileId: tileType = getUtility(ITileType, name=self.tileTypeName) if not checkPermission(tileType.add_permission, self.context): raise Unauthorized("You are not allowed to modify this " + \ "tile type") tile = self.context.restrictedTraverse( '@@%s/%s' % (self.tileTypeName, self.tileId,)) dm = ITileDataManager(tile) dm.delete() notify(ObjectRemovedEvent(tile, self.context, self.tileId)) self.deleted = True elif 'form.button.Ok' in self.request.form: self.request.response.redirect( self.context.absolute_url() + '/view') return '' return self.index()
def syncDraftOnSave(context, event): """When the edit form is saved, sync the draft (if set) and discard it. Also discard the drafting cookies. """ storage = queryUtility(IDraftStorage) if storage is None or not storage.enabled: return request = getattr(context, 'REQUEST', None) if request is None: return draft = getCurrentDraft(request) if draft is not None: syncDraft(draft, context) current = ICurrentDraftManagement(request) if current.userId and current.targetKey: storage.discardDrafts(current.userId, current.targetKey) current.discard()
def getCurrentDraft(request, create=False): """Get the current draft as stored in the request. The request must have been set up via an ``ICurrentDraftManagement`` adapter. This should happen in the integration layer between the drafts storage and the draft edit form. If no draft is available, but a user id and target key have been given, a new draft will be created if ``create`` is True. If not found, return None. """ current = ICurrentDraftManagement(request, None) if current is None: return None draft = current.draft if draft is not None: return draft if create and current.userId and current.targetKey: storage = queryUtility(IDraftStorage) if storage is None: return None draft = storage.createDraft(current.userId, current.targetKey) current.draft = draft current.draftName = draft.__name__ current.save() return draft return None
def test_mark(self): request = self.request current = ICurrentDraftManagement(request) current.mark() self.failIf(IDrafting.providedBy(request)) current.targetKey = u"123" current.mark() self.failUnless(IDrafting.providedBy(request))
def test_defaultPath(self): request = self.request request['URL'] = 'http://nohost' current = ICurrentDraftManagement(request) self.assertEqual('/', current.defaultPath) request['URL'] = 'http://nohost/' self.assertEqual('/', current.defaultPath) request['URL'] = 'http://nohost/test/edit' self.assertEqual('/test', current.defaultPath) request['URL'] = 'http://nohost/test/edit/' self.assertEqual('/test/edit', current.defaultPath)
def __init__(self, form, request, context): fti = queryUtility(IDexterityFTI, name=form.portal_type) if isDraftable(fti): current = ICurrentDraftManagement(request) if current.targetKey is None: beginDrafting(context, None) current.path = '/'.join(context.getPhysicalPath()) current.targetKey = IUUID(context) current.save() else: current.mark() if current.draft: context = DraftProxy(current.draft, context) alsoProvides(request, IEditFormDrafting) super(DefaultEditFormFieldWidgets, self).__init__(form, request, context) # noqa
def test_discard(self): request = self.request response = request.response current = ICurrentDraftManagement(request) current.discard() expires = 'Wed, 31-Dec-97 23:59:59 GMT' try: # expires date changed in ZPublisher.HTTPResponse # see https://github.com/zopefoundation/Zope/commit/77f483a22d6b0cb00883006cf38928cda77b75f9 # noqa zope_version = pkg_resources.get_distribution('Zope').version if parse_version(zope_version) >= parse_version('4.0b8'): expires = 'Wed, 31 Dec 1997 23:59:59 GMT' except Exception: pass deletedToken = {'expires': expires, 'max_age': 0, 'path': '/', 'quoted': True, 'value': 'deleted'} self.assertEqual( deletedToken, response.cookies['plone.app.drafts.targetKey'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.draftName'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.path'], ) current.path = '/test' current.discard() deletedToken['path'] = '/test' self.assertEqual( deletedToken, response.cookies['plone.app.drafts.targetKey'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.draftName'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.path'], )
def __init__(self, form, request, context): fti = queryUtility(IDexterityFTI, name=form.portal_type) if isDraftable(fti): current = ICurrentDraftManagement(request) if current.targetKey != '++add++{0}'.format(form.portal_type): beginDrafting(context, None) current.path = '/'.join(context.getPhysicalPath()) current.targetKey = '++add++{0}'.format(form.portal_type) current.save() else: current.mark() target = getattr(current.draft, '_draftAddFormTarget', None) if current.draft and target: context = DraftProxy(current.draft, target.__of__(context)) alsoProvides(request, IAddFormDrafting) super(DefaultAddFormFieldWidgets, self).__init__(form, request, context) # noqa
def subscriber(event): # Only listen to ObjectModifiedEvent if not isinstance(event, ObjectModifiedEvent): return # Only listen when we are drafting request = getRequest() if not IDrafting.providedBy(request): return # Only listen if its our drafting target, which has been modified drafting = ICurrentDraftManagement(request, None) if drafting is None: return source = IUUID(event.object, None) if source is None or source != drafting.targetKey: return # Sync draft now before indexers are called syncDraftOnSave(event.object, event)
def test_discard(self): request = self.request response = request.response current = ICurrentDraftManagement(request) current.discard() deletedToken = {'expires': 'Wed, 31-Dec-97 23:59:59 GMT', 'max_age': 0, 'path': '/', 'quoted': True, 'value': 'deleted'} self.assertEqual( deletedToken, response.cookies['plone.app.drafts.targetKey'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.draftName'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.path'], ) current.path = '/test' current.discard() deletedToken['path'] = '/test' self.assertEqual( deletedToken, response.cookies['plone.app.drafts.targetKey'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.draftName'], ) self.assertEqual( deletedToken, response.cookies['plone.app.drafts.path'], )
def test_draft(self): request = self.request current = ICurrentDraftManagement(request) self.assertEqual(None, current.draft) current.userId = u'user1' current.targetKey = u'123' current.draftName = u'draft' self.assertEqual(None, current.draft) storage = getUtility(IDraftStorage) created = storage.createDraft(u'user1', u'123') current.draftName = created.__name__ self.assertEqual(created, current.draft) newDraft = storage.createDraft(u'user1', u'123') current.draft = newDraft self.assertEqual(newDraft, current.draft)
def test_draft(self): request = self.request current = ICurrentDraftManagement(request) self.assertEquals(None, current.draft) current.userId = u"user1" current.targetKey = u"123" current.draftName = u"draft" self.assertEquals(None, current.draft) storage = getUtility(IDraftStorage) created = storage.createDraft(u"user1", u"123") current.draftName = created.__name__ self.assertEquals(created, current.draft) newDraft = storage.createDraft(u"user1", u"123") current.draft = newDraft self.assertEquals(newDraft, current.draft)
def test_save(self): request = self.request response = request.response current = ICurrentDraftManagement(request) self.assertEqual(False, current.save()) self.assertFalse('plone.app.drafts.targetKey' in response.cookies) self.assertFalse('plone.app.drafts.draftName' in response.cookies) self.assertFalse('plone.app.drafts.userId' in response.cookies) self.assertFalse('plone.app.drafts.path' in response.cookies) current.targetKey = u'123' self.assertEqual(True, current.save()) self.assertEqual( {'value': '123', 'quoted': True, 'path': '/'}, response.cookies['plone.app.drafts.targetKey'], ) self.assertFalse('plone.app.drafts.draftName' in response.cookies) self.assertFalse('plone.app.drafts.path' in response.cookies) current.targetKey = u'123' current.draftName = u'draft-1' self.assertEqual(True, current.save()) self.assertEqual( {'value': '123', 'quoted': True, 'path': '/'}, response.cookies['plone.app.drafts.targetKey'], ) self.assertEqual( {'value': 'draft-1', 'quoted': True, 'path': '/'}, response.cookies['plone.app.drafts.draftName'], ) self.assertFalse('plone.app.drafts.path' in response.cookies) current.targetKey = u'123' current.draftName = u'draft-1' current.path = '/test' # clear data del self.request.response.cookies['plone.app.drafts.targetKey'] del self.request.response.cookies['plone.app.drafts.draftName'] self.assertEqual(True, current.save()) self.assertEqual( {'value': '123', 'quoted': True, 'path': '/test'}, response.cookies['plone.app.drafts.targetKey'], ) self.assertEqual( {'value': 'draft-1', 'quoted': True, 'path': '/test'}, response.cookies['plone.app.drafts.draftName'], ) self.assertEqual( {'value': '/test', 'quoted': True, 'path': '/test'}, response.cookies['plone.app.drafts.path'], )