Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public static IndexComponentSelector getByKeyOrThrow(@Nullable String key) {
}
IndexComponentSelector selector = getByKey(key);
if (selector == null) {
throw new IllegalArgumentException(
throw new InvalidSelectorException(
"Unknown key of index component selector [" + key + "], available options are: " + KEY_REGISTRY.keySet()
);
}
Expand All @@ -107,7 +107,7 @@ public static IndexComponentSelector read(StreamInput in) throws IOException {
static IndexComponentSelector getById(byte id) {
IndexComponentSelector indexComponentSelector = ID_REGISTRY.get(id);
if (indexComponentSelector == null) {
throw new IllegalArgumentException(
throw new InvalidSelectorException(
"Unknown id of index component selector [" + id + "], available options are: " + ID_REGISTRY
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.action.support;

/**
* Exception thrown when a :: selector is invalid.
*/
public class InvalidSelectorException extends IllegalArgumentException {

public InvalidSelectorException(String message) {
super(message);
}

public InvalidSelectorException(String message, Throwable cause) {
super(message, cause);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.action.support;

/**
* Exception thrown when a :: selector is not supported.
*/
public class UnsupportedSelectorException extends IllegalArgumentException {

public UnsupportedSelectorException(String expression) {
super("Index component selectors are not supported in this context but found selector in expression [" + expression + "]");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import org.elasticsearch.action.support.IndexComponentSelector;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.UnsupportedSelectorException;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.Tuple;
Expand Down Expand Up @@ -57,11 +58,7 @@ public List<String> resolveIndexAbstractions(
Tuple<String, String> expressionAndSelector = IndexNameExpressionResolver.splitSelectorExpression(indexAbstraction);
String selectorString = expressionAndSelector.v2();
if (indicesOptions.allowSelectors() == false && selectorString != null) {
throw new IllegalArgumentException(
"Index component selectors are not supported in this context but found selector in expression ["
+ indexAbstraction
+ "]"
);
throw new UnsupportedSelectorException(indexAbstraction);
}
indexAbstraction = expressionAndSelector.v1();
IndexComponentSelector selector = IndexComponentSelector.getByKeyOrThrow(selectorString);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.support.IndexComponentSelector;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.UnsupportedSelectorException;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexAbstraction.Type;
import org.elasticsearch.cluster.project.ProjectResolver;
Expand Down Expand Up @@ -2394,13 +2395,11 @@ private static IndexComponentSelector resolveAndValidateSelectorString(Supplier<
* Checks the selectors that have been returned from splitting an expression and throws an exception if any were present.
* @param expression Original expression
* @param selector Selectors to validate
* @throws IllegalArgumentException if selectors are present
* @throws UnsupportedSelectorException if selectors are present
*/
private static void ensureNoSelectorsProvided(String expression, IndexComponentSelector selector) {
if (selector != null) {
throw new IllegalArgumentException(
"Index component selectors are not supported in this context but found selector in expression [" + expression + "]"
);
throw new UnsupportedSelectorException(expression);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ protected Tuple<String, String> getSingleDataAndFailureIndices(String dataStream
}

protected static void assertSelectorsNotSupported(ResponseException exception) {
assertThat(exception.getResponse().getStatusLine().getStatusCode(), equalTo(403));
assertThat(exception.getResponse().getStatusLine().getStatusCode(), equalTo(400));
assertThat(exception.getMessage(), containsString("Selectors are not yet supported on remote cluster patterns"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1891,7 +1891,10 @@ public void testWriteAndManageOperations() throws IOException {

expectThrows(() -> deleteDataStream(MANAGE_FAILURE_STORE_ACCESS, "test1"), 403);
// selectors aren't supported for deletes so we get a 403
expectThrows(() -> deleteDataStream(MANAGE_FAILURE_STORE_ACCESS, "test1::failures"), 403);
expectThrowsBadRequest(
() -> deleteDataStream(MANAGE_FAILURE_STORE_ACCESS, "test1::failures"),
containsString("Index component selectors are not supported in this context but found selector in expression [test1::failures]")
);

// manage user can delete data stream
deleteDataStream(MANAGE_ACCESS, "test1");
Expand Down Expand Up @@ -2345,6 +2348,12 @@ private static void expectThrows(ThrowingRunnable runnable, int statusCode) {
assertThat(ex.getResponse().getStatusLine().getStatusCode(), equalTo(statusCode));
}

private void expectThrowsBadRequest(ThrowingRunnable runnable, Matcher<String> errorMatcher) {
ResponseException ex = expectThrows(ResponseException.class, runnable);
assertThat(ex.getResponse().getStatusLine().getStatusCode(), equalTo(400));
assertThat(ex.getMessage(), errorMatcher);
}

private void expectThrowsUnauthorized(String user, Search search, Matcher<String> errorMatcher) {
ResponseException ex = expectThrows(ResponseException.class, () -> performRequestMaybeUsingApiKey(user, search.toSearchRequest()));
assertThat(ex.getResponse().getStatusLine().getStatusCode(), equalTo(403));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import org.elasticsearch.action.index.TransportIndexAction;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.GroupedActionListener;
import org.elasticsearch.action.support.InvalidSelectorException;
import org.elasticsearch.action.support.SubscribableListener;
import org.elasticsearch.action.support.UnsupportedSelectorException;
import org.elasticsearch.action.support.replication.TransportReplicationAction.ConcreteShardRequest;
import org.elasticsearch.action.update.TransportUpdateAction;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
Expand All @@ -44,6 +46,7 @@
import org.elasticsearch.core.Nullable;
import org.elasticsearch.core.Tuple;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.indices.InvalidIndexNameException;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportActionProxy;
Expand Down Expand Up @@ -502,6 +505,21 @@ private void authorizeAction(
indicesAndAliasesResolver.resolve(action, request, projectMetadata, authorizedIndices)
),
e -> {
if (e instanceof InvalidIndexNameException
|| e instanceof InvalidSelectorException
|| e instanceof UnsupportedSelectorException) {
logger.debug(
() -> Strings.format(
"failed [%s] action authorization for [%s] due to [%s] exception",
action,
authentication,
e.getClass().getSimpleName()
),
e
);
listener.onFailure(e);
return;
}
auditTrail.accessDenied(requestId, authentication, action, request, authzInfo);
if (e instanceof IndexNotFoundException) {
listener.onFailure(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.IndexComponentSelector;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.UnsupportedSelectorException;
import org.elasticsearch.cluster.metadata.AliasMetadata;
import org.elasticsearch.cluster.metadata.IndexAbstraction;
import org.elasticsearch.cluster.metadata.IndexAbstractionResolver;
Expand Down Expand Up @@ -315,11 +316,7 @@ ResolvedIndices resolveIndicesAndAliases(
// First, if a selector is present, check to make sure that selectors are even allowed here
if (indicesOptions.allowSelectors() == false && allIndicesPatternSelector != null) {
String originalIndexExpression = indicesRequest.indices()[0];
throw new IllegalArgumentException(
"Index component selectors are not supported in this context but found selector in expression ["
+ originalIndexExpression
+ "]"
);
throw new UnsupportedSelectorException(originalIndexExpression);
}
if (indicesOptions.expandWildcardExpressions()) {
IndexComponentSelector selector = IndexComponentSelector.getByKeyOrThrow(allIndicesPatternSelector);
Expand Down