Skip to content

Commit

Permalink
split isAvailable check
Browse files Browse the repository at this point in the history
  • Loading branch information
jakelandis committed Oct 3, 2023
1 parent cbe3083 commit 4df0815
Show file tree
Hide file tree
Showing 30 changed files with 383 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@
import static org.elasticsearch.xpack.core.security.action.apikey.CrossClusterApiKeyRoleDescriptorBuilder.CCS_CLUSTER_PRIVILEGE_NAMES;
import static org.elasticsearch.xpack.core.security.authz.RoleDescriptor.WORKFLOWS_RESTRICTION_VERSION;
import static org.elasticsearch.xpack.security.Security.SECURITY_CRYPTO_THREAD_POOL_NAME;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.Availability.PRIMARY_SHARDS;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.Availability.SEARCH_SHARDS;
import static org.elasticsearch.xpack.security.support.SecuritySystemIndices.SECURITY_MAIN_ALIAS;

public class ApiKeyService {
Expand Down Expand Up @@ -1309,12 +1311,12 @@ public void crossClusterApiKeyUsageStats(ActionListener<Map<String, Object>> lis
listener.onResponse(Map.of());
return;
}
final SecurityIndexManager frozenSecurityIndex = securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = securityIndex.defensiveCopy();
if (frozenSecurityIndex.indexExists() == false) {
logger.debug("security index does not exist");
listener.onResponse(Map.of("total", 0, "ccs", 0, "ccr", 0, "ccs_ccr", 0));
} else if (frozenSecurityIndex.isAvailable() == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (frozenSecurityIndex.isAvailable(SEARCH_SHARDS) == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(SEARCH_SHARDS));
} else {
final BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
.filter(QueryBuilders.termQuery("doc_type", "api_key"))
Expand Down Expand Up @@ -1638,11 +1640,11 @@ private <T> void findApiKeysForUserRealmApiKeyIdAndNameCombination(
Function<SearchHit, T> hitParser,
ActionListener<Collection<T>> listener
) {
final SecurityIndexManager frozenSecurityIndex = securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = securityIndex.defensiveCopy();
if (frozenSecurityIndex.indexExists() == false) {
listener.onResponse(Collections.emptyList());
} else if (frozenSecurityIndex.isAvailable() == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (frozenSecurityIndex.isAvailable(SEARCH_SHARDS) == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(SEARCH_SHARDS));
} else {
final BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().filter(QueryBuilders.termQuery("doc_type", "api_key"));
QueryBuilder realmsQuery = filterForRealmNames(realmNames);
Expand Down Expand Up @@ -1879,7 +1881,7 @@ long lastTimeWhenApiKeysRemoverWasTriggered() {
}

private void maybeStartApiKeyRemover() {
if (securityIndex.isAvailable()) {
if (securityIndex.isAvailable(PRIMARY_SHARDS)) {
if (client.threadPool().relativeTimeInMillis() - lastExpirationRunMs > deleteInterval.getMillis()) {
inactiveApiKeysRemover.submit(client.threadPool());
lastExpirationRunMs = client.threadPool().relativeTimeInMillis();
Expand Down Expand Up @@ -1935,12 +1937,12 @@ public void getApiKeys(
public void queryApiKeys(SearchRequest searchRequest, boolean withLimitedBy, ActionListener<QueryApiKeyResponse> listener) {
ensureEnabled();

final SecurityIndexManager frozenSecurityIndex = securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = securityIndex.defensiveCopy();
if (frozenSecurityIndex.indexExists() == false) {
logger.debug("security index does not exist");
listener.onResponse(QueryApiKeyResponse.emptyResponse());
} else if (frozenSecurityIndex.isAvailable() == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (frozenSecurityIndex.isAvailable(SEARCH_SHARDS) == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(SEARCH_SHARDS));
} else {
securityIndex.checkIndexVersionThenExecute(
listener::onFailure,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import static org.elasticsearch.core.Strings.format;
import static org.elasticsearch.xpack.core.ClientHelper.SECURITY_ORIGIN;
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.Availability.PRIMARY_SHARDS;

/**
* Responsible for cleaning the invalidated and expired tokens from the security indices (`main` and `tokens`).
Expand Down Expand Up @@ -68,10 +69,10 @@ final class ExpiredTokenRemover extends AbstractRunnable {
@Override
public void doRun() {
final List<String> indicesWithTokens = new ArrayList<>();
if (securityTokensIndex.isAvailable()) {
if (securityTokensIndex.isAvailable(PRIMARY_SHARDS)) {
indicesWithTokens.add(securityTokensIndex.aliasName());
}
if (securityMainIndex.isAvailable() && checkMainIndexForExpiredTokens) {
if (securityMainIndex.isAvailable(PRIMARY_SHARDS) && checkMainIndexForExpiredTokens) {
indicesWithTokens.add(securityMainIndex.aliasName());
}
if (indicesWithTokens.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@
import static org.elasticsearch.search.SearchService.DEFAULT_KEEPALIVE_SETTING;
import static org.elasticsearch.xpack.core.ClientHelper.SECURITY_ORIGIN;
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.Availability.PRIMARY_SHARDS;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.Availability.SEARCH_SHARDS;

/**
* Service responsible for the creation, validation, and other management of {@link UserToken}
Expand Down Expand Up @@ -552,10 +554,10 @@ private void getTokenDocById(
ActionListener<Doc> listener
) {
final SecurityIndexManager tokensIndex = getTokensIndexForVersion(tokenVersion);
final SecurityIndexManager frozenTokensIndex = tokensIndex.freeze();
if (frozenTokensIndex.isAvailable() == false) {
final SecurityIndexManager frozenTokensIndex = tokensIndex.defensiveCopy();
if (frozenTokensIndex.isAvailable(PRIMARY_SHARDS) == false) {
logger.warn("failed to get access token [{}] because index [{}] is not available", tokenId, tokensIndex.aliasName());
listener.onFailure(frozenTokensIndex.getUnavailableReason());
listener.onFailure(frozenTokensIndex.getUnavailableReason(PRIMARY_SHARDS));
return;
}
final GetRequest getRequest = client.prepareGet(tokensIndex.aliasName(), getTokenDocumentId(tokenId)).request();
Expand Down Expand Up @@ -1168,13 +1170,13 @@ private void findTokenFromRefreshToken(
onFailure.accept(ex);
}
};
final SecurityIndexManager frozenTokensIndex = tokensIndexManager.freeze();
final SecurityIndexManager frozenTokensIndex = tokensIndexManager.defensiveCopy();
if (frozenTokensIndex.indexExists() == false) {
logger.warn("index [{}] does not exist so we can't find token from refresh token", frozenTokensIndex.aliasName());
listener.onFailure(frozenTokensIndex.getUnavailableReason());
} else if (frozenTokensIndex.isAvailable() == false) {
listener.onFailure(new IndexNotFoundException(frozenTokensIndex.aliasName()));
} else if (frozenTokensIndex.isAvailable(SEARCH_SHARDS) == false) {
logger.debug("index [{}] is not available to find token from refresh token, retrying", frozenTokensIndex.aliasName());
maybeRetryOnFailure.accept(frozenTokensIndex.getUnavailableReason());
maybeRetryOnFailure.accept(frozenTokensIndex.getUnavailableReason(SEARCH_SHARDS));
} else {
final SearchRequest request = client.prepareSearch(tokensIndexManager.aliasName())
.setQuery(
Expand Down Expand Up @@ -1786,11 +1788,11 @@ private void searchActiveTokens(
*/
private void sourceIndicesWithTokensAndRun(ActionListener<List<String>> listener) {
final List<String> indicesWithTokens = new ArrayList<>(2);
final SecurityIndexManager frozenTokensIndex = securityTokensIndex.freeze();
final SecurityIndexManager frozenTokensIndex = securityTokensIndex.defensiveCopy();
if (frozenTokensIndex.indexExists()) {
// an existing tokens index always contains tokens (if available and version allows)
if (false == frozenTokensIndex.isAvailable()) {
listener.onFailure(frozenTokensIndex.getUnavailableReason());
if (false == frozenTokensIndex.isAvailable(PRIMARY_SHARDS)) {
listener.onFailure(frozenTokensIndex.getUnavailableReason(PRIMARY_SHARDS));
return;
}
if (false == frozenTokensIndex.isIndexUpToDate()) {
Expand All @@ -1806,14 +1808,14 @@ private void sourceIndicesWithTokensAndRun(ActionListener<List<String>> listener
}
indicesWithTokens.add(frozenTokensIndex.aliasName());
}
final SecurityIndexManager frozenMainIndex = securityMainIndex.freeze();
final SecurityIndexManager frozenMainIndex = securityMainIndex.defensiveCopy();
if (frozenMainIndex.indexExists()) {
// main security index _might_ contain tokens if the tokens index has been created recently
if (false == frozenTokensIndex.indexExists()
|| frozenTokensIndex.getCreationTime()
.isAfter(clock.instant().minus(ExpiredTokenRemover.MAXIMUM_TOKEN_LIFETIME_HOURS, ChronoUnit.HOURS))) {
if (false == frozenMainIndex.isAvailable()) {
listener.onFailure(frozenMainIndex.getUnavailableReason());
if (false == frozenMainIndex.isAvailable(PRIMARY_SHARDS)) {
listener.onFailure(frozenMainIndex.getUnavailableReason(PRIMARY_SHARDS));
return;
}
if (false == frozenMainIndex.isIndexUpToDate()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
import static org.elasticsearch.search.SearchService.DEFAULT_KEEPALIVE_SETTING;
import static org.elasticsearch.xpack.core.ClientHelper.SECURITY_ORIGIN;
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.Availability.PRIMARY_SHARDS;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.Availability.SEARCH_SHARDS;
import static org.elasticsearch.xpack.security.support.SecuritySystemIndices.SECURITY_MAIN_ALIAS;

/**
Expand Down Expand Up @@ -118,11 +120,11 @@ public void getUsers(String[] userNames, final ActionListener<Collection<User>>
listener.onFailure(t);
};

final SecurityIndexManager frozenSecurityIndex = this.securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = this.securityIndex.defensiveCopy();
if (frozenSecurityIndex.indexExists() == false) {
listener.onResponse(Collections.emptyList());
} else if (frozenSecurityIndex.isAvailable() == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (frozenSecurityIndex.isAvailable(SEARCH_SHARDS) == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(SEARCH_SHARDS));
} else if (userNames.length == 1) { // optimization for single user lookup
final String username = userNames[0];
getUserAndPassword(
Expand Down Expand Up @@ -160,11 +162,11 @@ public void getUsers(String[] userNames, final ActionListener<Collection<User>>
}

void getUserCount(final ActionListener<Long> listener) {
final SecurityIndexManager frozenSecurityIndex = this.securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = this.securityIndex.defensiveCopy();
if (frozenSecurityIndex.indexExists() == false) {
listener.onResponse(0L);
} else if (frozenSecurityIndex.isAvailable() == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (frozenSecurityIndex.isAvailable(SEARCH_SHARDS) == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(SEARCH_SHARDS));
} else {
securityIndex.checkIndexVersionThenExecute(
listener::onFailure,
Expand All @@ -187,8 +189,8 @@ void getUserCount(final ActionListener<Long> listener) {
* Async method to retrieve a user and their password
*/
private void getUserAndPassword(final String user, final ActionListener<UserAndPassword> listener) {
final SecurityIndexManager frozenSecurityIndex = securityIndex.freeze();
if (frozenSecurityIndex.isAvailable() == false) {
final SecurityIndexManager frozenSecurityIndex = securityIndex.defensiveCopy();
if (frozenSecurityIndex.isAvailable(PRIMARY_SHARDS) == false) {
if (frozenSecurityIndex.indexExists() == false) {
logger.trace("could not retrieve user [{}] because security index does not exist", user);
} else {
Expand Down Expand Up @@ -537,11 +539,11 @@ private void setReservedUserEnabled(
}

public void deleteUser(final DeleteUserRequest deleteUserRequest, final ActionListener<Boolean> listener) {
final SecurityIndexManager frozenSecurityIndex = securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = securityIndex.defensiveCopy();
if (frozenSecurityIndex.indexExists() == false) {
listener.onResponse(false);
} else if (frozenSecurityIndex.isAvailable() == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (frozenSecurityIndex.isAvailable(PRIMARY_SHARDS) == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(PRIMARY_SHARDS));
} else {
securityIndex.checkIndexVersionThenExecute(listener::onFailure, () -> {
DeleteRequest request = client.prepareDelete(SECURITY_MAIN_ALIAS, getIdForUser(USER_DOC_TYPE, deleteUserRequest.username()))
Expand Down Expand Up @@ -595,11 +597,11 @@ void verifyPassword(String username, final SecureString password, ActionListener
}

void getReservedUserInfo(String username, ActionListener<ReservedUserInfo> listener) {
final SecurityIndexManager frozenSecurityIndex = securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = securityIndex.defensiveCopy();
if (frozenSecurityIndex.indexExists() == false) {
listener.onResponse(null);
} else if (frozenSecurityIndex.isAvailable() == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (frozenSecurityIndex.isAvailable(PRIMARY_SHARDS) == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(PRIMARY_SHARDS));
} else {
securityIndex.checkIndexVersionThenExecute(
listener::onFailure,
Expand Down Expand Up @@ -648,11 +650,11 @@ public void onFailure(Exception e) {
}

void getAllReservedUserInfo(ActionListener<Map<String, ReservedUserInfo>> listener) {
final SecurityIndexManager frozenSecurityIndex = securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = securityIndex.defensiveCopy();
if (frozenSecurityIndex.indexExists() == false) {
listener.onResponse(Collections.emptyMap());
} else if (frozenSecurityIndex.isAvailable() == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (frozenSecurityIndex.isAvailable(SEARCH_SHARDS) == false) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(SEARCH_SHARDS));
} else {
securityIndex.checkIndexVersionThenExecute(
listener::onFailure,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
import static org.elasticsearch.search.SearchService.DEFAULT_KEEPALIVE_SETTING;
import static org.elasticsearch.xpack.core.ClientHelper.SECURITY_ORIGIN;
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.Availability.PRIMARY_SHARDS;
import static org.elasticsearch.xpack.security.support.SecurityIndexManager.Availability.SEARCH_SHARDS;
import static org.elasticsearch.xpack.security.support.SecuritySystemIndices.SECURITY_MAIN_ALIAS;

public class IndexServiceAccountTokenStore extends CachingServiceAccountTokenStore {
Expand Down Expand Up @@ -168,11 +170,11 @@ void createToken(
}

void findTokensFor(ServiceAccountId accountId, ActionListener<Collection<TokenInfo>> listener) {
final SecurityIndexManager frozenSecurityIndex = this.securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = this.securityIndex.defensiveCopy();
if (false == frozenSecurityIndex.indexExists()) {
listener.onResponse(List.of());
} else if (false == frozenSecurityIndex.isAvailable()) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (false == frozenSecurityIndex.isAvailable(SEARCH_SHARDS)) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(SEARCH_SHARDS));
} else {
securityIndex.checkIndexVersionThenExecute(listener::onFailure, () -> {
final Supplier<ThreadContext.StoredContext> contextSupplier = client.threadPool()
Expand Down Expand Up @@ -204,11 +206,11 @@ void findTokensFor(ServiceAccountId accountId, ActionListener<Collection<TokenIn
}

void deleteToken(DeleteServiceAccountTokenRequest request, ActionListener<Boolean> listener) {
final SecurityIndexManager frozenSecurityIndex = this.securityIndex.freeze();
final SecurityIndexManager frozenSecurityIndex = this.securityIndex.defensiveCopy();
if (false == frozenSecurityIndex.indexExists()) {
listener.onResponse(false);
} else if (false == frozenSecurityIndex.isAvailable()) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason());
} else if (false == frozenSecurityIndex.isAvailable(PRIMARY_SHARDS)) {
listener.onFailure(frozenSecurityIndex.getUnavailableReason(PRIMARY_SHARDS));
} else {
final ServiceAccountId accountId = new ServiceAccountId(request.getNamespace(), request.getServiceName());
if (false == ServiceAccountService.isServiceAccountPrincipal(accountId.asPrincipal())) {
Expand Down
Loading

0 comments on commit 4df0815

Please sign in to comment.