From b23709b17820bd452ad73e8eb20297188b5411b0 Mon Sep 17 00:00:00 2001 From: Dan Hermann Date: Mon, 29 Apr 2019 07:31:01 -0500 Subject: [PATCH] Applies the same naming restrictions to repositories as to snapshots except that leading underscores and uppercase characters are permitted. (#41585) Fixes #40817. --- .../repositories/RepositoriesService.java | 16 ++++++++++++++++ .../repositories/RepositoriesServiceTests.java | 15 +++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/server/src/main/java/org/elasticsearch/repositories/RepositoriesService.java b/server/src/main/java/org/elasticsearch/repositories/RepositoriesService.java index e141d0d6014..1e4f202afc1 100644 --- a/server/src/main/java/org/elasticsearch/repositories/RepositoriesService.java +++ b/server/src/main/java/org/elasticsearch/repositories/RepositoriesService.java @@ -35,6 +35,7 @@ import org.elasticsearch.cluster.metadata.RepositoriesMetaData; import org.elasticsearch.cluster.metadata.RepositoryMetaData; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.regex.Regex; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ConcurrentCollections; @@ -94,6 +95,7 @@ public class RepositoriesService implements ClusterStateApplier { */ public void registerRepository(final PutRepositoryRequest request, final ActionListener listener) { final RepositoryMetaData newRepositoryMetaData = new RepositoryMetaData(request.name(), request.type(), request.settings()); + validate(request.name()); final ActionListener registrationListener; if (request.verify()) { @@ -418,6 +420,20 @@ public class RepositoriesService implements ClusterStateApplier { } } + private static void validate(final String repositoryName) { + if (Strings.hasLength(repositoryName) == false) { + throw new RepositoryException(repositoryName, "cannot be empty"); + } + if (repositoryName.contains("#")) { + throw new RepositoryException(repositoryName, "must not contain '#'"); + } + if (Strings.validFileName(repositoryName) == false) { + throw new RepositoryException(repositoryName, + "must not contain the following characters " + Strings.INVALID_FILENAME_CHARS); + } + } + + private void ensureRepositoryNotInUse(ClusterState clusterState, String repository) { if (SnapshotsService.isRepositoryInUse(clusterState, repository) || RestoreService.isRepositoryInUse(clusterState, repository)) { throw new IllegalStateException("trying to modify or unregister repository that is currently used "); diff --git a/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java b/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java index 981004f48ef..505c0628d6a 100644 --- a/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java +++ b/server/src/test/java/org/elasticsearch/repositories/RepositoriesServiceTests.java @@ -22,11 +22,13 @@ package org.elasticsearch.repositories; import org.apache.lucene.index.IndexCommit; import org.elasticsearch.Version; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.RepositoryMetaData; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.Strings; import org.elasticsearch.common.UUIDs; import org.elasticsearch.common.component.Lifecycle; import org.elasticsearch.common.component.LifecycleListener; @@ -100,6 +102,19 @@ public class RepositoriesServiceTests extends ESTestCase { assertSame(repository, repository2); } + public void testRegisterRejectsInvalidRepositoryNames() { + assertThrowsOnRegister(""); + assertThrowsOnRegister("contains#InvalidCharacter"); + for (char c : Strings.INVALID_FILENAME_CHARS) { + assertThrowsOnRegister("contains" + c + "InvalidCharacters"); + } + } + + private void assertThrowsOnRegister(String repoName) { + PutRepositoryRequest request = new PutRepositoryRequest(repoName); + expectThrows(RepositoryException.class, () -> repositoriesService.registerRepository(request, null)); + } + private static class TestRepository implements Repository { private static final String TYPE = "internal";