def test_vfs_construct_path(self) -> None: """Test vfs_construct_path method.""" p = utils.vfs_construct_path('a', 'b', 'c') self.assertEqual(p, 'a/b/c') p = utils.vfs_construct_path('a/', '/b', 'c') self.assertEqual(p, '/b/c') p = utils.vfs_construct_path('a/', 'b', 'c') self.assertEqual(p, 'a/b/c') p = utils.vfs_construct_path('a', '/b', 'c') self.assertEqual(p, '/b/c') p = utils.vfs_construct_path('/a', 'b/') self.assertEqual(p, '/a/b/')
def listdir(self, dir_name): """Lists all files in a directory. Args: dir_name: str. The directory whose files should be listed. This should not start with '/' or end with '/'. Returns: list(str). A lexicographically-sorted list of filenames. """ if dir_name.startswith('/') or dir_name.endswith('/'): raise IOError( 'The dir_name should not start with / or end with / : %s' % dir_name) # The trailing slash is necessary to prevent non-identical directory # names with the same prefix from matching, e.g. /abcd/123.png should # not match a query for files under /abc/. if dir_name and not dir_name.endswith('/'): dir_name += '/' assets_path = '%s/' % self._assets_path prefix = utils.vfs_construct_path(self._assets_path, dir_name) blobs_in_dir = storage_services.listdir(self._bucket_name, prefix) return [blob.name.replace(assets_path, '') for blob in blobs_in_dir]
def _check_filepath(self, filepath: str) -> None: """Raises an error if a filepath is invalid. Args: filepath: str. The path to the relevant file within the entity's assets folder. Raises: OSError. Invalid filepath. """ base_dir = utils.vfs_construct_path('/', self.assets_path, 'assets') absolute_path = utils.vfs_construct_path(base_dir, filepath) normalized_path = utils.vfs_normpath(absolute_path) # This check prevents directory traversal. if not normalized_path.startswith(base_dir): raise IOError('Invalid filepath: %s' % filepath)