Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport] Fix for ApiKeyIntegTests related to Expired API keys remover (#43477) #47547

Merged
merged 1 commit into from
Oct 4, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.elasticsearch.xpack.security.authc;

import com.google.common.collect.Sets;

import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
Expand Down Expand Up @@ -292,9 +293,26 @@ public void testInvalidatedApiKeysDeletedByRemover() throws Exception {
assertThat(invalidateResponse.getPreviouslyInvalidatedApiKeys().size(), equalTo(0));
assertThat(invalidateResponse.getErrors().size(), equalTo(0));

awaitApiKeysRemoverCompletion();
refreshSecurityIndex();

PlainActionFuture<GetApiKeyResponse> getApiKeyResponseListener = new PlainActionFuture<>();
securityClient.getApiKey(GetApiKeyRequest.usingRealmName("file"), getApiKeyResponseListener);
assertThat(getApiKeyResponseListener.get().getApiKeyInfos().length, is(2));
Set<String> expectedKeyIds = Sets.newHashSet(createdApiKeys.get(0).getId(), createdApiKeys.get(1).getId());
boolean apiKeyInvalidatedButNotYetDeletedByExpiredApiKeysRemover = false;
for (ApiKey apiKey : getApiKeyResponseListener.get().getApiKeyInfos()) {
assertThat(apiKey.getId(), isIn(expectedKeyIds));
if (apiKey.getId().equals(createdApiKeys.get(0).getId())) {
// has been invalidated but not yet deleted by ExpiredApiKeysRemover
assertThat(apiKey.isInvalidated(), is(true));
apiKeyInvalidatedButNotYetDeletedByExpiredApiKeysRemover = true;
} else if (apiKey.getId().equals(createdApiKeys.get(1).getId())) {
// active api key
assertThat(apiKey.isInvalidated(), is(false));
}
}
assertThat(getApiKeyResponseListener.get().getApiKeyInfos().length,
is((apiKeyInvalidatedButNotYetDeletedByExpiredApiKeysRemover) ? 2 : 1));

client = waitForExpiredApiKeysRemoverTriggerReadyAndGetClient().filterWithHeader(
Collections.singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_SUPERUSER,
Expand All @@ -307,16 +325,24 @@ public void testInvalidatedApiKeysDeletedByRemover() throws Exception {
assertThat(listener.get().getInvalidatedApiKeys().size(), is(1));

awaitApiKeysRemoverCompletion();

refreshSecurityIndex();

// Verify that 1st invalidated API key is deleted whereas the next one is not
// Verify that 1st invalidated API key is deleted whereas the next one may be or may not be as it depends on whether update was
// indexed before ExpiredApiKeysRemover ran
getApiKeyResponseListener = new PlainActionFuture<>();
securityClient.getApiKey(GetApiKeyRequest.usingRealmName("file"), getApiKeyResponseListener);
assertThat(getApiKeyResponseListener.get().getApiKeyInfos().length, is(1));
ApiKey apiKey = getApiKeyResponseListener.get().getApiKeyInfos()[0];
assertThat(apiKey.getId(), is(createdApiKeys.get(1).getId()));
assertThat(apiKey.isInvalidated(), is(true));
expectedKeyIds = Sets.newHashSet(createdApiKeys.get(1).getId());
apiKeyInvalidatedButNotYetDeletedByExpiredApiKeysRemover = false;
for (ApiKey apiKey : getApiKeyResponseListener.get().getApiKeyInfos()) {
assertThat(apiKey.getId(), isIn(expectedKeyIds));
if (apiKey.getId().equals(createdApiKeys.get(1).getId())) {
// has been invalidated but not yet deleted by ExpiredApiKeysRemover
assertThat(apiKey.isInvalidated(), is(true));
apiKeyInvalidatedButNotYetDeletedByExpiredApiKeysRemover = true;
}
}
assertThat(getApiKeyResponseListener.get().getApiKeyInfos().length,
is((apiKeyInvalidatedButNotYetDeletedByExpiredApiKeysRemover) ? 1 : 0));
}

private Client waitForExpiredApiKeysRemoverTriggerReadyAndGetClient() throws Exception {
Expand All @@ -339,7 +365,6 @@ private Client waitForExpiredApiKeysRemoverTriggerReadyAndGetClient() throws Exc
return internalCluster().client(nodeWithMostRecentRun);
}

@AwaitsFix( bugUrl = "https://github.com/elastic/elasticsearch/issues/41747")
public void testExpiredApiKeysBehaviorWhenKeysExpired1WeekBeforeAnd1DayBefore() throws Exception {
Client client = waitForExpiredApiKeysRemoverTriggerReadyAndGetClient().filterWithHeader(
Collections.singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_SUPERUSER,
Expand All @@ -366,7 +391,7 @@ public void testExpiredApiKeysBehaviorWhenKeysExpired1WeekBeforeAnd1DayBefore()
.get();
assertThat(expirationDateUpdatedResponse.getResult(), is(DocWriteResponse.Result.UPDATED));

// Expire the 2nd key such that it cannot be deleted by the remover
// Expire the 2nd key such that it can be deleted by the remover
// hack doc to modify the expiration time to the week before
Instant weekBefore = created.minus(8L, ChronoUnit.DAYS);
assertTrue(Instant.now().isAfter(weekBefore));
Expand All @@ -385,23 +410,24 @@ public void testExpiredApiKeysBehaviorWhenKeysExpired1WeekBeforeAnd1DayBefore()

refreshSecurityIndex();

// Verify get API keys does not return expired and deleted key
// Verify get API keys does not return api keys deleted by ExpiredApiKeysRemover
getApiKeyResponseListener = new PlainActionFuture<>();
securityClient.getApiKey(GetApiKeyRequest.usingRealmName("file"), getApiKeyResponseListener);
assertThat(getApiKeyResponseListener.get().getApiKeyInfos().length, is(3));

Set<String> expectedKeyIds = Sets.newHashSet(createdApiKeys.get(0).getId(), createdApiKeys.get(2).getId(),
createdApiKeys.get(3).getId());
boolean apiKeyInvalidatedButNotYetDeletedByExpiredApiKeysRemover = false;
for (ApiKey apiKey : getApiKeyResponseListener.get().getApiKeyInfos()) {
assertThat(apiKey.getId(), isIn(expectedKeyIds));
if (apiKey.getId().equals(createdApiKeys.get(0).getId())) {
// has been expired, not invalidated
assertTrue(apiKey.getExpiration().isBefore(Instant.now()));
assertThat(apiKey.isInvalidated(), is(false));
} else if (apiKey.getId().equals(createdApiKeys.get(2).getId())) {
// has not been expired as no expiration, but invalidated
// has not been expired as no expiration, is invalidated but not yet deleted by ExpiredApiKeysRemover
assertThat(apiKey.getExpiration(), is(nullValue()));
assertThat(apiKey.isInvalidated(), is(true));
apiKeyInvalidatedButNotYetDeletedByExpiredApiKeysRemover = true;
} else if (apiKey.getId().equals(createdApiKeys.get(3).getId())) {
// has not been expired as no expiration, not invalidated
assertThat(apiKey.getExpiration(), is(nullValue()));
Expand All @@ -410,6 +436,8 @@ public void testExpiredApiKeysBehaviorWhenKeysExpired1WeekBeforeAnd1DayBefore()
fail("unexpected API key " + apiKey);
}
}
assertThat(getApiKeyResponseListener.get().getApiKeyInfos().length,
is((apiKeyInvalidatedButNotYetDeletedByExpiredApiKeysRemover) ? 3 : 2));
}

private void refreshSecurityIndex() throws Exception {
Expand Down