def _findUniqueName(self, name, obj): """Find a unique name in the parent folder, based on the given id, by appending -n, where n is a number greater than 1, or just the id if it's ok. """ check_id = self._getCheckId(obj) if not check_id(name, required=1): return name ext = '' m = FILENAME_REGEX.match(name) if m is not None: name = m.groups()[0] ext = '.' + m.groups()[1] idx = 1 while idx <= ATTEMPTS: new_name = "%s-%d%s" % (name, idx, ext) if not check_id(new_name, required=1): return new_name idx += 1 # give one last attempt using the current date time before giving up new_name = "%s-%s%s" % (name, time.time(), ext) if not check_id(new_name, required=1): return new_name raise ValueError( "Cannot find a unique name based on %s after %d attemps." % ( name, ATTEMPTS, ))
def _findUniqueName(self, name, obj): """Find a unique name in the parent folder, based on the given id, by appending -n, where n is a number greater than 1, or just the id if it's ok. """ check_id = self._getCheckId(obj) if not check_id(name, required=1): return name ext = '' m = FILENAME_REGEX.match(name) if m is not None: name = m.groups()[0] ext = '.' + m.groups()[1] idx = 1 while idx <= ATTEMPTS: new_name = "%s-%d%s" % (name, idx, ext) if not check_id(new_name, required=1): return new_name idx += 1 # give one last attempt using the current date time before giving up new_name = "%s-%s%s" % (name, time.time(), ext) if not check_id(new_name, required=1): return new_name raise ValueError( "Cannot find a unique name based on %s after %d attemps." % ( name, ATTEMPTS, ) )
def testCheckingMethodAliasesOnPortalRoot(self): # Test for bug http://dev.plone.org/plone/ticket/4351 self.setRoles(['Manager']) self.portal.manage_permission('Add portal content', ['Manager'], acquire=0) # Should not raise: Before we were using obj.getTypeInfo(), which is # not defined on the portal root. try: check_id(self.portal, 'foo') except AttributeError as e: self.fail(e)
def post_validate(self, REQUEST=None, errors=None): # Validates upload file and id. id = REQUEST.form.get('id') field = self.getPrimaryField() f_name = field.getName() upload = REQUEST.form.get('%s_file' % f_name, None) filename = getattr(upload, 'filename', None) if isinstance(filename, basestring): filename = os.path.basename(filename) filename = filename.split("\\")[-1] clean_filename = self._cleanupFilename(filename, request=REQUEST) used_id = clean_filename if id and not self._isIDAutoGenerated(id): used_id = id if upload: # the file may have already been read by a # former method upload.seek(0) if not used_id or not self._should_set_id_to_filename( filename, REQUEST.form.get('title')): # Set ID in whatever way the base classes usually do. return check_id_result = check_id(self, used_id, required=1) if check_id_result: if used_id == id: errors['id'] = check_id_result REQUEST.form['id'] = used_id else: errors[f_name] = check_id_result
def testCatalogMetadata(self): portal_catalog = getToolByName(self.portal, 'portal_catalog') portal_catalog.addColumn('new_metadata') self.assertTrue('new_metadata' in portal_catalog.schema()) self.assertFalse('new_metadata' in portal_catalog.indexes()) r = check_id(self.folder, 'new_metadata') self.assertEqual(r, u'new_metadata is reserved.')
def _renameAfterCreation(self, check_auto_id=False): # Renames an object like its normalized title. old_id = self.getId() if check_auto_id and not self._isIDAutoGenerated(old_id): # No auto generated id return False new_id = self.generateNewId() if new_id is None: return False invalid_id = check_id(self, new_id, required=1) # If check_id told us no, or if it was not found, make sure we have an # id unique in the parent folder. if invalid_id: unique_id = self._findUniqueId(new_id) if unique_id is not None: new_id = unique_id invalid_id = False if not invalid_id: # Can't rename without a subtransaction commit when using # portal_factory! transaction.savepoint(optimistic=True) self.setId(new_id) return new_id return False
def testCollision(self): self.folder.invokeFactory('Document', id='foo') self.folder.invokeFactory('Document', id='bar') r = check_id(self.folder.foo, 'bar') self.assertEqual( r, u'There is already an item named bar in this ' u'folder.')
def testInvalidIdSkipped(self): # Note that the check is skipped when we don't have # the "Add portal content" permission. self.folder.manage_permission('Add portal content', [], acquire=0) self.folder._setObject('foo', dummy.Item('foo')) r = check_id(self.folder.foo, '_foo') self.assertEqual(r, None) # success
def _findUniqueId(self, id): # Find a unique id in the parent folder, based on the given id, by # appending -n, where n is a number between 1 and the constant # RENAME_AFTER_CREATION_ATTEMPTS, set in config.py. If no id can be # found, return None. invalid_id = check_id(self, id, required=1) if not invalid_id: return id idx = 1 while idx <= RENAME_AFTER_CREATION_ATTEMPTS: new_id = "%s-%d" % (id, idx) if not check_id(self, new_id, required=1): return new_id idx += 1 return None
def testReservedIdSkipped(self): # This check is picked up by the checkIdAvailable, unless we don't have # the "Add portal content" permission, in which case it is picked up by # the final hasattr check. self.folder.manage_permission('Add portal content', [], acquire=0) self.folder._setObject('foo', dummy.Item('foo')) r = check_id(self.folder.foo, 'portal_catalog') self.assertEqual(r, u'portal_catalog is reserved.')
def testCatalogIndexSkipped(self): # Note that the check is skipped when we don't have # the "Search ZCatalogs" permission. self.portal.manage_permission('Search ZCatalog', ['Manager'], acquire=0) r = check_id(self.folder, 'created') # But now the final hasattr check picks this up self.assertEqual(r, u'created is reserved.')
def testParentMethodAliasDisallowed(self): # Note that the check is skipped when we don't have # the "Add portal content" permission. self.folder.manage_permission('Add portal content', ['Manager'], acquire=0) self.folder._setObject('foo', dummy.Item('foo')) for alias in self.folder.getTypeInfo().getMethodAliases().keys(): r = check_id(self.folder.foo, alias) self.assertEqual(r, u'%s is reserved.' % alias)
def testCatalogIndex(self): # TODO: Tripwire portal_membership = getToolByName(self.portal, 'portal_membership') have_permission = portal_membership.checkPermission self.assertTrue(have_permission('Search ZCatalog', self.portal.portal_catalog), 'Expected permission "Search ZCatalog"') r = check_id(self.folder, 'created') self.assertEqual(r, u'created is reserved.')
def do_Plone_check(newid, required): if _check_id is not None: return _check_id( newid, required=required, contained_by=parent ) from Products.CMFPlone.utils import check_id return check_id( obj, newid, required=required, contained_by=parent)
def testCollisionNotSkipped(self): # Note that the existing object check is done, even when we don't have # the "Access contents information" permission. # This used to be the other way around. The reason got lost. # Probably this was because the permission was checked automatically # because check_id was a skin script. Since Plone 5.2 it is a # function which cannot be accessed from the web or templates, # so the permission test seems unneeded. self.folder.manage_permission('Access contents information', [], acquire=0) self.folder._setObject('foo', dummy.Item('foo')) self.folder._setObject('bar', dummy.Item('bar')) r = check_id(self.folder.foo, 'bar') self.assertEqual(r, u'bar is reserved.')
def __call__(self, id, instance, *args, **kwargs): # Try to get a check_id from the instance, # for example a Python skin script or a method, # like Products/CMFPlone/skins/plone_scripts/check_id.py # until Plone 5.1. check_id = aq_get(instance, 'check_id', None, 1) if check_id is not None: # instance is passed implicitly: it is 'self' result = check_id(id, required=kwargs.get('required')) else: try: # try to use the check_id script of CMFPlone # Import here to avoid a hard dependency and # possible cyclic imports. from Products.CMFPlone.utils import check_id except ImportError: # Use our own fallback function. check_id = fallback_check_id # Pass all keywords. We may need the request. result = check_id(instance, id, **kwargs) else: # Only the 'required' keyword is accepted. result = check_id(instance, id, required=kwargs.get('required')) return result or 1
def do_Plone_check(newid, required): if _check_id is not None: return _check_id(newid, required=required, contained_by=parent) # Function in CMFPlone added in 5.1.4/5, # which replaces the skin script that will be removed in 5.2. try: from Products.CMFPlone.utils import check_id return check_id(obj, newid, required=required, contained_by=parent) except ImportError: pass # fallback to OFS try: parent._checkId(newid) except BadRequest: return True
def do_Plone_check(newid, required): if _check_id is not None: return _check_id( newid, required=required, contained_by=parent ) # Function in CMFPlone added in 5.1.4/5, # which replaces the skin script that will be removed in 5.2. try: from Products.CMFPlone.utils import check_id return check_id( obj, newid, required=required, contained_by=parent) except ImportError: pass # fallback to OFS try: parent._checkId(newid) except BadRequest: return True
def testMissingUtils(self): # check_id should not bomb out if the plone_utils tool is missing self.portal._delObject('plone_utils') r = check_id(self.folder, 'foo') self.assertEqual(r, None) # success
def testDecodeId(self): # See https://github.com/zopefoundation/Zope/pull/181 r = check_id(self.folder, '\xc3\xa4') self.assertEqual(r, None)
def testReservedId(self): self.folder._setObject('foo', dummy.Item('foo')) r = check_id(self.folder.foo, 'portal_catalog') self.assertEqual(r, u'portal_catalog is reserved.')
def testAlternativeId(self): r = check_id(self.folder, '', alternative_id='foo') self.assertEqual(r, None) # success
def testBadId(self): # See https://github.com/zopefoundation/Zope/pull/181 r = check_id(self.folder, '=') self.assertEqual(r, None)
def testEmptyId(self): r = check_id(self.folder, '') self.assertEqual(r, None) # success
def testRequiredId(self): r = check_id(self.folder, '', required=1) self.assertEqual(r, u'Please enter a name.')
def testHiddenObjectId(self): # If a parallel object is not in content-space, should get 'reserved' # instead of 'taken' r = check_id(self.folder, 'portal_skins') self.assertEqual(r, u'portal_skins is reserved.')
def testGoodId(self): r = check_id(self.folder, 'foo') self.assertEqual(r, None) # success
def testInvalidId(self): self.folder._setObject('foo', dummy.Item('foo')) r = check_id(self.folder.foo, '_foo') self.assertEqual(r, u'_foo is reserved.')
def testCanOverrideParentNames(self): self.folder.invokeFactory('Document', id='item1') self.folder.invokeFactory('Folder', id='folder1') self.folder.invokeFactory('Document', id='foo') r = check_id(self.folder.folder1.foo, 'item1') self.assertEqual(r, None)
def testContainerHook(self): # Container may have a checkValidId method; make sure it is called self.folder._setObject('checkValidId', dummy.Raiser(dummy.Error)) self.folder._setObject('foo', dummy.Item('foo')) r = check_id(self.folder.foo, 'whatever') self.assertEqual(r, u'whatever is reserved.')
def testContainerHookRaisesUnauthorized(self): # check_id should not swallow Unauthorized errors raised by hook self.folder._setObject('checkValidId', dummy.Raiser(Unauthorized)) self.folder._setObject('foo', dummy.Item('foo')) self.assertRaises(Unauthorized, check_id(self.folder.foo), 'whatever')
def testContainerHookRaisesConflictError(self): # check_id should not swallow ConflictErrors raised by hook self.folder._setObject('checkValidId', dummy.Raiser(ConflictError)) self.folder._setObject('foo', dummy.Item('foo')) self.assertRaises(ConflictError, check_id(self.folder.foo), 'whatever')
def testMissingFactory(self): # check_id should not bomb out if the portal_factory tool is missing if 'portal_factory' in self.portal: self.portal._delObject('portal_factory') r = check_id(self.folder, 'foo') self.assertEqual(r, None) # success
def testMissingCatalog(self): # check_id should not bomb out if the portal_catalog tool is missing self.portal._delObject('portal_catalog') r = check_id(self.folder, 'foo') self.assertEqual(r, None) # success