Security: Remove SecurityLifecycleService (#30526)

This commit removes the SecurityLifecycleService, relegating its former
functions of listening for cluster state updates to SecurityIndexManager
and IndexAuditTrail.
This commit is contained in:
Ryan Ernst 2018-05-15 12:13:24 -07:00 committed by GitHub
parent 5894e3574f
commit 21b9170dec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 247 additions and 375 deletions

View File

@ -7,6 +7,7 @@ package org.elasticsearch.xpack.security;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.util.SetOnce;
import org.elasticsearch.ElasticsearchTimeoutException;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRequest;
@ -16,6 +17,7 @@ import org.elasticsearch.action.support.DestructiveOperations;
import org.elasticsearch.bootstrap.BootstrapCheck;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
@ -232,7 +234,7 @@ import static java.util.Collections.singletonList;
import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_FORMAT_SETTING;
import static org.elasticsearch.xpack.core.XPackSettings.HTTP_SSL_ENABLED;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_TEMPLATE_NAME;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.INTERNAL_INDEX_FORMAT;
public class Security extends Plugin implements ActionPlugin, IngestPlugin, NetworkPlugin, ClusterPlugin,
@ -261,6 +263,8 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
private final SetOnce<ThreadContext> threadContext = new SetOnce<>();
private final SetOnce<TokenService> tokenService = new SetOnce<>();
private final SetOnce<SecurityActionFilter> securityActionFilter = new SetOnce<>();
private final SetOnce<SecurityIndexManager> securityIndex = new SetOnce<>();
private final SetOnce<IndexAuditTrail> indexAuditTrail = new SetOnce<>();
private final List<BootstrapCheck> bootstrapChecks;
private final List<SecurityExtension> securityExtensions = new ArrayList<>();
@ -368,7 +372,6 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
components.add(securityContext.get());
// audit trails construction
IndexAuditTrail indexAuditTrail = null;
Set<AuditTrail> auditTrails = new LinkedHashSet<>();
if (XPackSettings.AUDIT_ENABLED.get(settings)) {
List<String> outputs = AUDIT_OUTPUTS_SETTING.get(settings);
@ -383,8 +386,8 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
auditTrails.add(new LoggingAuditTrail(settings, clusterService, threadPool));
break;
case IndexAuditTrail.NAME:
indexAuditTrail = new IndexAuditTrail(settings, client, threadPool, clusterService);
auditTrails.add(indexAuditTrail);
indexAuditTrail.set(new IndexAuditTrail(settings, client, threadPool, clusterService));
auditTrails.add(indexAuditTrail.get());
break;
default:
throw new IllegalArgumentException("Unknown audit trail output [" + output + "]");
@ -396,20 +399,20 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
components.add(auditTrailService);
this.auditTrailService.set(auditTrailService);
final SecurityLifecycleService securityLifecycleService =
new SecurityLifecycleService(settings, clusterService, threadPool, client, indexAuditTrail);
final TokenService tokenService = new TokenService(settings, Clock.systemUTC(), client, securityLifecycleService, clusterService);
securityIndex.set(new SecurityIndexManager(settings, client, SecurityIndexManager.SECURITY_INDEX_NAME, clusterService));
final TokenService tokenService = new TokenService(settings, Clock.systemUTC(), client, securityIndex.get(), clusterService);
this.tokenService.set(tokenService);
components.add(tokenService);
// realms construction
final NativeUsersStore nativeUsersStore = new NativeUsersStore(settings, client, securityLifecycleService);
final NativeRoleMappingStore nativeRoleMappingStore = new NativeRoleMappingStore(settings, client, securityLifecycleService);
final NativeUsersStore nativeUsersStore = new NativeUsersStore(settings, client, securityIndex.get());
final NativeRoleMappingStore nativeRoleMappingStore = new NativeRoleMappingStore(settings, client, securityIndex.get());
final AnonymousUser anonymousUser = new AnonymousUser(settings);
final ReservedRealm reservedRealm = new ReservedRealm(env, settings, nativeUsersStore,
anonymousUser, securityLifecycleService, threadPool.getThreadContext());
anonymousUser, securityIndex.get(), threadPool.getThreadContext());
Map<String, Realm.Factory> realmFactories = new HashMap<>(InternalRealms.getFactories(threadPool, resourceWatcherService,
getSslService(), nativeUsersStore, nativeRoleMappingStore, securityLifecycleService));
getSslService(), nativeUsersStore, nativeRoleMappingStore, securityIndex.get()));
for (SecurityExtension extension : securityExtensions) {
Map<String, Realm.Factory> newRealms = extension.getRealms(resourceWatcherService);
for (Map.Entry<String, Realm.Factory> entry : newRealms.entrySet()) {
@ -424,7 +427,7 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
components.add(realms);
components.add(reservedRealm);
securityLifecycleService.securityIndex().addIndexStateListener(nativeRoleMappingStore::onSecurityIndexStateChange);
securityIndex.get().addIndexStateListener(nativeRoleMappingStore::onSecurityIndexStateChange);
AuthenticationFailureHandler failureHandler = null;
String extensionName = null;
@ -449,7 +452,7 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
components.add(authcService.get());
final FileRolesStore fileRolesStore = new FileRolesStore(settings, env, resourceWatcherService, getLicenseState());
final NativeRolesStore nativeRolesStore = new NativeRolesStore(settings, client, getLicenseState(), securityLifecycleService);
final NativeRolesStore nativeRolesStore = new NativeRolesStore(settings, client, getLicenseState(), securityIndex.get());
final ReservedRolesStore reservedRolesStore = new ReservedRolesStore();
List<BiConsumer<Set<String>, ActionListener<Set<RoleDescriptor>>>> rolesProviders = new ArrayList<>();
for (SecurityExtension extension : securityExtensions) {
@ -457,7 +460,7 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
}
final CompositeRolesStore allRolesStore = new CompositeRolesStore(settings, fileRolesStore, nativeRolesStore,
reservedRolesStore, rolesProviders, threadPool.getThreadContext(), getLicenseState());
securityLifecycleService.securityIndex().addIndexStateListener(allRolesStore::onSecurityIndexStateChange);
securityIndex.get().addIndexStateListener(allRolesStore::onSecurityIndexStateChange);
// to keep things simple, just invalidate all cached entries on license change. this happens so rarely that the impact should be
// minimal
getLicenseState().addListener(allRolesStore::invalidateAll);
@ -468,8 +471,6 @@ public class Security extends Plugin implements ActionPlugin, IngestPlugin, Netw
components.add(allRolesStore); // for SecurityFeatureSet and clear roles cache
components.add(authzService);
components.add(securityLifecycleService);
ipFilter.set(new IPFilter(settings, auditTrailService, clusterService.getClusterSettings(), getLicenseState()));
components.add(ipFilter.get());
DestructiveOperations destructiveOperations = new DestructiveOperations(settings, clusterService.getClusterSettings());

View File

@ -1,129 +0,0 @@
/*
* 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.security;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.Version;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateListener;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.health.ClusterIndexHealth;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.component.LifecycleListener;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* This class is used to provide a lifecycle for services that is based on the cluster's state
* rather than the typical lifecycle that is used to start services as part of the node startup.
*
* This type of lifecycle is necessary for services that need to perform actions that require the
* cluster to be in a certain state; some examples are storing index templates and creating indices.
* These actions would most likely fail from within a plugin if executed in the
* {@link org.elasticsearch.common.component.AbstractLifecycleComponent#doStart()} method.
* However, if the startup of these services waits for the cluster to form and recover indices then
* it will be successful. This lifecycle service allows for this to happen by listening for
* {@link ClusterChangedEvent} and checking if the services can start. Additionally, the service
* also provides hooks for stop and close functionality.
*/
public class SecurityLifecycleService extends AbstractComponent implements ClusterStateListener {
public static final String INTERNAL_SECURITY_INDEX = SecurityIndexManager.INTERNAL_SECURITY_INDEX;
public static final String SECURITY_INDEX_NAME = ".security";
private final Settings settings;
private final ThreadPool threadPool;
private final IndexAuditTrail indexAuditTrail;
private final SecurityIndexManager securityIndex;
public SecurityLifecycleService(Settings settings, ClusterService clusterService,
ThreadPool threadPool, Client client,
@Nullable IndexAuditTrail indexAuditTrail) {
super(settings);
this.settings = settings;
this.threadPool = threadPool;
this.indexAuditTrail = indexAuditTrail;
this.securityIndex = new SecurityIndexManager(settings, client, SECURITY_INDEX_NAME);
clusterService.addListener(this);
clusterService.addLifecycleListener(new LifecycleListener() {
@Override
public void beforeStop() {
close();
}
});
}
@Override
public void clusterChanged(ClusterChangedEvent event) {
final ClusterState state = event.state();
if (state.blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK)) {
// wait until the gateway has recovered from disk, otherwise we think we don't have the
// .security index but they may not have been restored from the cluster state on disk
logger.debug("lifecycle service waiting until state has been recovered");
return;
}
securityIndex.clusterChanged(event);
try {
if (Security.indexAuditLoggingEnabled(settings) &&
indexAuditTrail.state() == IndexAuditTrail.State.INITIALIZED) {
if (indexAuditTrail.canStart(event)) {
threadPool.generic().execute(new AbstractRunnable() {
@Override
public void onFailure(Exception throwable) {
logger.error("failed to start index audit trail services", throwable);
assert false : "security lifecycle services startup failed";
}
@Override
public void doRun() {
indexAuditTrail.start();
}
});
}
}
} catch (Exception e) {
logger.error("failed to start index audit trail", e);
}
}
public SecurityIndexManager securityIndex() {
return securityIndex;
}
// this is called in a lifecycle listener beforeStop on the cluster service
private void close() {
if (indexAuditTrail != null) {
try {
indexAuditTrail.stop();
} catch (Exception e) {
logger.error("failed to stop audit trail module", e);
}
}
}
public static List<String> indexNames() {
return Collections.unmodifiableList(Arrays.asList(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX));
}
}

View File

@ -20,6 +20,7 @@ import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateListener;
import org.elasticsearch.cluster.metadata.AliasOrIndex;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
@ -29,12 +30,14 @@ import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.component.LifecycleListener;
import org.elasticsearch.common.network.NetworkAddress;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -110,7 +113,7 @@ import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECU
/**
* Audit trail implementation that writes events into an index.
*/
public class IndexAuditTrail extends AbstractComponent implements AuditTrail {
public class IndexAuditTrail extends AbstractComponent implements AuditTrail, ClusterStateListener {
public static final String NAME = "index";
public static final String DOC_TYPE = "doc";
@ -199,6 +202,13 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail {
} else {
this.client = initializeRemoteClient(settings, logger);
}
clusterService.addListener(this);
clusterService.addLifecycleListener(new LifecycleListener() {
@Override
public void beforeStop() {
stop();
}
});
}
@ -206,6 +216,29 @@ public class IndexAuditTrail extends AbstractComponent implements AuditTrail {
return state.get();
}
@Override
public void clusterChanged(ClusterChangedEvent event) {
try {
if (state() == IndexAuditTrail.State.INITIALIZED && canStart(event)) {
threadPool.generic().execute(new AbstractRunnable() {
@Override
public void onFailure(Exception throwable) {
logger.error("failed to start index audit trail services", throwable);
assert false : "security lifecycle services startup failed";
}
@Override
public void doRun() {
start();
}
});
}
} catch (Exception e) {
logger.error("failed to start index audit trail", e);
}
}
/**
* This method determines if this service can be started based on the state in the {@link ClusterChangedEvent} and
* if the node is the master or not. When using remote indexing, a call to the remote cluster will be made to retrieve

View File

@ -22,7 +22,7 @@ import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.index.reindex.ScrollableHitSource;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.threadpool.ThreadPool.Names;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
@ -50,7 +50,7 @@ final class ExpiredTokenRemover extends AbstractRunnable {
@Override
public void doRun() {
SearchRequest searchRequest = new SearchRequest(SecurityLifecycleService.SECURITY_INDEX_NAME);
SearchRequest searchRequest = new SearchRequest(SecurityIndexManager.SECURITY_INDEX_NAME);
DeleteByQueryRequest expiredDbq = new DeleteByQueryRequest(searchRequest);
if (timeout != TimeValue.MINUS_ONE) {
expiredDbq.setTimeout(timeout);

View File

@ -20,7 +20,6 @@ import org.elasticsearch.xpack.core.security.authc.ldap.LdapRealmSettings;
import org.elasticsearch.xpack.core.security.authc.pki.PkiRealmSettings;
import org.elasticsearch.xpack.core.security.authc.saml.SamlRealmSettings;
import org.elasticsearch.xpack.core.ssl.SSLService;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.esnative.NativeRealm;
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
@ -30,6 +29,7 @@ import org.elasticsearch.xpack.security.authc.pki.PkiRealm;
import org.elasticsearch.xpack.security.authc.saml.SamlRealm;
import org.elasticsearch.xpack.security.authc.support.RoleMappingFileBootstrapCheck;
import org.elasticsearch.xpack.security.authc.support.mapper.NativeRoleMappingStore;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.util.ArrayList;
import java.util.Arrays;
@ -90,13 +90,13 @@ public final class InternalRealms {
public static Map<String, Realm.Factory> getFactories(ThreadPool threadPool, ResourceWatcherService resourceWatcherService,
SSLService sslService, NativeUsersStore nativeUsersStore,
NativeRoleMappingStore nativeRoleMappingStore,
SecurityLifecycleService securityLifecycleService) {
SecurityIndexManager securityIndex) {
Map<String, Realm.Factory> map = new HashMap<>();
map.put(FileRealmSettings.TYPE, config -> new FileRealm(config, resourceWatcherService));
map.put(NativeRealmSettings.TYPE, config -> {
final NativeRealm nativeRealm = new NativeRealm(config, nativeUsersStore);
securityLifecycleService.securityIndex().addIndexStateListener(nativeRealm::onSecurityIndexStateChange);
securityIndex.addIndexStateListener(nativeRealm::onSecurityIndexStateChange);
return nativeRealm;
});
map.put(LdapRealmSettings.AD_TYPE, config -> new LdapRealm(LdapRealmSettings.AD_TYPE, config, sslService,

View File

@ -9,7 +9,6 @@ import org.apache.logging.log4j.message.ParameterizedMessage;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.elasticsearch.core.internal.io.IOUtils;
import org.apache.lucene.util.StringHelper;
import org.apache.lucene.util.UnicodeUtil;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.ExceptionsHelper;
@ -70,7 +69,7 @@ import org.elasticsearch.xpack.core.security.ScrollHelper;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.KeyAndTimestamp;
import org.elasticsearch.xpack.core.security.authc.TokenMetaData;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
@ -161,7 +160,7 @@ public final class TokenService extends AbstractComponent {
private final TimeValue expirationDelay;
private final TimeValue deleteInterval;
private final Client client;
private final SecurityLifecycleService lifecycleService;
private final SecurityIndexManager securityIndex;
private final ExpiredTokenRemover expiredTokenRemover;
private final boolean enabled;
private volatile TokenKeys keyCache;
@ -176,7 +175,7 @@ public final class TokenService extends AbstractComponent {
* @param client the client to use when checking for revocations
*/
public TokenService(Settings settings, Clock clock, Client client,
SecurityLifecycleService lifecycleService, ClusterService clusterService) throws GeneralSecurityException {
SecurityIndexManager securityIndex, ClusterService clusterService) throws GeneralSecurityException {
super(settings);
byte[] saltArr = new byte[SALT_BYTES];
secureRandom.nextBytes(saltArr);
@ -185,7 +184,7 @@ public final class TokenService extends AbstractComponent {
this.clock = clock.withZone(ZoneOffset.UTC);
this.expirationDelay = TOKEN_EXPIRATION.get(settings);
this.client = client;
this.lifecycleService = lifecycleService;
this.securityIndex = securityIndex;
this.lastExpirationRunMs = client.threadPool().relativeTimeInMillis();
this.deleteInterval = DELETE_INTERVAL.get(settings);
this.enabled = isTokenServiceEnabled(settings);
@ -245,12 +244,12 @@ public final class TokenService extends AbstractComponent {
.endObject();
builder.endObject();
IndexRequest request =
client.prepareIndex(SecurityLifecycleService.SECURITY_INDEX_NAME, TYPE, getTokenDocumentId(userToken))
client.prepareIndex(SecurityIndexManager.SECURITY_INDEX_NAME, TYPE, getTokenDocumentId(userToken))
.setOpType(OpType.CREATE)
.setSource(builder)
.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL)
.request();
lifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
executeAsyncWithOrigin(client, SECURITY_ORIGIN, IndexAction.INSTANCE, request,
ActionListener.wrap(indexResponse -> listener.onResponse(new Tuple<>(userToken, refreshToken)),
listener::onFailure))
@ -354,9 +353,9 @@ public final class TokenService extends AbstractComponent {
if (version.onOrAfter(Version.V_6_2_0)) {
// we only have the id and need to get the token from the doc!
decryptTokenId(in, cipher, version, ActionListener.wrap(tokenId ->
lifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
final GetRequest getRequest =
client.prepareGet(SecurityLifecycleService.SECURITY_INDEX_NAME, TYPE,
client.prepareGet(SecurityIndexManager.SECURITY_INDEX_NAME, TYPE,
getTokenDocumentId(tokenId)).request();
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN, getRequest,
ActionListener.<GetResponse>wrap(response -> {
@ -517,14 +516,14 @@ public final class TokenService extends AbstractComponent {
listener.onFailure(invalidGrantException("failed to invalidate token"));
} else {
final String invalidatedTokenId = getInvalidatedTokenDocumentId(userToken);
IndexRequest indexRequest = client.prepareIndex(SecurityLifecycleService.SECURITY_INDEX_NAME, TYPE, invalidatedTokenId)
IndexRequest indexRequest = client.prepareIndex(SecurityIndexManager.SECURITY_INDEX_NAME, TYPE, invalidatedTokenId)
.setOpType(OpType.CREATE)
.setSource("doc_type", INVALIDATED_TOKEN_DOC_TYPE, "expiration_time", expirationEpochMilli)
.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL)
.request();
final String tokenDocId = getTokenDocumentId(userToken);
final Version version = userToken.getVersion();
lifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN, indexRequest,
ActionListener.<IndexResponse>wrap(indexResponse -> {
ActionListener<Boolean> wrappedListener =
@ -561,12 +560,12 @@ public final class TokenService extends AbstractComponent {
if (attemptCount.get() > 5) {
listener.onFailure(invalidGrantException("failed to invalidate token"));
} else {
UpdateRequest request = client.prepareUpdate(SecurityLifecycleService.SECURITY_INDEX_NAME, TYPE, tokenDocId)
UpdateRequest request = client.prepareUpdate(SecurityIndexManager.SECURITY_INDEX_NAME, TYPE, tokenDocId)
.setDoc(srcPrefix, Collections.singletonMap("invalidated", true))
.setVersion(documentVersion)
.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL)
.request();
lifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN, request,
ActionListener.<UpdateResponse>wrap(updateResponse -> {
if (updateResponse.getGetResult() != null
@ -593,7 +592,7 @@ public final class TokenService extends AbstractComponent {
|| isShardNotAvailableException(cause)) {
attemptCount.incrementAndGet();
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareGet(SecurityLifecycleService.SECURITY_INDEX_NAME, TYPE, tokenDocId).request(),
client.prepareGet(SecurityIndexManager.SECURITY_INDEX_NAME, TYPE, tokenDocId).request(),
ActionListener.<GetResponse>wrap(getResult -> {
if (getResult.isExists()) {
Map<String, Object> source = getResult.getSource();
@ -658,14 +657,14 @@ public final class TokenService extends AbstractComponent {
if (attemptCount.get() > 5) {
listener.onFailure(invalidGrantException("could not refresh the requested token"));
} else {
SearchRequest request = client.prepareSearch(SecurityLifecycleService.SECURITY_INDEX_NAME)
SearchRequest request = client.prepareSearch(SecurityIndexManager.SECURITY_INDEX_NAME)
.setQuery(QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("doc_type", "token"))
.filter(QueryBuilders.termQuery("refresh_token.token", refreshToken)))
.setVersion(true)
.request();
lifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN, request,
ActionListener.<SearchResponse>wrap(searchResponse -> {
if (searchResponse.isTimedOut()) {
@ -702,7 +701,7 @@ public final class TokenService extends AbstractComponent {
if (attemptCount.getAndIncrement() > 5) {
listener.onFailure(invalidGrantException("could not refresh the requested token"));
} else {
GetRequest getRequest = client.prepareGet(SecurityLifecycleService.SECURITY_INDEX_NAME, TYPE, tokenDocId).request();
GetRequest getRequest = client.prepareGet(SecurityIndexManager.SECURITY_INDEX_NAME, TYPE, tokenDocId).request();
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN, getRequest,
ActionListener.<GetResponse>wrap(response -> {
if (response.isExists()) {
@ -723,7 +722,7 @@ public final class TokenService extends AbstractComponent {
in.setVersion(authVersion);
Authentication authentication = new Authentication(in);
UpdateRequest updateRequest =
client.prepareUpdate(SecurityLifecycleService.SECURITY_INDEX_NAME, TYPE, tokenDocId)
client.prepareUpdate(SecurityIndexManager.SECURITY_INDEX_NAME, TYPE, tokenDocId)
.setVersion(response.getVersion())
.setDoc("refresh_token", Collections.singletonMap("refreshed", true))
.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL)
@ -838,7 +837,7 @@ public final class TokenService extends AbstractComponent {
.should(QueryBuilders.termQuery("refresh_token.invalidated", false))
);
final SearchRequest request = client.prepareSearch(SecurityLifecycleService.SECURITY_INDEX_NAME)
final SearchRequest request = client.prepareSearch(SecurityIndexManager.SECURITY_INDEX_NAME)
.setScroll(TimeValue.timeValueSeconds(10L))
.setQuery(boolQuery)
.setVersion(false)
@ -847,7 +846,7 @@ public final class TokenService extends AbstractComponent {
.request();
final Supplier<ThreadContext.StoredContext> supplier = client.threadPool().getThreadContext().newRestorableContext(false);
lifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
ScrollHelper.fetchAllByEntity(client, request, new ContextPreservingActionListener<>(supplier, listener), this::parseHit));
}
@ -914,14 +913,14 @@ public final class TokenService extends AbstractComponent {
* have been explicitly cleared.
*/
private void checkIfTokenIsRevoked(UserToken userToken, ActionListener<UserToken> listener) {
if (lifecycleService.securityIndex().indexExists() == false) {
if (securityIndex.indexExists() == false) {
// index doesn't exist so the token is considered valid.
listener.onResponse(userToken);
} else {
lifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
MultiGetRequest mGetRequest = client.prepareMultiGet()
.add(SecurityLifecycleService.SECURITY_INDEX_NAME, TYPE, getInvalidatedTokenDocumentId(userToken))
.add(SecurityLifecycleService.SECURITY_INDEX_NAME, TYPE, getTokenDocumentId(userToken))
.add(SecurityIndexManager.SECURITY_INDEX_NAME, TYPE, getInvalidatedTokenDocumentId(userToken))
.add(SecurityIndexManager.SECURITY_INDEX_NAME, TYPE, getTokenDocumentId(userToken))
.request();
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
mGetRequest,
@ -989,7 +988,7 @@ public final class TokenService extends AbstractComponent {
}
private void maybeStartTokenRemover() {
if (lifecycleService.securityIndex().isAvailable()) {
if (securityIndex.isAvailable()) {
if (client.threadPool().relativeTimeInMillis() - lastExpirationRunMs > deleteInterval.getMillis()) {
expiredTokenRemover.submit(client.threadPool());
lastExpirationRunMs = client.threadPool().relativeTimeInMillis();

View File

@ -50,7 +50,7 @@ import org.elasticsearch.xpack.core.security.user.SystemUser;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.security.user.User.Fields;
import org.elasticsearch.xpack.core.security.user.XPackUser;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.util.Arrays;
import java.util.Collection;
@ -64,7 +64,7 @@ import java.util.function.Supplier;
import static org.elasticsearch.xpack.core.ClientHelper.SECURITY_ORIGIN;
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
import static org.elasticsearch.xpack.core.ClientHelper.stashWithOrigin;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
/**
* NativeUsersStore is a store for users that reads from an Elasticsearch index. This store is responsible for fetching the full
@ -83,12 +83,12 @@ public class NativeUsersStore extends AbstractComponent {
private final Hasher hasher = Hasher.BCRYPT;
private final Client client;
private volatile SecurityLifecycleService securityLifecycleService;
private final SecurityIndexManager securityIndex;
public NativeUsersStore(Settings settings, Client client, SecurityLifecycleService securityLifecycleService) {
public NativeUsersStore(Settings settings, Client client, SecurityIndexManager securityIndex) {
super(settings);
this.client = client;
this.securityLifecycleService = securityLifecycleService;
this.securityIndex = securityIndex;
}
/**
@ -114,7 +114,7 @@ public class NativeUsersStore extends AbstractComponent {
}
};
if (securityLifecycleService.securityIndex().indexExists() == false) {
if (securityIndex.indexExists() == false) {
// TODO remove this short circuiting and fix tests that fail without this!
listener.onResponse(Collections.emptyList());
} else if (userNames.length == 1) { // optimization for single user lookup
@ -123,7 +123,7 @@ public class NativeUsersStore extends AbstractComponent {
(uap) -> listener.onResponse(uap == null ? Collections.emptyList() : Collections.singletonList(uap.user())),
handleException));
} else {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
final QueryBuilder query;
if (userNames == null || userNames.length == 0) {
query = QueryBuilders.termQuery(Fields.TYPE.getPreferredName(), USER_DOC_TYPE);
@ -154,11 +154,11 @@ public class NativeUsersStore extends AbstractComponent {
* Async method to retrieve a user and their password
*/
private void getUserAndPassword(final String user, final ActionListener<UserAndPassword> listener) {
if (securityLifecycleService.securityIndex().indexExists() == false) {
if (securityIndex.indexExists() == false) {
// TODO remove this short circuiting and fix tests that fail without this!
listener.onResponse(null);
} else {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareGet(SECURITY_INDEX_NAME,
INDEX_TYPE, getIdForUser(USER_DOC_TYPE, user)).request(),
@ -199,7 +199,7 @@ public class NativeUsersStore extends AbstractComponent {
docType = USER_DOC_TYPE;
}
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareUpdate(SECURITY_INDEX_NAME, INDEX_TYPE, getIdForUser(docType, username))
.setDoc(Requests.INDEX_CONTENT_TYPE, Fields.PASSWORD.getPreferredName(),
@ -237,7 +237,7 @@ public class NativeUsersStore extends AbstractComponent {
* has been indexed
*/
private void createReservedUser(String username, char[] passwordHash, RefreshPolicy refresh, ActionListener<Void> listener) {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareIndex(SECURITY_INDEX_NAME, INDEX_TYPE,
getIdForUser(RESERVED_USER_TYPE, username))
@ -279,7 +279,7 @@ public class NativeUsersStore extends AbstractComponent {
private void updateUserWithoutPassword(final PutUserRequest putUserRequest, final ActionListener<Boolean> listener) {
assert putUserRequest.passwordHash() == null;
// We must have an existing document
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareUpdate(SECURITY_INDEX_NAME, INDEX_TYPE,
getIdForUser(USER_DOC_TYPE, putUserRequest.username()))
@ -322,7 +322,7 @@ public class NativeUsersStore extends AbstractComponent {
private void indexUser(final PutUserRequest putUserRequest, final ActionListener<Boolean> listener) {
assert putUserRequest.passwordHash() != null;
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareIndex(SECURITY_INDEX_NAME, INDEX_TYPE,
getIdForUser(USER_DOC_TYPE, putUserRequest.username()))
@ -366,7 +366,7 @@ public class NativeUsersStore extends AbstractComponent {
private void setRegularUserEnabled(final String username, final boolean enabled, final RefreshPolicy refreshPolicy,
final ActionListener<Void> listener) {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareUpdate(SECURITY_INDEX_NAME, INDEX_TYPE,
getIdForUser(USER_DOC_TYPE, username))
@ -401,7 +401,7 @@ public class NativeUsersStore extends AbstractComponent {
private void setReservedUserEnabled(final String username, final boolean enabled, final RefreshPolicy refreshPolicy,
boolean clearCache, final ActionListener<Void> listener) {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareUpdate(SECURITY_INDEX_NAME, INDEX_TYPE,
getIdForUser(RESERVED_USER_TYPE, username))
@ -431,7 +431,7 @@ public class NativeUsersStore extends AbstractComponent {
}
public void deleteUser(final DeleteUserRequest deleteUserRequest, final ActionListener<Boolean> listener) {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
DeleteRequest request = client.prepareDelete(SECURITY_INDEX_NAME,
INDEX_TYPE, getIdForUser(USER_DOC_TYPE, deleteUserRequest.username())).request();
request.setRefreshPolicy(deleteUserRequest.getRefreshPolicy());
@ -470,11 +470,11 @@ public class NativeUsersStore extends AbstractComponent {
}
void getReservedUserInfo(String username, ActionListener<ReservedUserInfo> listener) {
if (securityLifecycleService.securityIndex().indexExists() == false) {
if (securityIndex.indexExists() == false) {
// TODO remove this short circuiting and fix tests that fail without this!
listener.onResponse(null);
} else {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareGet(SECURITY_INDEX_NAME, INDEX_TYPE,
getIdForUser(RESERVED_USER_TYPE, username)).request(),
@ -514,7 +514,7 @@ public class NativeUsersStore extends AbstractComponent {
}
void getAllReservedUserInfo(ActionListener<Map<String, ReservedUserInfo>> listener) {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareSearch(SECURITY_INDEX_NAME)
.setQuery(QueryBuilders.termQuery(Fields.TYPE.getPreferredName(), RESERVED_USER_TYPE))

View File

@ -30,9 +30,9 @@ import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.LogstashSystemUser;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore.ReservedUserInfo;
import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.util.ArrayList;
import java.util.Arrays;
@ -63,16 +63,16 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
private final AnonymousUser anonymousUser;
private final boolean realmEnabled;
private final boolean anonymousEnabled;
private final SecurityLifecycleService securityLifecycleService;
private final SecurityIndexManager securityIndex;
public ReservedRealm(Environment env, Settings settings, NativeUsersStore nativeUsersStore, AnonymousUser anonymousUser,
SecurityLifecycleService securityLifecycleService, ThreadContext threadContext) {
SecurityIndexManager securityIndex, ThreadContext threadContext) {
super(TYPE, new RealmConfig(TYPE, Settings.EMPTY, settings, env, threadContext));
this.nativeUsersStore = nativeUsersStore;
this.realmEnabled = XPackSettings.RESERVED_REALM_ENABLED_SETTING.get(settings);
this.anonymousUser = anonymousUser;
this.anonymousEnabled = AnonymousUser.isAnonymousEnabled(settings);
this.securityLifecycleService = securityLifecycleService;
this.securityIndex = securityIndex;
final char[] hash = BOOTSTRAP_ELASTIC_PASSWORD.get(settings).length() == 0 ? EMPTY_PASSWORD_HASH :
Hasher.BCRYPT.hash(BOOTSTRAP_ELASTIC_PASSWORD.get(settings));
bootstrapUserInfo = new ReservedUserInfo(hash, true, hash == EMPTY_PASSWORD_HASH);
@ -191,7 +191,7 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
if (userIsDefinedForCurrentSecurityMapping(username) == false) {
logger.debug("Marking user [{}] as disabled because the security mapping is not at the required version", username);
listener.onResponse(DISABLED_DEFAULT_USER_INFO.deepClone());
} else if (securityLifecycleService.securityIndex().indexExists() == false) {
} else if (securityIndex.indexExists() == false) {
listener.onResponse(getDefaultUserInfo(username));
} else {
nativeUsersStore.getReservedUserInfo(username, ActionListener.wrap((userInfo) -> {
@ -218,7 +218,7 @@ public class ReservedRealm extends CachingUsernamePasswordRealm {
private boolean userIsDefinedForCurrentSecurityMapping(String username) {
final Version requiredVersion = getDefinedVersion(username);
return securityLifecycleService.securityIndex().checkMappingVersion(requiredVersion::onOrBefore);
return securityIndex.checkMappingVersion(requiredVersion::onOrBefore);
}
private Version getDefinedVersion(String username) {

View File

@ -12,8 +12,6 @@ import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.ContextPreservingActionListener;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.health.ClusterIndexHealth;
import org.elasticsearch.common.CheckedBiConsumer;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.component.AbstractComponent;
@ -36,7 +34,6 @@ import org.elasticsearch.xpack.core.security.action.rolemapping.PutRoleMappingRe
import org.elasticsearch.xpack.core.security.authc.support.mapper.ExpressionRoleMapping;
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.ExpressionModel;
import org.elasticsearch.xpack.core.security.client.SecurityClient;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm;
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
@ -62,13 +59,13 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.xpack.core.ClientHelper.SECURITY_ORIGIN;
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
import static org.elasticsearch.xpack.core.ClientHelper.stashWithOrigin;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.isIndexDeleted;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.isMoveFromRedToNonRed;
/**
* This store reads + writes {@link ExpressionRoleMapping role mappings} in an Elasticsearch
* {@link SecurityLifecycleService#SECURITY_INDEX_NAME index}.
* {@link SecurityIndexManager#SECURITY_INDEX_NAME index}.
* <br>
* The store is responsible for all read and write operations as well as
* {@link #resolveRoles(UserData, ActionListener) resolving roles}.
@ -99,13 +96,13 @@ public class NativeRoleMappingStore extends AbstractComponent implements UserRol
};
private final Client client;
private final SecurityLifecycleService securityLifecycleService;
private final SecurityIndexManager securityIndex;
private final List<String> realmsToRefresh = new CopyOnWriteArrayList<>();
public NativeRoleMappingStore(Settings settings, Client client, SecurityLifecycleService securityLifecycleService) {
public NativeRoleMappingStore(Settings settings, Client client, SecurityIndexManager securityIndex) {
super(settings);
this.client = client;
this.securityLifecycleService = securityLifecycleService;
this.securityIndex = securityIndex;
}
private String getNameFromId(String id) {
@ -122,7 +119,7 @@ public class NativeRoleMappingStore extends AbstractComponent implements UserRol
* <em>package private</em> for unit testing
*/
void loadMappings(ActionListener<List<ExpressionRoleMapping>> listener) {
if (securityLifecycleService.securityIndex().isIndexUpToDate() == false) {
if (securityIndex.isIndexUpToDate() == false) {
listener.onFailure(new IllegalStateException(
"Security index is not on the current version - the native realm will not be operational until " +
"the upgrade API is run on the security index"));
@ -178,7 +175,7 @@ public class NativeRoleMappingStore extends AbstractComponent implements UserRol
private <Request, Result> void modifyMapping(String name, CheckedBiConsumer<Request, ActionListener<Result>, Exception> inner,
Request request, ActionListener<Result> listener) {
if (securityLifecycleService.securityIndex().isIndexUpToDate() == false) {
if (securityIndex.isIndexUpToDate() == false) {
listener.onFailure(new IllegalStateException(
"Security index is not on the current version - the native realm will not be operational until " +
"the upgrade API is run on the security index"));
@ -194,7 +191,7 @@ public class NativeRoleMappingStore extends AbstractComponent implements UserRol
private void innerPutMapping(PutRoleMappingRequest request, ActionListener<Boolean> listener) {
final ExpressionRoleMapping mapping = request.getMapping();
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
final XContentBuilder xContentBuilder;
try {
xContentBuilder = mapping.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS, true);
@ -224,7 +221,7 @@ public class NativeRoleMappingStore extends AbstractComponent implements UserRol
}
private void innerDeleteMapping(DeleteRoleMappingRequest request, ActionListener<Boolean> listener) throws IOException {
if (securityLifecycleService.securityIndex().isIndexUpToDate() == false) {
if (securityIndex.isIndexUpToDate() == false) {
listener.onFailure(new IllegalStateException(
"Security index is not on the current version - the native realm will not be operational until " +
"the upgrade API is run on the security index"));
@ -278,16 +275,16 @@ public class NativeRoleMappingStore extends AbstractComponent implements UserRol
}
private void getMappings(ActionListener<List<ExpressionRoleMapping>> listener) {
if (securityLifecycleService.securityIndex().isAvailable()) {
if (securityIndex.isAvailable()) {
loadMappings(listener);
} else {
logger.info("The security index is not yet available - no role mappings can be loaded");
if (logger.isDebugEnabled()) {
logger.debug("Security Index [{}] [exists: {}] [available: {}] [mapping up to date: {}]",
SECURITY_INDEX_NAME,
securityLifecycleService.securityIndex().indexExists(),
securityLifecycleService.securityIndex().isAvailable(),
securityLifecycleService.securityIndex().isMappingUpToDate()
securityIndex.indexExists(),
securityIndex.isAvailable(),
securityIndex.isMappingUpToDate()
);
}
listener.onResponse(Collections.emptyList());
@ -304,7 +301,7 @@ public class NativeRoleMappingStore extends AbstractComponent implements UserRol
* </ul>
*/
public void usageStats(ActionListener<Map<String, Object>> listener) {
if (securityLifecycleService.securityIndex().indexExists() == false) {
if (securityIndex.indexExists() == false) {
reportStats(listener, Collections.emptyList());
} else {
getMappings(ActionListener.wrap(mappings -> reportStats(listener, mappings), listener::onFailure));

View File

@ -60,11 +60,11 @@ import org.elasticsearch.xpack.core.security.user.SystemUser;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.security.user.XPackSecurityUser;
import org.elasticsearch.xpack.core.security.user.XPackUser;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.audit.AuditTrailService;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.elasticsearch.xpack.security.authz.IndicesAndAliasesResolver.ResolvedIndices;
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.util.Arrays;
import java.util.Collections;
@ -301,7 +301,7 @@ public class AuthorizationService extends AbstractComponent {
// only the XPackUser is allowed to work with this index, but we should allow indices monitoring actions through for debugging
// purposes. These monitor requests also sometimes resolve indices concretely and then requests them
logger.debug("user [{}] attempted to directly perform [{}] against the security index [{}]",
authentication.getUser().principal(), action, SecurityLifecycleService.SECURITY_INDEX_NAME);
authentication.getUser().principal(), action, SecurityIndexManager.SECURITY_INDEX_NAME);
throw denial(authentication, action, request, permission.names());
} else {
putTransientIfNonExisting(AuthorizationServiceField.INDICES_PERMISSIONS_KEY, indicesAccessControl);
@ -337,7 +337,7 @@ public class AuthorizationService extends AbstractComponent {
}
private boolean hasSecurityIndexAccess(IndicesAccessControl indicesAccessControl) {
for (String index : SecurityLifecycleService.indexNames()) {
for (String index : SecurityIndexManager.indexNames()) {
final IndicesAccessControl.IndexAccessControl indexPermissions = indicesAccessControl.getIndexPermissions(index);
if (indexPermissions != null && indexPermissions.isGranted()) {
return true;

View File

@ -9,7 +9,7 @@ import org.elasticsearch.cluster.metadata.AliasOrIndex;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.xpack.core.security.authz.permission.Role;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.util.ArrayList;
import java.util.Collections;
@ -58,7 +58,7 @@ class AuthorizedIndices {
if (isSuperuser(user) == false) {
// we should filter out all of the security indices from wildcards
indicesAndAliases.removeAll(SecurityLifecycleService.indexNames());
indicesAndAliases.removeAll(SecurityIndexManager.indexNames());
}
return Collections.unmodifiableList(indicesAndAliases);
}

View File

@ -7,8 +7,6 @@ package org.elasticsearch.xpack.security.authz.store;
import org.apache.logging.log4j.message.ParameterizedMessage;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.health.ClusterIndexHealth;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
@ -34,7 +32,6 @@ import org.elasticsearch.xpack.core.security.authz.privilege.ClusterPrivilege;
import org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege;
import org.elasticsearch.xpack.core.security.authz.privilege.Privilege;
import org.elasticsearch.xpack.core.security.authz.store.ReservedRolesStore;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.util.ArrayList;

View File

@ -43,7 +43,7 @@ import org.elasticsearch.xpack.core.security.action.role.PutRoleRequest;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor.IndicesPrivileges;
import org.elasticsearch.xpack.core.security.client.SecurityClient;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.io.IOException;
import java.util.ArrayList;
@ -85,22 +85,21 @@ public class NativeRolesStore extends AbstractComponent {
private final XPackLicenseState licenseState;
private SecurityClient securityClient;
private final SecurityLifecycleService securityLifecycleService;
private final SecurityIndexManager securityIndex;
public NativeRolesStore(Settings settings, Client client, XPackLicenseState licenseState,
SecurityLifecycleService securityLifecycleService) {
public NativeRolesStore(Settings settings, Client client, XPackLicenseState licenseState, SecurityIndexManager securityIndex) {
super(settings);
this.client = client;
this.securityClient = new SecurityClient(client);
this.licenseState = licenseState;
this.securityLifecycleService = securityLifecycleService;
this.securityIndex = securityIndex;
}
/**
* Retrieve a list of roles, if rolesToGet is null or empty, fetch all roles
*/
public void getRoleDescriptors(String[] names, final ActionListener<Collection<RoleDescriptor>> listener) {
if (securityLifecycleService.securityIndex().indexExists() == false) {
if (securityIndex.indexExists() == false) {
// TODO remove this short circuiting and fix tests that fail without this!
listener.onResponse(Collections.emptyList());
} else if (names != null && names.length == 1) {
@ -108,7 +107,7 @@ public class NativeRolesStore extends AbstractComponent {
listener.onResponse(roleDescriptor == null ? Collections.emptyList() : Collections.singletonList(roleDescriptor)),
listener::onFailure));
} else {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
QueryBuilder query;
if (names == null || names.length == 0) {
query = QueryBuilders.termQuery(RoleDescriptor.Fields.TYPE.getPreferredName(), ROLE_TYPE);
@ -118,7 +117,7 @@ public class NativeRolesStore extends AbstractComponent {
}
final Supplier<ThreadContext.StoredContext> supplier = client.threadPool().getThreadContext().newRestorableContext(false);
try (ThreadContext.StoredContext ignore = stashWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN)) {
SearchRequest request = client.prepareSearch(SecurityLifecycleService.SECURITY_INDEX_NAME)
SearchRequest request = client.prepareSearch(SecurityIndexManager.SECURITY_INDEX_NAME)
.setScroll(TimeValue.timeValueSeconds(10L))
.setQuery(query)
.setSize(1000)
@ -133,8 +132,8 @@ public class NativeRolesStore extends AbstractComponent {
}
public void deleteRole(final DeleteRoleRequest deleteRoleRequest, final ActionListener<Boolean> listener) {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
DeleteRequest request = client.prepareDelete(SecurityLifecycleService.SECURITY_INDEX_NAME,
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
DeleteRequest request = client.prepareDelete(SecurityIndexManager.SECURITY_INDEX_NAME,
ROLE_DOC_TYPE, getIdForUser(deleteRoleRequest.name())).request();
request.setRefreshPolicy(deleteRoleRequest.getRefreshPolicy());
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN, request,
@ -166,7 +165,7 @@ public class NativeRolesStore extends AbstractComponent {
// pkg-private for testing
void innerPutRole(final PutRoleRequest request, final RoleDescriptor role, final ActionListener<Boolean> listener) {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () -> {
final XContentBuilder xContentBuilder;
try {
xContentBuilder = role.toXContent(jsonBuilder(), ToXContent.EMPTY_PARAMS, true);
@ -175,7 +174,7 @@ public class NativeRolesStore extends AbstractComponent {
return;
}
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareIndex(SecurityLifecycleService.SECURITY_INDEX_NAME, ROLE_DOC_TYPE, getIdForUser(role.getName()))
client.prepareIndex(SecurityIndexManager.SECURITY_INDEX_NAME, ROLE_DOC_TYPE, getIdForUser(role.getName()))
.setSource(xContentBuilder)
.setRefreshPolicy(request.getRefreshPolicy())
.request(),
@ -197,19 +196,19 @@ public class NativeRolesStore extends AbstractComponent {
public void usageStats(ActionListener<Map<String, Object>> listener) {
Map<String, Object> usageStats = new HashMap<>();
if (securityLifecycleService.securityIndex().indexExists() == false) {
if (securityIndex.indexExists() == false) {
usageStats.put("size", 0L);
usageStats.put("fls", false);
usageStats.put("dls", false);
listener.onResponse(usageStats);
} else {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareMultiSearch()
.add(client.prepareSearch(SecurityLifecycleService.SECURITY_INDEX_NAME)
.add(client.prepareSearch(SecurityIndexManager.SECURITY_INDEX_NAME)
.setQuery(QueryBuilders.termQuery(RoleDescriptor.Fields.TYPE.getPreferredName(), ROLE_TYPE))
.setSize(0))
.add(client.prepareSearch(SecurityLifecycleService.SECURITY_INDEX_NAME)
.add(client.prepareSearch(SecurityIndexManager.SECURITY_INDEX_NAME)
.setQuery(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery(RoleDescriptor.Fields.TYPE.getPreferredName(), ROLE_TYPE))
.must(QueryBuilders.boolQuery()
@ -219,7 +218,7 @@ public class NativeRolesStore extends AbstractComponent {
.should(existsQuery("indices.fields"))))
.setSize(0)
.setTerminateAfter(1))
.add(client.prepareSearch(SecurityLifecycleService.SECURITY_INDEX_NAME)
.add(client.prepareSearch(SecurityIndexManager.SECURITY_INDEX_NAME)
.setQuery(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery(RoleDescriptor.Fields.TYPE.getPreferredName(), ROLE_TYPE))
.filter(existsQuery("indices.query")))
@ -259,11 +258,11 @@ public class NativeRolesStore extends AbstractComponent {
}
private void getRoleDescriptor(final String roleId, ActionListener<RoleDescriptor> roleActionListener) {
if (securityLifecycleService.securityIndex().indexExists() == false) {
if (securityIndex.indexExists() == false) {
// TODO remove this short circuiting and fix tests that fail without this!
roleActionListener.onResponse(null);
} else {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(roleActionListener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(roleActionListener::onFailure, () ->
executeGetRoleRequest(roleId, new ActionListener<GetResponse>() {
@Override
public void onResponse(GetResponse response) {
@ -288,9 +287,9 @@ public class NativeRolesStore extends AbstractComponent {
}
private void executeGetRoleRequest(String role, ActionListener<GetResponse> listener) {
securityLifecycleService.securityIndex().prepareIndexIfNeededThenExecute(listener::onFailure, () ->
securityIndex.prepareIndexIfNeededThenExecute(listener::onFailure, () ->
executeAsyncWithOrigin(client.threadPool().getThreadContext(), SECURITY_ORIGIN,
client.prepareGet(SecurityLifecycleService.SECURITY_INDEX_NAME,
client.prepareGet(SecurityIndexManager.SECURITY_INDEX_NAME,
ROLE_DOC_TYPE, getIdForUser(role)).request(),
listener,
client::get));

View File

@ -23,6 +23,7 @@ import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.ClusterChangedEvent;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.ClusterStateListener;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.cluster.health.ClusterIndexHealth;
import org.elasticsearch.cluster.metadata.AliasOrIndex;
@ -30,15 +31,19 @@ import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.routing.IndexRoutingTable;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.xpack.core.template.TemplateUtils;
import org.elasticsearch.xpack.core.upgrade.IndexUpgradeCheckVersion;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -54,18 +59,18 @@ import java.util.stream.Collectors;
import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_FORMAT_SETTING;
import static org.elasticsearch.xpack.core.ClientHelper.SECURITY_ORIGIN;
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
/**
* Manages the lifecycle of a single index, its template, mapping and and data upgrades/migrations.
*/
public class SecurityIndexManager extends AbstractComponent {
public class SecurityIndexManager extends AbstractComponent implements ClusterStateListener {
public static final String INTERNAL_SECURITY_INDEX = ".security-" + IndexUpgradeCheckVersion.UPRADE_VERSION;
public static final int INTERNAL_INDEX_FORMAT = 6;
public static final String SECURITY_VERSION_STRING = "security-version";
public static final String TEMPLATE_VERSION_PATTERN = Pattern.quote("${security.template.version}");
public static final String SECURITY_TEMPLATE_NAME = "security-index-template";
public static final String SECURITY_INDEX_NAME = ".security";
private final String indexName;
private final Client client;
@ -74,10 +79,15 @@ public class SecurityIndexManager extends AbstractComponent {
private volatile State indexState = new State(false, false, false, false, null, null);
public SecurityIndexManager(Settings settings, Client client, String indexName) {
public SecurityIndexManager(Settings settings, Client client, String indexName, ClusterService clusterService) {
super(settings);
this.client = client;
this.indexName = indexName;
clusterService.addListener(this);
}
public static List<String> indexNames() {
return Collections.unmodifiableList(Arrays.asList(SECURITY_INDEX_NAME, INTERNAL_SECURITY_INDEX));
}
public boolean checkMappingVersion(Predicate<Version> requiredVersion) {
@ -115,7 +125,14 @@ public class SecurityIndexManager extends AbstractComponent {
stateChangeListeners.add(listener);
}
@Override
public void clusterChanged(ClusterChangedEvent event) {
if (event.state().blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK)) {
// wait until the gateway has recovered from disk, otherwise we think we don't have the
// .security index but they may not have been restored from the cluster state on disk
logger.debug("security index manager waiting until state has been recovered");
return;
}
final State previousState = indexState;
final IndexMetaData indexMetaData = resolveConcreteIndex(indexName, event.state().metaData());
final boolean indexExists = indexMetaData != null;

View File

@ -7,16 +7,14 @@ package org.elasticsearch.integration;
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.test.NativeRealmIntegTestCase;
import org.elasticsearch.xpack.core.security.action.role.DeleteRoleResponse;
import org.elasticsearch.xpack.core.security.action.role.GetRolesResponse;
import org.elasticsearch.xpack.core.security.action.role.PutRoleResponse;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
import org.elasticsearch.xpack.core.security.client.SecurityClient;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authz.store.NativeRolesStore;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.junit.Before;
import org.junit.BeforeClass;
@ -57,7 +55,7 @@ public class ClearRolesCacheTests extends NativeRealmIntegTestCase {
logger.debug("--> created role [{}]", role);
}
ensureGreen(SecurityLifecycleService.SECURITY_INDEX_NAME);
ensureGreen(SecurityIndexManager.SECURITY_INDEX_NAME);
// warm up the caches on every node
for (NativeRolesStore rolesStore : internalCluster().getInstances(NativeRolesStore.class)) {

View File

@ -64,7 +64,7 @@ import static org.elasticsearch.test.SecuritySettingsSourceField.TEST_PASSWORD_S
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoTimeout;
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsCollectionContaining.hasItem;

View File

@ -62,7 +62,7 @@ import java.util.function.Function;
import java.util.function.Predicate;
import static org.elasticsearch.cluster.metadata.IndexMetaData.INDEX_FORMAT_SETTING;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.INTERNAL_INDEX_FORMAT;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;

View File

@ -57,7 +57,6 @@ import org.elasticsearch.xpack.core.security.authc.RealmConfig;
import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
import org.elasticsearch.xpack.core.security.authc.saml.SamlRealmSettings;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.Realms;
import org.elasticsearch.xpack.security.authc.TokenService;
import org.elasticsearch.xpack.security.authc.UserToken;
@ -161,16 +160,14 @@ public class TransportSamlInvalidateSessionActionTests extends SamlTestCase {
}
};
final SecurityLifecycleService lifecycleService = mock(SecurityLifecycleService.class);
final SecurityIndexManager securityIndex = mock(SecurityIndexManager.class);
when(lifecycleService.securityIndex()).thenReturn(securityIndex);
doAnswer(inv -> {
((Runnable) inv.getArguments()[1]).run();
return null;
}).when(securityIndex).prepareIndexIfNeededThenExecute(any(Consumer.class), any(Runnable.class));
final ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);
tokenService = new TokenService(settings, Clock.systemUTC(), client, lifecycleService, clusterService);
tokenService = new TokenService(settings, Clock.systemUTC(), client, securityIndex, clusterService);
final TransportService transportService = new TransportService(Settings.EMPTY, null, null,
TransportService.NOOP_TRANSPORT_INTERCEPTOR, x -> null, null, Collections.emptySet());

View File

@ -47,7 +47,6 @@ import org.elasticsearch.xpack.core.security.authc.RealmConfig;
import org.elasticsearch.xpack.core.security.authc.saml.SamlRealmSettings;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.ssl.SSLService;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.Realms;
import org.elasticsearch.xpack.security.authc.TokenService;
import org.elasticsearch.xpack.security.authc.UserToken;
@ -173,16 +172,14 @@ public class TransportSamlLogoutActionTests extends SamlTestCase {
return Void.TYPE;
}).when(client).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), any(ActionListener.class));
final SecurityLifecycleService lifecycleService = mock(SecurityLifecycleService.class);
final SecurityIndexManager securityIndex = mock(SecurityIndexManager.class);
when(lifecycleService.securityIndex()).thenReturn(securityIndex);
doAnswer(inv -> {
((Runnable) inv.getArguments()[1]).run();
return null;
}).when(securityIndex).prepareIndexIfNeededThenExecute(any(Consumer.class), any(Runnable.class));
final ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);
tokenService = new TokenService(settings, Clock.systemUTC(), client, lifecycleService, clusterService);
tokenService = new TokenService(settings, Clock.systemUTC(), client, securityIndex, clusterService);
final TransportService transportService = new TransportService(Settings.EMPTY, null, null,
TransportService.NOOP_TRANSPORT_INTERCEPTOR, x -> null, null, Collections.emptySet());

View File

@ -24,7 +24,6 @@ import org.elasticsearch.xpack.core.security.user.AnonymousUser;
import org.elasticsearch.xpack.core.security.user.SystemUser;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.security.user.XPackUser;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealmTests;
@ -76,13 +75,11 @@ public class TransportGetUsersActionTests extends ESTestCase {
public void testAnonymousUser() {
NativeUsersStore usersStore = mock(NativeUsersStore.class);
SecurityLifecycleService securityLifecycleService = mock(SecurityLifecycleService.class);
SecurityIndexManager securityIndex = mock(SecurityIndexManager.class);
when(securityLifecycleService.securityIndex()).thenReturn(securityIndex);
when(securityIndex.isAvailable()).thenReturn(true);
AnonymousUser anonymousUser = new AnonymousUser(settings);
ReservedRealm reservedRealm =
new ReservedRealm(mock(Environment.class), settings, usersStore, anonymousUser, securityLifecycleService, new ThreadContext(Settings.EMPTY));
new ReservedRealm(mock(Environment.class), settings, usersStore, anonymousUser, securityIndex, new ThreadContext(Settings.EMPTY));
TransportService transportService = new TransportService(Settings.EMPTY, null, null, TransportService.NOOP_TRANSPORT_INTERCEPTOR,
x -> null, null, Collections.emptySet());
TransportGetUsersAction action = new TransportGetUsersAction(Settings.EMPTY, mock(ThreadPool.class), mock(ActionFilters.class),
@ -148,15 +145,13 @@ public class TransportGetUsersActionTests extends ESTestCase {
public void testReservedUsersOnly() {
NativeUsersStore usersStore = mock(NativeUsersStore.class);
SecurityLifecycleService securityLifecycleService = mock(SecurityLifecycleService.class);
SecurityIndexManager securityIndex = mock(SecurityIndexManager.class);
when(securityLifecycleService.securityIndex()).thenReturn(securityIndex);
when(securityIndex.isAvailable()).thenReturn(true);
when(securityIndex.checkMappingVersion(any())).thenReturn(true);
ReservedRealmTests.mockGetAllReservedUserInfo(usersStore, Collections.emptyMap());
ReservedRealm reservedRealm =
new ReservedRealm(mock(Environment.class), settings, usersStore, new AnonymousUser(settings), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new ReservedRealm(mock(Environment.class), settings, usersStore, new AnonymousUser(settings), securityIndex, new ThreadContext(Settings.EMPTY));
PlainActionFuture<Collection<User>> userFuture = new PlainActionFuture<>();
reservedRealm.users(userFuture);
final Collection<User> allReservedUsers = userFuture.actionGet();
@ -198,13 +193,11 @@ public class TransportGetUsersActionTests extends ESTestCase {
final List<User> storeUsers = randomFrom(Collections.<User>emptyList(), Collections.singletonList(new User("joe")),
Arrays.asList(new User("jane"), new User("fred")), randomUsers());
NativeUsersStore usersStore = mock(NativeUsersStore.class);
SecurityLifecycleService securityLifecycleService = mock(SecurityLifecycleService.class);
SecurityIndexManager securityIndex = mock(SecurityIndexManager.class);
when(securityLifecycleService.securityIndex()).thenReturn(securityIndex);
when(securityIndex.isAvailable()).thenReturn(true);
ReservedRealmTests.mockGetAllReservedUserInfo(usersStore, Collections.emptyMap());
ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), settings, usersStore, new AnonymousUser(settings),
securityLifecycleService, new ThreadContext(Settings.EMPTY));
securityIndex, new ThreadContext(Settings.EMPTY));
TransportService transportService = new TransportService(Settings.EMPTY, null, null, TransportService.NOOP_TRANSPORT_INTERCEPTOR,
x -> null, null, Collections.emptySet());
TransportGetUsersAction action = new TransportGetUsersAction(Settings.EMPTY, mock(ThreadPool.class), mock(ActionFilters.class),

View File

@ -25,7 +25,6 @@ import org.elasticsearch.xpack.core.security.user.AnonymousUser;
import org.elasticsearch.xpack.core.security.user.SystemUser;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.security.user.XPackUser;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealmTests;
@ -118,14 +117,12 @@ public class TransportPutUserActionTests extends ESTestCase {
public void testReservedUser() {
NativeUsersStore usersStore = mock(NativeUsersStore.class);
SecurityLifecycleService securityLifecycleService = mock(SecurityLifecycleService.class);
SecurityIndexManager securityIndex = mock(SecurityIndexManager.class);
when(securityLifecycleService.securityIndex()).thenReturn(securityIndex);
when(securityIndex.isAvailable()).thenReturn(true);
ReservedRealmTests.mockGetAllReservedUserInfo(usersStore, Collections.emptyMap());
Settings settings = Settings.builder().put("path.home", createTempDir()).build();
ReservedRealm reservedRealm = new ReservedRealm(TestEnvironment.newEnvironment(settings), settings, usersStore,
new AnonymousUser(settings), securityLifecycleService, new ThreadContext(settings));
new AnonymousUser(settings), securityIndex, new ThreadContext(settings));
PlainActionFuture<Collection<User>> userFuture = new PlainActionFuture<>();
reservedRealm.users(userFuture);
final User reserved = randomFrom(userFuture.actionGet().toArray(new User[0]));

View File

@ -64,7 +64,6 @@ import org.elasticsearch.xpack.core.security.authz.permission.Role;
import org.elasticsearch.xpack.core.security.user.AnonymousUser;
import org.elasticsearch.xpack.core.security.user.SystemUser;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.audit.AuditTrailService;
import org.elasticsearch.xpack.security.authc.AuthenticationService.Authenticator;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
@ -125,7 +124,6 @@ public class AuthenticationServiceTests extends ESTestCase {
private ThreadPool threadPool;
private ThreadContext threadContext;
private TokenService tokenService;
private SecurityLifecycleService lifecycleService;
private SecurityIndexManager securityIndex;
private Client client;
private InetSocketAddress remoteAddress;
@ -182,16 +180,14 @@ public class AuthenticationServiceTests extends ESTestCase {
.setId((String) invocationOnMock.getArguments()[2]);
return builder;
}).when(client).prepareGet(anyString(), anyString(), anyString());
lifecycleService = mock(SecurityLifecycleService.class);
securityIndex = mock(SecurityIndexManager.class);
when(lifecycleService.securityIndex()).thenReturn(securityIndex);
doAnswer(invocationOnMock -> {
Runnable runnable = (Runnable) invocationOnMock.getArguments()[1];
runnable.run();
return null;
}).when(securityIndex).prepareIndexIfNeededThenExecute(any(Consumer.class), any(Runnable.class));
ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);
tokenService = new TokenService(settings, Clock.systemUTC(), client, lifecycleService, clusterService);
tokenService = new TokenService(settings, Clock.systemUTC(), client, securityIndex, clusterService);
service = new AuthenticationService(settings, realms, auditTrail,
new DefaultAuthenticationFailureHandler(), threadPool, new AnonymousUser(settings), tokenService);
}
@ -929,7 +925,7 @@ public class AuthenticationServiceTests extends ESTestCase {
public void testExpiredToken() throws Exception {
when(securityIndex.isAvailable()).thenReturn(true);
when(lifecycleService.securityIndex().indexExists()).thenReturn(true);
when(securityIndex.indexExists()).thenReturn(true);
User user = new User("_username", "r1");
final Authentication expected = new Authentication(user, new RealmRef("realm", "custom", "node"), null);
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();

View File

@ -15,7 +15,6 @@ import org.elasticsearch.xpack.core.security.authc.Realm;
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
import org.elasticsearch.xpack.core.ssl.SSLService;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore;
import org.elasticsearch.xpack.security.authc.support.mapper.NativeRoleMappingStore;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
@ -31,18 +30,15 @@ import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class InternalRealmsTests extends ESTestCase {
public void testNativeRealmRegistersIndexHealthChangeListener() throws Exception {
SecurityLifecycleService lifecycleService = mock(SecurityLifecycleService.class);
SecurityIndexManager securityIndex = mock(SecurityIndexManager.class);
when(lifecycleService.securityIndex()).thenReturn(securityIndex);
Map<String, Realm.Factory> factories = InternalRealms.getFactories(mock(ThreadPool.class), mock(ResourceWatcherService.class),
mock(SSLService.class), mock(NativeUsersStore.class), mock(NativeRoleMappingStore.class), lifecycleService);
mock(SSLService.class), mock(NativeUsersStore.class), mock(NativeRoleMappingStore.class), securityIndex);
assertThat(factories, hasEntry(is(NativeRealmSettings.TYPE), any(Realm.Factory.class)));
verifyZeroInteractions(lifecycleService);
verifyZeroInteractions(securityIndex);
Settings settings = Settings.builder().put("path.home", createTempDir()).build();
factories.get(NativeRealmSettings.TYPE).create(new RealmConfig("test", Settings.EMPTY, settings,

View File

@ -32,7 +32,7 @@ import org.elasticsearch.xpack.core.security.action.user.AuthenticateResponse;
import org.elasticsearch.xpack.core.security.authc.TokenMetaData;
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import org.elasticsearch.xpack.core.security.client.SecurityClient;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.junit.After;
import org.junit.Before;
@ -147,7 +147,7 @@ public class TokenAuthIntegTests extends SecurityIntegTestCase {
assertTrue(invalidateResponse.isCreated());
AtomicReference<String> docId = new AtomicReference<>();
assertBusy(() -> {
SearchResponse searchResponse = client.prepareSearch(SecurityLifecycleService.SECURITY_INDEX_NAME)
SearchResponse searchResponse = client.prepareSearch(SecurityIndexManager.SECURITY_INDEX_NAME)
.setSource(SearchSourceBuilder.searchSource()
.query(QueryBuilders.termQuery("doc_type", TokenService.INVALIDATED_TOKEN_DOC_TYPE)))
.setSize(1)
@ -160,7 +160,7 @@ public class TokenAuthIntegTests extends SecurityIntegTestCase {
// hack doc to modify the time to the day before
Instant dayBefore = created.minus(1L, ChronoUnit.DAYS);
assertTrue(Instant.now().isAfter(dayBefore));
client.prepareUpdate(SecurityLifecycleService.SECURITY_INDEX_NAME, "doc", docId.get())
client.prepareUpdate(SecurityIndexManager.SECURITY_INDEX_NAME, "doc", docId.get())
.setDoc("expiration_time", dayBefore.toEpochMilli())
.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)
.get();
@ -178,8 +178,8 @@ public class TokenAuthIntegTests extends SecurityIntegTestCase {
assertEquals("token malformed", e.getMessage());
}
}
client.admin().indices().prepareRefresh(SecurityLifecycleService.SECURITY_INDEX_NAME).get();
SearchResponse searchResponse = client.prepareSearch(SecurityLifecycleService.SECURITY_INDEX_NAME)
client.admin().indices().prepareRefresh(SecurityIndexManager.SECURITY_INDEX_NAME).get();
SearchResponse searchResponse = client.prepareSearch(SecurityIndexManager.SECURITY_INDEX_NAME)
.setSource(SearchSourceBuilder.searchSource()
.query(QueryBuilders.termQuery("doc_type", TokenService.INVALIDATED_TOKEN_DOC_TYPE)))
.setSize(0)

View File

@ -50,7 +50,6 @@ import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
import org.elasticsearch.xpack.core.security.authc.TokenMetaData;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.watcher.watch.ClockMock;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.junit.AfterClass;
import org.junit.Before;
@ -86,7 +85,6 @@ public class TokenServiceTests extends ESTestCase {
.put(XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey(), true).build();
private Client client;
private SecurityLifecycleService lifecycleService;
private SecurityIndexManager securityIndex;
private ClusterService clusterService;
private Settings tokenServiceEnabledSettings = Settings.builder()
@ -132,9 +130,7 @@ public class TokenServiceTests extends ESTestCase {
}).when(client).execute(eq(IndexAction.INSTANCE), any(IndexRequest.class), any(ActionListener.class));
// setup lifecycle service
lifecycleService = mock(SecurityLifecycleService.class);
securityIndex = mock(SecurityIndexManager.class);
when(lifecycleService.securityIndex()).thenReturn(securityIndex);
doAnswer(invocationOnMock -> {
Runnable runnable = (Runnable) invocationOnMock.getArguments()[1];
runnable.run();
@ -157,7 +153,7 @@ public class TokenServiceTests extends ESTestCase {
}
public void testAttachAndGetToken() throws Exception {
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService, clusterService);
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex, clusterService);
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
tokenService.createUserToken(authentication, authentication, tokenFuture, Collections.emptyMap());
@ -177,7 +173,7 @@ public class TokenServiceTests extends ESTestCase {
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
// verify a second separate token service with its own salt can also verify
TokenService anotherService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService
TokenService anotherService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex
, clusterService);
anotherService.refreshMetaData(tokenService.getTokenMetaData());
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
@ -188,7 +184,7 @@ public class TokenServiceTests extends ESTestCase {
}
public void testRotateKey() throws Exception {
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService, clusterService);
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex, clusterService);
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
tokenService.createUserToken(authentication, authentication, tokenFuture, Collections.emptyMap());
@ -240,12 +236,12 @@ public class TokenServiceTests extends ESTestCase {
}
public void testKeyExchange() throws Exception {
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService, clusterService);
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex, clusterService);
int numRotations = 0;randomIntBetween(1, 5);
for (int i = 0; i < numRotations; i++) {
rotateKeys(tokenService);
}
TokenService otherTokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService,
TokenService otherTokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex,
clusterService);
otherTokenService.refreshMetaData(tokenService.getTokenMetaData());
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
@ -277,7 +273,7 @@ public class TokenServiceTests extends ESTestCase {
}
public void testPruneKeys() throws Exception {
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService, clusterService);
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex, clusterService);
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
tokenService.createUserToken(authentication, authentication, tokenFuture, Collections.emptyMap());
@ -338,7 +334,7 @@ public class TokenServiceTests extends ESTestCase {
}
public void testPassphraseWorks() throws Exception {
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService, clusterService);
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex, clusterService);
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
tokenService.createUserToken(authentication, authentication, tokenFuture, Collections.emptyMap());
@ -358,7 +354,7 @@ public class TokenServiceTests extends ESTestCase {
try (ThreadContext.StoredContext ignore = requestContext.newStoredContext(true)) {
// verify a second separate token service with its own passphrase cannot verify
TokenService anotherService = new TokenService(Settings.EMPTY, systemUTC(), client, lifecycleService,
TokenService anotherService = new TokenService(Settings.EMPTY, systemUTC(), client, securityIndex,
clusterService);
PlainActionFuture<UserToken> future = new PlainActionFuture<>();
anotherService.getAndValidateToken(requestContext, future);
@ -367,7 +363,7 @@ public class TokenServiceTests extends ESTestCase {
}
public void testGetTokenWhenKeyCacheHasExpired() throws Exception {
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService, clusterService);
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex, clusterService);
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
@ -382,7 +378,7 @@ public class TokenServiceTests extends ESTestCase {
public void testInvalidatedToken() throws Exception {
when(securityIndex.indexExists()).thenReturn(true);
TokenService tokenService =
new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService, clusterService);
new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex, clusterService);
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
tokenService.createUserToken(authentication, authentication, tokenFuture, Collections.emptyMap());
@ -436,7 +432,7 @@ public class TokenServiceTests extends ESTestCase {
public void testTokenExpiry() throws Exception {
ClockMock clock = ClockMock.frozen();
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, clock, client, lifecycleService, clusterService);
TokenService tokenService = new TokenService(tokenServiceEnabledSettings, clock, client, securityIndex, clusterService);
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
tokenService.createUserToken(authentication, authentication, tokenFuture, Collections.emptyMap());
@ -488,7 +484,7 @@ public class TokenServiceTests extends ESTestCase {
TokenService tokenService = new TokenService(Settings.builder()
.put(XPackSettings.TOKEN_SERVICE_ENABLED_SETTING.getKey(), false)
.build(),
Clock.systemUTC(), client, lifecycleService, clusterService);
Clock.systemUTC(), client, securityIndex, clusterService);
IllegalStateException e = expectThrows(IllegalStateException.class, () -> tokenService.createUserToken(null, null, null, null));
assertEquals("tokens are not enabled", e.getMessage());
@ -530,7 +526,7 @@ public class TokenServiceTests extends ESTestCase {
final int numBytes = randomIntBetween(1, TokenService.MINIMUM_BYTES + 32);
final byte[] randomBytes = new byte[numBytes];
random().nextBytes(randomBytes);
TokenService tokenService = new TokenService(Settings.EMPTY, systemUTC(), client, lifecycleService, clusterService);
TokenService tokenService = new TokenService(Settings.EMPTY, systemUTC(), client, securityIndex, clusterService);
ThreadContext requestContext = new ThreadContext(Settings.EMPTY);
requestContext.putHeader("Authorization", "Bearer " + Base64.getEncoder().encodeToString(randomBytes));
@ -544,7 +540,7 @@ public class TokenServiceTests extends ESTestCase {
public void testIndexNotAvailable() throws Exception {
TokenService tokenService =
new TokenService(tokenServiceEnabledSettings, systemUTC(), client, lifecycleService, clusterService);
new TokenService(tokenServiceEnabledSettings, systemUTC(), client, securityIndex, clusterService);
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
PlainActionFuture<Tuple<UserToken, String>> tokenFuture = new PlainActionFuture<>();
tokenService.createUserToken(authentication, authentication, tokenFuture, Collections.emptyMap());
@ -577,7 +573,7 @@ public class TokenServiceTests extends ESTestCase {
public void testGetAuthenticationWorksWithExpiredToken() throws Exception {
TokenService tokenService =
new TokenService(tokenServiceEnabledSettings, Clock.systemUTC(), client, lifecycleService, clusterService);
new TokenService(tokenServiceEnabledSettings, Clock.systemUTC(), client, securityIndex, clusterService);
Authentication authentication = new Authentication(new User("joe", "admin"), new RealmRef("native_realm", "native", "node1"), null);
UserToken expired = new UserToken(authentication, Instant.now().minus(3L, ChronoUnit.DAYS));
mockGetTokenFromId(expired);

View File

@ -9,14 +9,13 @@ import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.elasticsearch.cli.MockTerminal;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.test.NativeRealmIntegTestCase;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.xpack.core.security.authc.support.CharArrays;
import org.elasticsearch.xpack.core.security.client.SecurityClient;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.junit.BeforeClass;
import java.nio.charset.StandardCharsets;
@ -82,7 +81,7 @@ public class ESNativeMigrateToolTests extends NativeRealmIntegTestCase {
addedUsers.add(uname);
}
logger.error("--> waiting for .security index");
ensureGreen(SecurityLifecycleService.SECURITY_INDEX_NAME);
ensureGreen(SecurityIndexManager.SECURITY_INDEX_NAME);
MockTerminal t = new MockTerminal();
String username = nodeClientUsername();
@ -127,7 +126,7 @@ public class ESNativeMigrateToolTests extends NativeRealmIntegTestCase {
addedRoles.add(rname);
}
logger.error("--> waiting for .security index");
ensureGreen(SecurityLifecycleService.SECURITY_INDEX_NAME);
ensureGreen(SecurityIndexManager.SECURITY_INDEX_NAME);
MockTerminal t = new MockTerminal();
String username = nodeClientUsername();

View File

@ -54,7 +54,7 @@ import java.util.concurrent.CountDownLatch;
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoTimeout;
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.INTERNAL_SECURITY_INDEX;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.containsString;

View File

@ -32,7 +32,6 @@ import org.elasticsearch.xpack.core.security.user.ElasticUser;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.LogstashSystemUser;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.junit.Before;
@ -113,7 +112,7 @@ public class NativeUsersStoreTests extends ESTestCase {
values.put(PASSWORD_FIELD, BLANK_PASSWORD);
final GetResult result = new GetResult(
SecurityLifecycleService.SECURITY_INDEX_NAME,
SecurityIndexManager.SECURITY_INDEX_NAME,
NativeUsersStore.INDEX_TYPE,
NativeUsersStore.getIdForUser(NativeUsersStore.RESERVED_USER_TYPE, randomAlphaOfLength(12)),
1L,
@ -182,7 +181,7 @@ public class NativeUsersStoreTests extends ESTestCase {
nativeUsersStore.verifyPassword(username, password, future);
final GetResult getResult = new GetResult(
SecurityLifecycleService.SECURITY_INDEX_NAME,
SecurityIndexManager.SECURITY_INDEX_NAME,
NativeUsersStore.INDEX_TYPE,
NativeUsersStore.getIdForUser(NativeUsersStore.USER_DOC_TYPE, username),
1L,
@ -223,7 +222,7 @@ public class NativeUsersStoreTests extends ESTestCase {
values.put(User.Fields.TYPE.getPreferredName(), NativeUsersStore.USER_DOC_TYPE);
final BytesReference source = BytesReference.bytes(jsonBuilder().map(values));
final GetResult getResult = new GetResult(
SecurityLifecycleService.SECURITY_INDEX_NAME,
SecurityIndexManager.SECURITY_INDEX_NAME,
NativeUsersStore.INDEX_TYPE,
NativeUsersStore.getIdForUser(NativeUsersStore.USER_DOC_TYPE, username),
1L,
@ -236,9 +235,7 @@ public class NativeUsersStoreTests extends ESTestCase {
}
private NativeUsersStore startNativeUsersStore() {
SecurityLifecycleService securityLifecycleService = mock(SecurityLifecycleService.class);
SecurityIndexManager securityIndex = mock(SecurityIndexManager.class);
when(securityLifecycleService.securityIndex()).thenReturn(securityIndex);
when(securityIndex.isAvailable()).thenReturn(true);
when(securityIndex.indexExists()).thenReturn(true);
when(securityIndex.isMappingUpToDate()).thenReturn(true);
@ -248,7 +245,7 @@ public class NativeUsersStoreTests extends ESTestCase {
action.run();
return null;
}).when(securityIndex).prepareIndexIfNeededThenExecute(any(Consumer.class), any(Runnable.class));
return new NativeUsersStore(Settings.EMPTY, client, securityLifecycleService);
return new NativeUsersStore(Settings.EMPTY, client, securityIndex);
}
}

View File

@ -27,7 +27,6 @@ import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.LogstashSystemUser;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.security.user.UsernamesField;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.esnative.NativeUsersStore.ReservedUserInfo;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.junit.Before;
@ -63,15 +62,12 @@ public class ReservedRealmTests extends ESTestCase {
private static final SecureString EMPTY_PASSWORD = new SecureString("".toCharArray());
private NativeUsersStore usersStore;
private SecurityLifecycleService securityLifecycleService;
private SecurityIndexManager securityIndex;
@Before
public void setupMocks() throws Exception {
usersStore = mock(NativeUsersStore.class);
securityLifecycleService = mock(SecurityLifecycleService.class);
securityIndex = mock(SecurityIndexManager.class);
when(securityLifecycleService.securityIndex()).thenReturn(securityIndex);
when(securityIndex.isAvailable()).thenReturn(true);
when(securityIndex.checkMappingVersion(any())).thenReturn(true);
mockGetAllReservedUserInfo(usersStore, Collections.emptyMap());
@ -82,7 +78,7 @@ public class ReservedRealmTests extends ESTestCase {
UsernamesField.BEATS_NAME);
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
PlainActionFuture<AuthenticationResult> listener = new PlainActionFuture<>();
@ -98,7 +94,7 @@ public class ReservedRealmTests extends ESTestCase {
}
final ReservedRealm reservedRealm =
new ReservedRealm(mock(Environment.class), settings, usersStore,
new AnonymousUser(settings), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(settings), securityIndex, new ThreadContext(Settings.EMPTY));
final User expected = randomReservedUser(true);
final String principal = expected.principal();
@ -120,7 +116,7 @@ public class ReservedRealmTests extends ESTestCase {
private void verifySuccessfulAuthentication(boolean enabled) throws Exception {
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
final User expectedUser = randomReservedUser(enabled);
final String principal = expectedUser.principal();
final SecureString newPassword = new SecureString("foobar".toCharArray());
@ -161,7 +157,7 @@ public class ReservedRealmTests extends ESTestCase {
public void testLookup() throws Exception {
final ReservedRealm reservedRealm =
new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
final User expectedUser = randomReservedUser(true);
final String principal = expectedUser.principal();
@ -186,7 +182,7 @@ public class ReservedRealmTests extends ESTestCase {
Settings settings = Settings.builder().put(XPackSettings.RESERVED_REALM_ENABLED_SETTING.getKey(), false).build();
final ReservedRealm reservedRealm =
new ReservedRealm(mock(Environment.class), settings, usersStore, new AnonymousUser(settings),
securityLifecycleService, new ThreadContext(Settings.EMPTY));
securityIndex, new ThreadContext(Settings.EMPTY));
final User expectedUser = randomReservedUser(true);
final String principal = expectedUser.principal();
@ -200,7 +196,7 @@ public class ReservedRealmTests extends ESTestCase {
public void testLookupThrows() throws Exception {
final ReservedRealm reservedRealm =
new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
final User expectedUser = randomReservedUser(true);
final String principal = expectedUser.principal();
when(securityIndex.indexExists()).thenReturn(true);
@ -247,7 +243,7 @@ public class ReservedRealmTests extends ESTestCase {
public void testGetUsers() {
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
PlainActionFuture<Collection<User>> userFuture = new PlainActionFuture<>();
reservedRealm.users(userFuture);
assertThat(userFuture.actionGet(),
@ -262,7 +258,7 @@ public class ReservedRealmTests extends ESTestCase {
.build();
final AnonymousUser anonymousUser = new AnonymousUser(settings);
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), settings, usersStore, anonymousUser,
securityLifecycleService, new ThreadContext(Settings.EMPTY));
securityIndex, new ThreadContext(Settings.EMPTY));
PlainActionFuture<Collection<User>> userFuture = new PlainActionFuture<>();
reservedRealm.users(userFuture);
if (anonymousEnabled) {
@ -279,7 +275,7 @@ public class ReservedRealmTests extends ESTestCase {
ReservedUserInfo userInfo = new ReservedUserInfo(hash, true, false);
mockGetAllReservedUserInfo(usersStore, Collections.singletonMap("elastic", userInfo));
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), Settings.EMPTY, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
if (randomBoolean()) {
PlainActionFuture<AuthenticationResult> future = new PlainActionFuture<>();
@ -309,7 +305,7 @@ public class ReservedRealmTests extends ESTestCase {
when(securityIndex.indexExists()).thenReturn(true);
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), settings, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
PlainActionFuture<AuthenticationResult> listener = new PlainActionFuture<>();
doAnswer((i) -> {
@ -331,7 +327,7 @@ public class ReservedRealmTests extends ESTestCase {
when(securityIndex.indexExists()).thenReturn(true);
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), settings, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
PlainActionFuture<AuthenticationResult> listener = new PlainActionFuture<>();
SecureString password = new SecureString("password".toCharArray());
doAnswer((i) -> {
@ -358,7 +354,7 @@ public class ReservedRealmTests extends ESTestCase {
when(securityIndex.indexExists()).thenReturn(false);
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), settings, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
PlainActionFuture<AuthenticationResult> listener = new PlainActionFuture<>();
reservedRealm.doAuthenticate(new UsernamePasswordToken(new ElasticUser(true).principal(),
@ -376,7 +372,7 @@ public class ReservedRealmTests extends ESTestCase {
when(securityIndex.indexExists()).thenReturn(true);
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), settings, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
PlainActionFuture<AuthenticationResult> listener = new PlainActionFuture<>();
final String principal = randomFrom(KibanaUser.NAME, LogstashSystemUser.NAME, BeatsSystemUser.NAME);
@ -398,7 +394,7 @@ public class ReservedRealmTests extends ESTestCase {
when(securityIndex.indexExists()).thenReturn(false);
final ReservedRealm reservedRealm = new ReservedRealm(mock(Environment.class), settings, usersStore,
new AnonymousUser(Settings.EMPTY), securityLifecycleService, new ThreadContext(Settings.EMPTY));
new AnonymousUser(Settings.EMPTY), securityIndex, new ThreadContext(Settings.EMPTY));
PlainActionFuture<AuthenticationResult> listener = new PlainActionFuture<>();
final String principal = randomFrom(KibanaUser.NAME, LogstashSystemUser.NAME, BeatsSystemUser.NAME);

View File

@ -26,7 +26,6 @@ import org.elasticsearch.xpack.core.security.authc.support.mapper.ExpressionRole
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.FieldExpression;
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.FieldExpression.FieldValue;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm;
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
@ -73,12 +72,10 @@ public class NativeRoleMappingStoreTests extends ESTestCase {
Arrays.asList("mutants"), Collections.emptyMap(), false);
final Client client = mock(Client.class);
final SecurityLifecycleService lifecycleService = mock(SecurityLifecycleService.class);
SecurityIndexManager securityIndex = mock(SecurityIndexManager.class);
when(lifecycleService.securityIndex()).thenReturn(securityIndex);
when(securityIndex.isAvailable()).thenReturn(true);
final NativeRoleMappingStore store = new NativeRoleMappingStore(Settings.EMPTY, client, lifecycleService) {
final NativeRoleMappingStore store = new NativeRoleMappingStore(Settings.EMPTY, client, securityIndex) {
@Override
protected void loadMappings(ActionListener<List<ExpressionRoleMapping>> listener) {
final List<ExpressionRoleMapping> mappings = Arrays.asList(mapping1, mapping2, mapping3, mapping4);
@ -212,7 +209,7 @@ public class NativeRoleMappingStoreTests extends ESTestCase {
listener.onResponse(null);
}
};
final NativeRoleMappingStore store = new NativeRoleMappingStore(Settings.EMPTY, client, mock(SecurityLifecycleService.class));
final NativeRoleMappingStore store = new NativeRoleMappingStore(Settings.EMPTY, client, mock(SecurityIndexManager.class));
store.refreshRealmOnChange(mockRealm);
return store;
}

View File

@ -140,7 +140,7 @@ import static java.util.Arrays.asList;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthenticationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationExceptionRunAs;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;

View File

@ -20,8 +20,8 @@ import org.elasticsearch.xpack.core.security.authz.permission.Role;
import org.elasticsearch.xpack.core.security.authz.privilege.ClusterPrivilege;
import org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import java.util.List;
@ -81,7 +81,7 @@ public class AuthorizedIndicesTests extends ESTestCase {
MetaData metaData = MetaData.builder()
.put(new IndexMetaData.Builder("an-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
.put(new IndexMetaData.Builder("another-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
.put(new IndexMetaData.Builder(SecurityLifecycleService.SECURITY_INDEX_NAME).settings(indexSettings)
.put(new IndexMetaData.Builder(SecurityIndexManager.SECURITY_INDEX_NAME).settings(indexSettings)
.numberOfShards(1).numberOfReplicas(0).build(), true)
.build();
@ -97,12 +97,12 @@ public class AuthorizedIndicesTests extends ESTestCase {
MetaData metaData = MetaData.builder()
.put(new IndexMetaData.Builder("an-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
.put(new IndexMetaData.Builder("another-index").settings(indexSettings).numberOfShards(1).numberOfReplicas(0).build(), true)
.put(new IndexMetaData.Builder(SecurityLifecycleService.SECURITY_INDEX_NAME).settings(indexSettings)
.put(new IndexMetaData.Builder(SecurityIndexManager.SECURITY_INDEX_NAME).settings(indexSettings)
.numberOfShards(1).numberOfReplicas(0).build(), true)
.build();
AuthorizedIndices authorizedIndices = new AuthorizedIndices(user, role, SearchAction.NAME, metaData);
List<String> list = authorizedIndices.get();
assertThat(list, containsInAnyOrder("an-index", "another-index", SecurityLifecycleService.SECURITY_INDEX_NAME));
assertThat(list, containsInAnyOrder("an-index", "another-index", SecurityIndexManager.SECURITY_INDEX_NAME));
}
}

View File

@ -61,10 +61,10 @@ import org.elasticsearch.xpack.core.security.user.AnonymousUser;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.security.user.XPackSecurityUser;
import org.elasticsearch.xpack.core.security.user.XPackUser;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.audit.AuditTrailService;
import org.elasticsearch.xpack.security.authz.IndicesAndAliasesResolver.ResolvedIndices;
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.elasticsearch.xpack.security.test.SecurityTestUtils;
import org.junit.Before;
@ -75,7 +75,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
import static org.hamcrest.Matchers.containsInAnyOrder;
@ -1199,14 +1199,14 @@ public class IndicesAndAliasesResolverTests extends ESTestCase {
{
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(XPackSecurityUser.INSTANCE, SearchAction.NAME);
List<String> indices = resolveIndices(request, authorizedIndices).getLocal();
assertThat(indices, hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME));
assertThat(indices, hasItem(SecurityIndexManager.SECURITY_INDEX_NAME));
}
{
IndicesAliasesRequest aliasesRequest = new IndicesAliasesRequest();
aliasesRequest.addAliasAction(AliasActions.add().alias("security_alias").index(SECURITY_INDEX_NAME));
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(XPackSecurityUser.INSTANCE, IndicesAliasesAction.NAME);
List<String> indices = resolveIndices(aliasesRequest, authorizedIndices).getLocal();
assertThat(indices, hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME));
assertThat(indices, hasItem(SecurityIndexManager.SECURITY_INDEX_NAME));
}
}
@ -1214,7 +1214,7 @@ public class IndicesAndAliasesResolverTests extends ESTestCase {
SearchRequest request = new SearchRequest();
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(XPackUser.INSTANCE, SearchAction.NAME);
List<String> indices = resolveIndices(request, authorizedIndices).getLocal();
assertThat(indices, not(hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME)));
assertThat(indices, not(hasItem(SecurityIndexManager.SECURITY_INDEX_NAME)));
}
public void testNonXPackUserAccessingSecurityIndex() {
@ -1226,7 +1226,7 @@ public class IndicesAndAliasesResolverTests extends ESTestCase {
SearchRequest request = new SearchRequest();
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(allAccessUser, SearchAction.NAME);
List<String> indices = resolveIndices(request, authorizedIndices).getLocal();
assertThat(indices, not(hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME)));
assertThat(indices, not(hasItem(SecurityIndexManager.SECURITY_INDEX_NAME)));
}
{
@ -1234,7 +1234,7 @@ public class IndicesAndAliasesResolverTests extends ESTestCase {
aliasesRequest.addAliasAction(AliasActions.add().alias("security_alias1").index("*"));
final AuthorizedIndices authorizedIndices = buildAuthorizedIndices(allAccessUser, IndicesAliasesAction.NAME);
List<String> indices = resolveIndices(aliasesRequest, authorizedIndices).getLocal();
assertThat(indices, not(hasItem(SecurityLifecycleService.SECURITY_INDEX_NAME)));
assertThat(indices, not(hasItem(SecurityIndexManager.SECURITY_INDEX_NAME)));
}
}

View File

@ -41,8 +41,6 @@ import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.xpack.core.security.action.role.PutRoleRequest;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor.IndicesPrivileges;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.elasticsearch.xpack.security.test.SecurityTestUtils;
import org.junit.After;
@ -58,7 +56,7 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.elasticsearch.cluster.routing.RecoverySource.StoreRecoverySource.EXISTING_STORE_INSTANCE;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString;
@ -189,10 +187,9 @@ public class NativeRolesStoreTests extends ESTestCase {
final ClusterService clusterService = mock(ClusterService.class);
final XPackLicenseState licenseState = mock(XPackLicenseState.class);
final AtomicBoolean methodCalled = new AtomicBoolean(false);
final SecurityLifecycleService securityLifecycleService =
new SecurityLifecycleService(Settings.EMPTY, clusterService, threadPool, client,
mock(IndexAuditTrail.class));
final NativeRolesStore rolesStore = new NativeRolesStore(Settings.EMPTY, client, licenseState, securityLifecycleService) {
final SecurityIndexManager securityIndex =
new SecurityIndexManager(Settings.EMPTY, client, SecurityIndexManager.SECURITY_INDEX_NAME, clusterService);
final NativeRolesStore rolesStore = new NativeRolesStore(Settings.EMPTY, client, licenseState, securityIndex) {
@Override
void innerPutRole(final PutRoleRequest request, final RoleDescriptor role, final ActionListener<Boolean> listener) {
if (methodCalled.compareAndSet(false, true)) {
@ -203,7 +200,7 @@ public class NativeRolesStoreTests extends ESTestCase {
}
};
// setup the roles store so the security index exists
securityLifecycleService.clusterChanged(new ClusterChangedEvent(
securityIndex.clusterChanged(new ClusterChangedEvent(
"fls_dls_license", getClusterStateWithSecurityIndex(), getEmptyClusterState()));
PutRoleRequest putRoleRequest = new PutRoleRequest();

View File

@ -37,6 +37,7 @@ import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
import org.elasticsearch.cluster.routing.RoutingTable;
import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.cluster.routing.UnassignedInfo;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
@ -51,7 +52,7 @@ import org.hamcrest.Matchers;
import org.junit.Before;
import static org.elasticsearch.cluster.routing.RecoverySource.StoreRecoverySource.EXISTING_STORE_INSTANCE;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_TEMPLATE_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.TEMPLATE_VERSION_PATTERN;
import static org.hamcrest.Matchers.equalTo;
@ -74,6 +75,7 @@ public class SecurityIndexManagerTests extends ESTestCase {
when(threadPool.getThreadContext()).thenReturn(new ThreadContext(Settings.EMPTY));
when(mockClient.threadPool()).thenReturn(threadPool);
when(mockClient.settings()).thenReturn(Settings.EMPTY);
final ClusterService clusterService = mock(ClusterService.class);
actions = new LinkedHashMap<>();
final Client client = new FilterClient(mockClient) {
@ -88,7 +90,7 @@ public class SecurityIndexManagerTests extends ESTestCase {
actions.put(action, map);
}
};
manager = new SecurityIndexManager(Settings.EMPTY, client, INDEX_NAME);
manager = new SecurityIndexManager(Settings.EMPTY, client, INDEX_NAME, clusterService);
}
public void testIndexWithUpToDateMappingAndTemplate() throws IOException {

View File

@ -40,7 +40,7 @@ import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static java.nio.file.StandardOpenOption.WRITE;
import static org.elasticsearch.cluster.routing.RecoverySource.StoreRecoverySource.EXISTING_STORE_INSTANCE;
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.SECURITY_INDEX_NAME;
import static org.junit.Assert.assertEquals;
public class SecurityTestUtils {

View File

@ -12,8 +12,8 @@ import org.elasticsearch.action.update.UpdateAction;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.security.index.IndexAuditTrailField;
import org.elasticsearch.xpack.core.security.user.XPackUser;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.audit.index.IndexNameResolver;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.hamcrest.Matchers;
import org.joda.time.DateTime;
@ -31,8 +31,8 @@ public class XPackUserTests extends ESTestCase {
public void testXPackUserCannotAccessSecurityIndex() {
final String action = randomFrom(GetAction.NAME, SearchAction.NAME, IndexAction.NAME);
final Predicate<String> predicate = XPackUser.ROLE.indices().allowedIndicesMatcher(action);
assertThat(predicate.test(SecurityLifecycleService.SECURITY_INDEX_NAME), Matchers.is(false));
assertThat(predicate.test(SecurityLifecycleService.INTERNAL_SECURITY_INDEX), Matchers.is(false));
assertThat(predicate.test(SecurityIndexManager.SECURITY_INDEX_NAME), Matchers.is(false));
assertThat(predicate.test(SecurityIndexManager.INTERNAL_SECURITY_INDEX), Matchers.is(false));
}
public void testXPackUserCanReadAuditTrail() {