mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-23 13:26:02 +00:00
Avoid NPE when checking for CCR index privileges (#44397)
This commit avoids an NPE when checking for privileges to follow indices. The problem here is that in some cases we might not be able to read the authentication info from the thread context. In that case, a null user would be returned and we were not guarding against this.
This commit is contained in:
parent
53514b0477
commit
becbf450fa
@ -7,10 +7,10 @@
|
|||||||
package org.elasticsearch.xpack.ccr;
|
package org.elasticsearch.xpack.ccr;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchStatusException;
|
import org.elasticsearch.ElasticsearchStatusException;
|
||||||
import org.elasticsearch.action.ActionType;
|
|
||||||
import org.elasticsearch.action.ActionListener;
|
import org.elasticsearch.action.ActionListener;
|
||||||
import org.elasticsearch.action.ActionRequest;
|
import org.elasticsearch.action.ActionRequest;
|
||||||
import org.elasticsearch.action.ActionResponse;
|
import org.elasticsearch.action.ActionResponse;
|
||||||
|
import org.elasticsearch.action.ActionType;
|
||||||
import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
|
import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
|
||||||
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
|
import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
|
||||||
import org.elasticsearch.action.admin.indices.stats.IndexShardStats;
|
import org.elasticsearch.action.admin.indices.stats.IndexShardStats;
|
||||||
@ -45,6 +45,7 @@ import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesResponse;
|
|||||||
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
|
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
|
||||||
import org.elasticsearch.xpack.core.security.authz.permission.ResourcePrivileges;
|
import org.elasticsearch.xpack.core.security.authz.permission.ResourcePrivileges;
|
||||||
import org.elasticsearch.xpack.core.security.support.Exceptions;
|
import org.elasticsearch.xpack.core.security.support.Exceptions;
|
||||||
|
import org.elasticsearch.xpack.core.security.user.User;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -61,7 +62,7 @@ import java.util.stream.Collectors;
|
|||||||
/**
|
/**
|
||||||
* Encapsulates licensing checking for CCR.
|
* Encapsulates licensing checking for CCR.
|
||||||
*/
|
*/
|
||||||
public final class CcrLicenseChecker {
|
public class CcrLicenseChecker {
|
||||||
|
|
||||||
private final BooleanSupplier isCcrAllowed;
|
private final BooleanSupplier isCcrAllowed;
|
||||||
private final BooleanSupplier isAuthAllowed;
|
private final BooleanSupplier isAuthAllowed;
|
||||||
@ -307,9 +308,12 @@ public final class CcrLicenseChecker {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadContext threadContext = remoteClient.threadPool().getThreadContext();
|
final User user = getUser(remoteClient);
|
||||||
SecurityContext securityContext = new SecurityContext(Settings.EMPTY, threadContext);
|
if (user == null) {
|
||||||
String username = securityContext.getUser().principal();
|
handler.accept(new IllegalStateException("missing or unable to read authentication info on request"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String username = user.principal();
|
||||||
|
|
||||||
RoleDescriptor.IndicesPrivileges privileges = RoleDescriptor.IndicesPrivileges.builder()
|
RoleDescriptor.IndicesPrivileges privileges = RoleDescriptor.IndicesPrivileges.builder()
|
||||||
.indices(indices)
|
.indices(indices)
|
||||||
@ -344,6 +348,12 @@ public final class CcrLicenseChecker {
|
|||||||
remoteClient.execute(HasPrivilegesAction.INSTANCE, request, ActionListener.wrap(responseHandler, handler));
|
remoteClient.execute(HasPrivilegesAction.INSTANCE, request, ActionListener.wrap(responseHandler, handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
User getUser(final Client remoteClient) {
|
||||||
|
final ThreadContext threadContext = remoteClient.threadPool().getThreadContext();
|
||||||
|
final SecurityContext securityContext = new SecurityContext(Settings.EMPTY, threadContext);
|
||||||
|
return securityContext.getUser();
|
||||||
|
}
|
||||||
|
|
||||||
public static Client wrapClient(Client client, Map<String, String> headers) {
|
public static Client wrapClient(Client client, Map<String, String> headers) {
|
||||||
if (headers.isEmpty()) {
|
if (headers.isEmpty()) {
|
||||||
return client;
|
return client;
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.xpack.ccr;
|
||||||
|
|
||||||
|
import org.elasticsearch.client.Client;
|
||||||
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
import org.elasticsearch.xpack.core.security.user.User;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.hasToString;
|
||||||
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
|
public class CcrLicenseCheckerTests extends ESTestCase {
|
||||||
|
|
||||||
|
public void testNoAuthenticationInfo() {
|
||||||
|
final boolean isCcrAllowed = randomBoolean();
|
||||||
|
final CcrLicenseChecker checker = new CcrLicenseChecker(() -> isCcrAllowed, () -> true) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
User getUser(final Client remoteClient) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
final AtomicBoolean invoked = new AtomicBoolean();
|
||||||
|
checker.hasPrivilegesToFollowIndices(
|
||||||
|
mock(Client.class),
|
||||||
|
new String[]{randomAlphaOfLength(8)},
|
||||||
|
e -> {
|
||||||
|
invoked.set(true);
|
||||||
|
assertThat(e, instanceOf(IllegalStateException.class));
|
||||||
|
assertThat(e, hasToString(containsString("missing or unable to read authentication info on request")));
|
||||||
|
});
|
||||||
|
assertTrue(invoked.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user