diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DateMathExpressionIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DateMathExpressionIntegTests.java index 7aeaccf63bab4..b1a76a4559812 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DateMathExpressionIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DateMathExpressionIntegTests.java @@ -10,7 +10,6 @@ import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.MultiGetResponse; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.internal.Client; @@ -25,6 +24,7 @@ import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.NONE; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; import static org.hamcrest.Matchers.containsString; @@ -77,8 +77,7 @@ public void testDateMathExpressionsCanBeAuthorized() throws Exception { if (refeshOnOperation == false) { client.admin().indices().prepareRefresh(expression).get(); } - SearchResponse searchResponse = client.prepareSearch(expression).setQuery(QueryBuilders.matchAllQuery()).get(); - assertThat(searchResponse.getHits().getTotalHits().value, is(1L)); + assertHitCount(client.prepareSearch(expression).setQuery(QueryBuilders.matchAllQuery()), 1); assertResponse( client.prepareMultiSearch().add(client.prepareSearch(expression).setQuery(QueryBuilders.matchAllQuery()).request()), diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DlsFlsRequestCacheTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DlsFlsRequestCacheTests.java index 0e8cb486ffb2d..1e1d8a7f0654c 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DlsFlsRequestCacheTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DlsFlsRequestCacheTests.java @@ -11,7 +11,7 @@ import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.admin.indices.forcemerge.ForceMergeResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; -import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.client.internal.Client; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.settings.SecureString; @@ -191,31 +191,31 @@ public void testRequestCacheForDLS() { final Client limitedClient = limitedClient(); // Search first with power client, it should see all docs - assertSearchResponse(powerClient.prepareSearch(DLS_INDEX).setRequestCache(true).get(), Set.of("101", "102")); + assertSearchResponse(powerClient.prepareSearch(DLS_INDEX).setRequestCache(true), Set.of("101", "102")); assertCacheState(DLS_INDEX, 0, 1); // Search with the limited client and it should see only one doc (i.e. it won't use cache entry for power client) - assertSearchResponse(limitedClient.prepareSearch(DLS_INDEX).setRequestCache(true).get(), Set.of("101")); + assertSearchResponse(limitedClient.prepareSearch(DLS_INDEX).setRequestCache(true), Set.of("101")); assertCacheState(DLS_INDEX, 0, 2); // Execute the above search again and it should use the cache entry for limited client - assertSearchResponse(limitedClient.prepareSearch(DLS_INDEX).setRequestCache(true).get(), Set.of("101")); + assertSearchResponse(limitedClient.prepareSearch(DLS_INDEX).setRequestCache(true), Set.of("101")); assertCacheState(DLS_INDEX, 1, 2); // Execute the search with power client again and it should still see all docs - assertSearchResponse(powerClient.prepareSearch(DLS_INDEX).setRequestCache(true).get(), Set.of("101", "102")); + assertSearchResponse(powerClient.prepareSearch(DLS_INDEX).setRequestCache(true), Set.of("101", "102")); assertCacheState(DLS_INDEX, 2, 2); // The limited client has a different DLS query for dls-alias compared to the underlying dls-index - assertSearchResponse(limitedClient.prepareSearch(DLS_ALIAS).setRequestCache(true).get(), Set.of("102")); + assertSearchResponse(limitedClient.prepareSearch(DLS_ALIAS).setRequestCache(true), Set.of("102")); assertCacheState(DLS_INDEX, 2, 3); - assertSearchResponse(limitedClient.prepareSearch(DLS_ALIAS).setRequestCache(true).get(), Set.of("102")); + assertSearchResponse(limitedClient.prepareSearch(DLS_ALIAS).setRequestCache(true), Set.of("102")); assertCacheState(DLS_INDEX, 3, 3); // Search with limited client for dls-alias and dls-index returns all docs. The cache entry is however different // from the power client, i.e. still no sharing even if the end results are the same. This is because the // search with limited client still have DLS queries attached to it. - assertSearchResponse(limitedClient.prepareSearch(DLS_ALIAS, DLS_INDEX).setRequestCache(true).get(), Set.of("101", "102")); + assertSearchResponse(limitedClient.prepareSearch(DLS_ALIAS, DLS_INDEX).setRequestCache(true), Set.of("101", "102")); assertCacheState(DLS_INDEX, 3, 4); } @@ -224,37 +224,29 @@ public void testRequestCacheForFLS() { final Client limitedClient = limitedClient(); // Search first with power client, it should see all fields - assertSearchResponse( - powerClient.prepareSearch(FLS_INDEX).setRequestCache(true).get(), - Set.of("201", "202"), - Set.of("public", "private") - ); + assertSearchResponse(powerClient.prepareSearch(FLS_INDEX).setRequestCache(true), Set.of("201", "202"), Set.of("public", "private")); assertCacheState(FLS_INDEX, 0, 1); // Search with limited client and it should see only public field - assertSearchResponse(limitedClient.prepareSearch(FLS_INDEX).setRequestCache(true).get(), Set.of("201", "202"), Set.of("public")); + assertSearchResponse(limitedClient.prepareSearch(FLS_INDEX).setRequestCache(true), Set.of("201", "202"), Set.of("public")); assertCacheState(FLS_INDEX, 0, 2); // Search with limited client again and it should use the cache - assertSearchResponse(limitedClient.prepareSearch(FLS_INDEX).setRequestCache(true).get(), Set.of("201", "202"), Set.of("public")); + assertSearchResponse(limitedClient.prepareSearch(FLS_INDEX).setRequestCache(true), Set.of("201", "202"), Set.of("public")); assertCacheState(FLS_INDEX, 1, 2); // Search again with power client, it should use its own cache entry - assertSearchResponse( - powerClient.prepareSearch(FLS_INDEX).setRequestCache(true).get(), - Set.of("201", "202"), - Set.of("public", "private") - ); + assertSearchResponse(powerClient.prepareSearch(FLS_INDEX).setRequestCache(true), Set.of("201", "202"), Set.of("public", "private")); assertCacheState(FLS_INDEX, 2, 2); // The fls-alias has a different FLS definition compared to its underlying fls-index. - assertSearchResponse(limitedClient.prepareSearch(FLS_ALIAS).setRequestCache(true).get(), Set.of("201", "202"), Set.of("private")); + assertSearchResponse(limitedClient.prepareSearch(FLS_ALIAS).setRequestCache(true), Set.of("201", "202"), Set.of("private")); assertCacheState(FLS_INDEX, 2, 3); // Search with the limited client for both fls-alias and fls-index and all docs and fields are also returned. // But request cache is not shared with the power client because it still has a different indexAccessControl assertSearchResponse( - limitedClient.prepareSearch(FLS_ALIAS, FLS_INDEX).setRequestCache(true).get(), + limitedClient.prepareSearch(FLS_ALIAS, FLS_INDEX).setRequestCache(true), Set.of("201", "202"), Set.of("public", "private") ); @@ -267,7 +259,7 @@ public void testRequestCacheForBothDLSandFLS() throws ExecutionException, Interr // Search first with power client, it should see all fields assertSearchResponse( - powerClient.prepareSearch(INDEX).setRequestCache(true).get(), + powerClient.prepareSearch(INDEX).setRequestCache(true), Set.of("1", "2"), Set.of("number", "letter", "public", "private") ); @@ -278,25 +270,17 @@ public void testRequestCacheForBothDLSandFLS() throws ExecutionException, Interr expectThrows(ElasticsearchSecurityException.class, () -> limitedClient.prepareSearch(INDEX).setRequestCache(true).get()); // Search for alias1 that points to index and has DLS/FLS - assertSearchResponse( - limitedClient.prepareSearch(ALIAS1).setRequestCache(true).get(), - Set.of("1"), - Set.of("number", "letter", "public") - ); + assertSearchResponse(limitedClient.prepareSearch(ALIAS1).setRequestCache(true), Set.of("1"), Set.of("number", "letter", "public")); assertCacheState(INDEX, 0, 2); // Search for alias2 that also points to index but has a different set of DLS/FLS - assertSearchResponse( - limitedClient.prepareSearch(ALIAS2).setRequestCache(true).get(), - Set.of("2"), - Set.of("number", "letter", "private") - ); + assertSearchResponse(limitedClient.prepareSearch(ALIAS2).setRequestCache(true), Set.of("2"), Set.of("number", "letter", "private")); assertCacheState(INDEX, 0, 3); // Search for all-alias that has full read access to the underlying index // This makes it share the cache entry of the power client assertSearchResponse( - limitedClient.prepareSearch(ALL_ALIAS).setRequestCache(true).get(), + limitedClient.prepareSearch(ALL_ALIAS).setRequestCache(true), Set.of("1", "2"), Set.of("number", "letter", "public", "private") ); @@ -305,7 +289,7 @@ public void testRequestCacheForBothDLSandFLS() throws ExecutionException, Interr // Similarly, search for alias1 and all-alias results in full read access to the index // and again reuse the cache entry of the power client assertSearchResponse( - limitedClient.prepareSearch(ALIAS1, ALL_ALIAS).setRequestCache(true).get(), + limitedClient.prepareSearch(ALIAS1, ALL_ALIAS).setRequestCache(true), Set.of("1", "2"), Set.of("number", "letter", "public", "private") ); @@ -314,7 +298,7 @@ public void testRequestCacheForBothDLSandFLS() throws ExecutionException, Interr // Though search for both alias1 and alias2 is effectively full read access to index, // it does not share the cache entry of the power client because role queries still exist. assertSearchResponse( - limitedClient.prepareSearch(ALIAS1, ALIAS2).setRequestCache(true).get(), + limitedClient.prepareSearch(ALIAS1, ALIAS2).setRequestCache(true), Set.of("1", "2"), Set.of("number", "letter", "public", "private") ); @@ -325,7 +309,7 @@ public void testRequestCacheForBothDLSandFLS() throws ExecutionException, Interr // It should not reuse any entries from the cache assertSearchResponse( - limitedClientApiKey.prepareSearch(ALL_ALIAS).setRequestCache(true).get(), + limitedClientApiKey.prepareSearch(ALL_ALIAS).setRequestCache(true), Set.of("1"), Set.of("letter", "public", "private") ); @@ -341,43 +325,23 @@ public void testRequestCacheWithTemplateRoleQuery() { ); // Search first with user1 and only one document will be return with the corresponding username - assertSearchResponse( - client1.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_INDEX).setRequestCache(true).get(), - Set.of("1"), - Set.of("username") - ); + assertSearchResponse(client1.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_INDEX).setRequestCache(true), Set.of("1"), Set.of("username")); assertCacheState(DLS_TEMPLATE_ROLE_QUERY_INDEX, 0, 1); // Search with user2 will not use user1's cache because template query is resolved differently for them - assertSearchResponse( - client2.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_INDEX).setRequestCache(true).get(), - Set.of("2"), - Set.of("username") - ); + assertSearchResponse(client2.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_INDEX).setRequestCache(true), Set.of("2"), Set.of("username")); assertCacheState(DLS_TEMPLATE_ROLE_QUERY_INDEX, 0, 2); // Search with user1 again will use user1's cache - assertSearchResponse( - client1.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_INDEX).setRequestCache(true).get(), - Set.of("1"), - Set.of("username") - ); + assertSearchResponse(client1.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_INDEX).setRequestCache(true), Set.of("1"), Set.of("username")); assertCacheState(DLS_TEMPLATE_ROLE_QUERY_INDEX, 1, 2); // Search with user2 again will use user2's cache - assertSearchResponse( - client2.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_INDEX).setRequestCache(true).get(), - Set.of("2"), - Set.of("username") - ); + assertSearchResponse(client2.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_INDEX).setRequestCache(true), Set.of("2"), Set.of("username")); assertCacheState(DLS_TEMPLATE_ROLE_QUERY_INDEX, 2, 2); // Since the DLS for the alias uses a stored script, this should cause the request cached to be disabled - assertSearchResponse( - client1.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_ALIAS).setRequestCache(true).get(), - Set.of("1"), - Set.of("username") - ); + assertSearchResponse(client1.prepareSearch(DLS_TEMPLATE_ROLE_QUERY_ALIAS).setRequestCache(true), Set.of("1"), Set.of("username")); // No cache should be used assertCacheState(DLS_TEMPLATE_ROLE_QUERY_INDEX, 2, 2); } @@ -455,19 +419,24 @@ private Client limitedClientApiKey() throws ExecutionException, InterruptedExcep return client().filterWithHeader(Map.of("Authorization", "ApiKey " + base64ApiKey)); } - private void assertSearchResponse(SearchResponse searchResponse, Set docIds) { - assertSearchResponse(searchResponse, docIds, null); + private void assertSearchResponse(SearchRequestBuilder requestBuilder, Set docIds) { + assertSearchResponse(requestBuilder, docIds, null); } - private void assertSearchResponse(SearchResponse searchResponse, Set docIds, Set fieldNames) { - assertThat(searchResponse.getFailedShards(), equalTo(0)); - assertThat(searchResponse.getHits().getTotalHits().value, equalTo((long) docIds.size())); - final SearchHit[] hits = searchResponse.getHits().getHits(); - assertThat(Arrays.stream(hits).map(SearchHit::getId).collect(Collectors.toUnmodifiableSet()), equalTo(docIds)); - if (fieldNames != null) { - for (SearchHit hit : hits) { - assertThat(hit.getSourceAsMap().keySet(), equalTo(fieldNames)); + private void assertSearchResponse(SearchRequestBuilder requestBuilder, Set docIds, Set fieldNames) { + var searchResponse = requestBuilder.get(); + try { + assertThat(searchResponse.getFailedShards(), equalTo(0)); + assertThat(searchResponse.getHits().getTotalHits().value, equalTo((long) docIds.size())); + final SearchHit[] hits = searchResponse.getHits().getHits(); + assertThat(Arrays.stream(hits).map(SearchHit::getId).collect(Collectors.toUnmodifiableSet()), equalTo(docIds)); + if (fieldNames != null) { + for (SearchHit hit : hits) { + assertThat(hit.getSourceAsMap().keySet(), equalTo(fieldNames)); + } } + } finally { + searchResponse.decRef(); } } diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentAndFieldLevelSecurityTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentAndFieldLevelSecurityTests.java index 164d28216ea93..57d18abaf1a92 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentAndFieldLevelSecurityTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentAndFieldLevelSecurityTests.java @@ -14,7 +14,6 @@ import org.elasticsearch.action.fieldcaps.FieldCapabilities; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesRequest; import org.elasticsearch.action.fieldcaps.FieldCapabilitiesResponse; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.internal.Requests; import org.elasticsearch.cluster.metadata.MappingMetadata; import org.elasticsearch.common.settings.SecureString; @@ -35,6 +34,7 @@ import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHits; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; @@ -113,32 +113,41 @@ public void testSimpleQuery() { prepareIndex("test").setId("1").setSource("id", "1", "field1", "value1").setRefreshPolicy(IMMEDIATE).get(); prepareIndex("test").setId("2").setSource("id", "2", "field2", "value2").setRefreshPolicy(IMMEDIATE).get(); - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").get(); - assertHitCount(response, 1); - assertSearchHits(response, "1"); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("id").toString(), equalTo("1")); - - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertHitCount(response, 1); - assertSearchHits(response, "2"); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("id").toString(), equalTo("2")); - - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) - .prepareSearch("test") - .addSort("id", SortOrder.ASC) - .get(); - assertHitCount(response, 2); - assertSearchHits(response, "1", "2"); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); - assertThat(response.getHits().getAt(1).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertHitCount(response, 1); + assertSearchHits(response, "1"); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("id").toString(), equalTo("1")); + } + ); + + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertHitCount(response, 1); + assertSearchHits(response, "2"); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("id").toString(), equalTo("2")); + } + ); + + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) + .prepareSearch("test") + .addSort("id", SortOrder.ASC), + response -> { + assertHitCount(response, 2); + assertSearchHits(response, "1", "2"); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertThat(response.getHits().getAt(1).getSourceAsMap().get("field2").toString(), equalTo("value2")); + } + ); } public void testUpdatesAreRejected() { @@ -181,13 +190,17 @@ public void testDLSIsAppliedBeforeFLS() { prepareIndex("test").setId("1").setSource("field1", "value1", "field2", "value1").setRefreshPolicy(IMMEDIATE).get(); prepareIndex("test").setId("2").setSource("field1", "value2", "field2", "value2").setRefreshPolicy(IMMEDIATE).get(); - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD)) - ).prepareSearch("test").setQuery(QueryBuilders.termQuery("field1", "value2")).get(); - assertHitCount(response, 1); - assertSearchHits(response, "2"); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(1)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(QueryBuilders.termQuery("field1", "value2")), + response -> { + assertHitCount(response, 1); + assertSearchHits(response, "2"); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(1)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value2")); + } + ); assertHitCount( client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD))) @@ -209,48 +222,60 @@ public void testQueryCache() { // Both users have the same role query, but user3 has access to field2 and not field1, which should result in zero hits: int max = scaledRandomIntBetween(4, 32); for (int i = 0; i < max; i++) { - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").get(); - assertHitCount(response, 1); - assertThat(response.getHits().getAt(0).getId(), equalTo("1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("id"), equalTo("1")); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertHitCount(response, 1); - assertThat(response.getHits().getAt(0).getId(), equalTo("2")); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2"), equalTo("value2")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("id"), equalTo("2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertHitCount(response, 1); + assertThat(response.getHits().getAt(0).getId(), equalTo("1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("id"), equalTo("1")); + } + ); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertHitCount(response, 1); + assertThat(response.getHits().getAt(0).getId(), equalTo("2")); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2"), equalTo("value2")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("id"), equalTo("2")); + } + ); // this is a bit weird the document level permission (all docs with field2:value2) don't match with the field level // permissions (field1), // this results in document 2 being returned but no fields are visible: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertHitCount(response, 1); - assertThat(response.getHits().getAt(0).getId(), equalTo("2")); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(1)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("id"), equalTo("2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertHitCount(response, 1); + assertThat(response.getHits().getAt(0).getId(), equalTo("2")); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(1)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("id"), equalTo("2")); + } + ); // user4 has all roles - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) - .prepareSearch("test") - .addSort("id", SortOrder.ASC) - .get(); - assertHitCount(response, 2); - assertThat(response.getHits().getAt(0).getId(), equalTo("1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("id"), equalTo("1")); - assertThat(response.getHits().getAt(1).getId(), equalTo("2")); - assertThat(response.getHits().getAt(1).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(1).getSourceAsMap().get("field2"), equalTo("value2")); - assertThat(response.getHits().getAt(1).getSourceAsMap().get("id"), equalTo("2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) + .prepareSearch("test") + .addSort("id", SortOrder.ASC), + response -> { + assertHitCount(response, 2); + assertThat(response.getHits().getAt(0).getId(), equalTo("1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("id"), equalTo("1")); + assertThat(response.getHits().getAt(1).getId(), equalTo("2")); + assertThat(response.getHits().getAt(1).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(1).getSourceAsMap().get("field2"), equalTo("value2")); + assertThat(response.getHits().getAt(1).getSourceAsMap().get("id"), equalTo("2")); + } + ); } } diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityFeatureUsageTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityFeatureUsageTests.java index 116e94cafcadf..258c4acd6c7f2 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityFeatureUsageTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityFeatureUsageTests.java @@ -6,7 +6,6 @@ */ package org.elasticsearch.integration; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.Strings; @@ -20,6 +19,7 @@ import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHits; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; @@ -89,13 +89,16 @@ public void testDlsFeatureUsageTracking() throws Exception { prepareIndex("test").setId("2").setSource("field2", "value2").setRefreshPolicy(IMMEDIATE).get(); prepareIndex("test").setId("3").setSource("field3", "value3").setRefreshPolicy(IMMEDIATE).get(); - SearchResponse response = internalCluster().coordOnlyNodeClient() - .filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(randomBoolean() ? QueryBuilders.termQuery("field1", "value1") : QueryBuilders.matchAllQuery()) - .get(); - assertHitCount(response, 1); - assertSearchHits(response, "1"); + assertResponse( + internalCluster().coordOnlyNodeClient() + .filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(randomBoolean() ? QueryBuilders.termQuery("field1", "value1") : QueryBuilders.matchAllQuery()), + response -> { + assertHitCount(response, 1); + assertSearchHits(response, "1"); + } + ); // coordinating only node should not tack DLS/FLS feature usage assertDlsFlsNotTrackedOnCoordOnlyNode(); @@ -109,13 +112,15 @@ public void testDlsFlsFeatureUsageNotTracked() { prepareIndex("test").setId("2").setSource("id", "2", "field2", "value2").setRefreshPolicy(IMMEDIATE).get(); // Running a search with user2 (which has role3 without DLS/FLS) should not trigger feature tracking. - SearchResponse response = internalCluster().coordOnlyNodeClient() - .filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertHitCount(response, 2); - assertSearchHits(response, "1", "2"); - + assertResponse( + internalCluster().coordOnlyNodeClient() + .filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertHitCount(response, 2); + assertSearchHits(response, "1", "2"); + } + ); assertDlsFlsNotTrackedAcrossAllNodes(); } diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityRandomTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityRandomTests.java index 61126810e3df1..73897fc38633a 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityRandomTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityRandomTests.java @@ -8,7 +8,6 @@ import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder; import org.elasticsearch.action.index.IndexRequestBuilder; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.query.QueryBuilders; @@ -21,6 +20,7 @@ import java.util.List; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; import static org.hamcrest.Matchers.equalTo; @@ -105,14 +105,17 @@ public void testDuelWithAliasFilters() throws Exception { builder.get(); for (int roleI = 1; roleI <= numberOfRoles; roleI++) { - SearchResponse searchResponse1 = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user" + roleI, USERS_PASSWD)) - ).prepareSearch("test").get(); - SearchResponse searchResponse2 = prepareSearch("alias" + roleI).get(); - assertThat(searchResponse1.getHits().getTotalHits().value, equalTo(searchResponse2.getHits().getTotalHits().value)); - for (int hitI = 0; hitI < searchResponse1.getHits().getHits().length; hitI++) { - assertThat(searchResponse1.getHits().getAt(hitI).getId(), equalTo(searchResponse2.getHits().getAt(hitI).getId())); - } + final int role = roleI; + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user" + roleI, USERS_PASSWD))) + .prepareSearch("test"), + searchResponse1 -> assertResponse(prepareSearch("alias" + role), searchResponse2 -> { + assertThat(searchResponse1.getHits().getTotalHits().value, equalTo(searchResponse2.getHits().getTotalHits().value)); + for (int hitI = 0; hitI < searchResponse1.getHits().getHits().length; hitI++) { + assertThat(searchResponse1.getHits().getAt(hitI).getId(), equalTo(searchResponse2.getHits().getAt(hitI).getId())); + } + }) + ); } } diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityTests.java index e42fab4708b8a..c10dc7f1da25c 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/DocumentLevelSecurityTests.java @@ -92,7 +92,9 @@ import static org.elasticsearch.join.query.JoinQueryBuilders.hasParentQuery; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCountAndNoFailures; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailuresAndResponse; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHits; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHitsWithoutFailures; @@ -542,18 +544,19 @@ public void testPercolateQueryWithIndexedDocWithDLS() { .setRefreshPolicy(IMMEDIATE) .get(); // user1 can preform the percolate search for doc#1 in the doc_index because user1 has access to the doc - SearchResponse result = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("query_index").setQuery(new PercolateQueryBuilder("query", "doc_index", "1", null, null, null)).get(); - assertNoFailures(result); - assertHitCount(result, 1); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("query_index") + .setQuery(new PercolateQueryBuilder("query", "doc_index", "1", null, null, null)), + 1 + ); // user2 can access the query_index itself (without performing percolate search) - result = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("query_index") - .setQuery(QueryBuilders.matchAllQuery()) - .get(); - assertNoFailures(result); - assertHitCount(result, 1); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("query_index") + .setQuery(QueryBuilders.matchAllQuery()), + 1 + ); // user2 cannot access doc#1 of the doc_index so the percolate search fails because doc#1 cannot be found ResourceNotFoundException e = expectThrows( ResourceNotFoundException.class, @@ -587,7 +590,6 @@ public void testGeoQueryWithIndexedShapeWithDLS() { ShapeQueryBuilder shapeQuery = new ShapeQueryBuilder("search_field", "1").relation(ShapeRelation.WITHIN) .indexedShapeIndex("shape_index") .indexedShapePath("shape_field"); - SearchResponse result; // user1 has access to doc#1 of the shape_index so everything works SearchRequestBuilder requestBuilder = client().filterWithHeader( Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) @@ -597,16 +599,14 @@ public void testGeoQueryWithIndexedShapeWithDLS() { } else { requestBuilder.setQuery(shapeQuery); } - result = requestBuilder.get(); - assertNoFailures(result); - assertHitCount(result, 1); + assertHitCountAndNoFailures(requestBuilder, 1); // user2 does not have access to doc#1 of the shape_index - result = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("search_index") - .setQuery(QueryBuilders.matchAllQuery()) - .get(); - assertNoFailures(result); - assertHitCount(result, 1); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("search_index") + .setQuery(QueryBuilders.matchAllQuery()), + 1 + ); IllegalArgumentException e; if (randomBoolean()) { e = expectThrows( @@ -696,8 +696,7 @@ public void testTermsLookupOnIndexWithDLS() { assertHitCount( client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) .prepareSearch("search_index") - .setQuery(lookup) - .get(), + .setQuery(lookup), 0 ); assertSearchHitsWithoutFailures( @@ -877,36 +876,48 @@ public void testKnnSearch() throws Exception { } // user1 should only be able to see docs with field1: value1 - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").setQuery(query).addFetchField("field1").setSize(10).get(); - assertEquals(5, response.getHits().getTotalHits().value); - assertEquals(5, response.getHits().getHits().length); - for (SearchHit hit : response.getHits().getHits()) { - assertNotNull(hit.field("field1")); - } + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(query) + .addFetchField("field1") + .setSize(10), + response -> { + assertEquals(5, response.getHits().getTotalHits().value); + assertEquals(5, response.getHits().getHits().length); + for (SearchHit hit : response.getHits().getHits()) { + assertNotNull(hit.field("field1")); + } + } + ); // user2 should only be able to see docs with field2: value2 - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(query) - .addFetchField("field2") - .setSize(10) - .get(); - assertEquals(5, response.getHits().getTotalHits().value); - assertEquals(5, response.getHits().getHits().length); - for (SearchHit hit : response.getHits().getHits()) { - assertNotNull(hit.field("field2")); - } + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(query) + .addFetchField("field2") + .setSize(10), + response -> { + assertEquals(5, response.getHits().getTotalHits().value); + assertEquals(5, response.getHits().getHits().length); + for (SearchHit hit : response.getHits().getHits()) { + assertNotNull(hit.field("field2")); + } + } + ); // user3 can see all indexed docs - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(query) - .setSize(10) - .get(); - assertEquals(10, response.getHits().getTotalHits().value); - assertEquals(10, response.getHits().getHits().length); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(query) + .setSize(10), + response -> { + assertEquals(10, response.getHits().getTotalHits().value); + assertEquals(10, response.getHits().getHits().length); + } + ); } public void testGlobalAggregation() throws Exception { @@ -918,53 +929,63 @@ public void testGlobalAggregation() throws Exception { prepareIndex("test").setId("2").setSource("field2", "value2").setRefreshPolicy(IMMEDIATE).get(); prepareIndex("test").setId("3").setSource("field3", "value3").setRefreshPolicy(IMMEDIATE).get(); - SearchResponse response = prepareSearch("test").addAggregation( - AggregationBuilders.global("global").subAggregation(AggregationBuilders.terms("field2").field("field2")) - ).get(); - assertHitCount(response, 3); - assertSearchHits(response, "1", "2", "3"); - - Global globalAgg = response.getAggregations().get("global"); - assertThat(globalAgg.getDocCount(), equalTo(3L)); - Terms termsAgg = globalAgg.getAggregations().get("field2"); - assertThat(termsAgg.getBuckets().get(0).getKeyAsString(), equalTo("value2")); - assertThat(termsAgg.getBuckets().get(0).getDocCount(), equalTo(1L)); - - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("test") - .addAggregation(AggregationBuilders.global("global").subAggregation(AggregationBuilders.terms("field2").field("field2"))) - .get(); - assertHitCount(response, 1); - assertSearchHits(response, "1"); - - globalAgg = response.getAggregations().get("global"); - assertThat(globalAgg.getDocCount(), equalTo(1L)); - termsAgg = globalAgg.getAggregations().get("field2"); - assertThat(termsAgg.getBuckets().size(), equalTo(0)); - - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addAggregation(AggregationBuilders.global("global").subAggregation(AggregationBuilders.terms("field2").field("field2"))) - .get(); - assertHitCount(response, 1); - assertSearchHits(response, "2"); - - globalAgg = response.getAggregations().get("global"); - assertThat(globalAgg.getDocCount(), equalTo(1L)); - termsAgg = globalAgg.getAggregations().get("field2"); - assertThat(termsAgg.getBuckets().size(), equalTo(1)); - - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("test") - .addAggregation(AggregationBuilders.global("global").subAggregation(AggregationBuilders.terms("field2").field("field2"))) - .get(); - assertHitCount(response, 2); - assertSearchHits(response, "1", "2"); - - globalAgg = response.getAggregations().get("global"); - assertThat(globalAgg.getDocCount(), equalTo(2L)); - termsAgg = globalAgg.getAggregations().get("field2"); - assertThat(termsAgg.getBuckets().size(), equalTo(1)); + assertResponse( + prepareSearch("test").addAggregation( + AggregationBuilders.global("global").subAggregation(AggregationBuilders.terms("field2").field("field2")) + ), + response -> { + assertHitCount(response, 3); + assertSearchHits(response, "1", "2", "3"); + + Global globalAgg = response.getAggregations().get("global"); + assertThat(globalAgg.getDocCount(), equalTo(3L)); + Terms termsAgg = globalAgg.getAggregations().get("field2"); + assertThat(termsAgg.getBuckets().get(0).getKeyAsString(), equalTo("value2")); + assertThat(termsAgg.getBuckets().get(0).getDocCount(), equalTo(1L)); + } + ); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .addAggregation(AggregationBuilders.global("global").subAggregation(AggregationBuilders.terms("field2").field("field2"))), + response -> { + assertHitCount(response, 1); + assertSearchHits(response, "1"); + + Global globalAgg = response.getAggregations().get("global"); + assertThat(globalAgg.getDocCount(), equalTo(1L)); + Terms termsAgg = globalAgg.getAggregations().get("field2"); + assertThat(termsAgg.getBuckets().size(), equalTo(0)); + } + ); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addAggregation(AggregationBuilders.global("global").subAggregation(AggregationBuilders.terms("field2").field("field2"))), + response -> { + assertHitCount(response, 1); + assertSearchHits(response, "2"); + + Global globalAgg = response.getAggregations().get("global"); + assertThat(globalAgg.getDocCount(), equalTo(1L)); + Terms termsAgg = globalAgg.getAggregations().get("field2"); + assertThat(termsAgg.getBuckets().size(), equalTo(1)); + } + ); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("test") + .addAggregation(AggregationBuilders.global("global").subAggregation(AggregationBuilders.terms("field2").field("field2"))), + response -> { + assertHitCount(response, 2); + assertSearchHits(response, "1", "2"); + + Global globalAgg = response.getAggregations().get("global"); + assertThat(globalAgg.getDocCount(), equalTo(2L)); + Terms termsAgg = globalAgg.getAggregations().get("field2"); + assertThat(termsAgg.getBuckets().size(), equalTo(1)); + } + ); } public void testParentChild() throws Exception { @@ -1016,17 +1037,20 @@ public void testParentChild() throws Exception { } private void verifyParentChild() { - SearchResponse searchResponse = prepareSearch("test").setQuery(hasChildQuery("child", matchAllQuery(), ScoreMode.None)).get(); - assertHitCount(searchResponse, 1L); - assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("p1")); - - searchResponse = prepareSearch("test").setQuery(hasParentQuery("parent", matchAllQuery(), false)) - .addSort("id", SortOrder.ASC) - .get(); - assertHitCount(searchResponse, 3L); - assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("c1")); - assertThat(searchResponse.getHits().getAt(1).getId(), equalTo("c2")); - assertThat(searchResponse.getHits().getAt(2).getId(), equalTo("c3")); + assertResponse(prepareSearch("test").setQuery(hasChildQuery("child", matchAllQuery(), ScoreMode.None)), searchResponse -> { + assertHitCount(searchResponse, 1L); + assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("p1")); + }); + + assertResponse( + prepareSearch("test").setQuery(hasParentQuery("parent", matchAllQuery(), false)).addSort("id", SortOrder.ASC), + searchResponse -> { + assertHitCount(searchResponse, 3L); + assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("c1")); + assertThat(searchResponse.getHits().getAt(1).getId(), equalTo("c2")); + assertThat(searchResponse.getHits().getAt(2).getId(), equalTo("c3")); + } + ); // Both user1 and user2 can't see field1 and field2, no parent/child query should yield results: assertHitCount( @@ -1058,20 +1082,26 @@ private void verifyParentChild() { ); // user 3 can see them but not c3 - searchResponse = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(hasChildQuery("child", matchAllQuery(), ScoreMode.None)) - .get(); - assertHitCount(searchResponse, 1L); - assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("p1")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(hasChildQuery("child", matchAllQuery(), ScoreMode.None)), + searchResponse -> { + assertHitCount(searchResponse, 1L); + assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("p1")); + } + ); - searchResponse = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(hasParentQuery("parent", matchAllQuery(), false)) - .get(); - assertHitCount(searchResponse, 2L); - assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("c1")); - assertThat(searchResponse.getHits().getAt(1).getId(), equalTo("c2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(hasParentQuery("parent", matchAllQuery(), false)), + searchResponse -> { + assertHitCount(searchResponse, 2L); + assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("c1")); + assertThat(searchResponse.getHits().getAt(1).getId(), equalTo("c2")); + } + ); } public void testScroll() throws Exception { @@ -1111,6 +1141,7 @@ public void testScroll() throws Exception { break; } + response.decRef(); response = client().filterWithHeader( Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) ).prepareSearchScroll(response.getScrollId()).setScroll(TimeValue.timeValueMinutes(1L)).get(); @@ -1118,6 +1149,7 @@ public void testScroll() throws Exception { } finally { if (response != null) { String scrollId = response.getScrollId(); + response.decRef(); if (scrollId != null) { client().prepareClearScroll().addScrollId(scrollId).get(); } @@ -1148,6 +1180,9 @@ public void testReaderId() throws Exception { SearchResponse response = null; try { for (int from = 0; from < numVisible; from++) { + if (response != null) { + response.decRef(); + } response = client().filterWithHeader( Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) ) @@ -1164,6 +1199,7 @@ public void testReaderId() throws Exception { } } finally { client().execute(TransportClosePointInTimeAction.TYPE, new ClosePointInTimeRequest(response.pointInTimeId())).actionGet(); + response.decRef(); } } @@ -1181,27 +1217,30 @@ public void testRequestCache() throws Exception { int max = scaledRandomIntBetween(4, 32); for (int i = 0; i < max; i++) { Boolean requestCache = randomFrom(true, null); - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").setSize(0).setQuery(termQuery("field1", "value1")).setRequestCache(requestCache).get(); - assertNoFailures(response); - assertHitCount(response, 1); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .setSize(0) - .setQuery(termQuery("field1", "value1")) - .setRequestCache(requestCache) - .get(); - assertNoFailures(response); - assertHitCount(response, 0); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("test") - .setSize(0) - .setQuery(termQuery("field1", "value1")) - .setRequestCache(requestCache) - .get(); - assertNoFailures(response); - assertHitCount(response, 1); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setSize(0) + .setQuery(termQuery("field1", "value1")) + .setRequestCache(requestCache), + 1 + ); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .setSize(0) + .setQuery(termQuery("field1", "value1")) + .setRequestCache(requestCache), + 0 + ); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("test") + .setSize(0) + .setQuery(termQuery("field1", "value1")) + .setRequestCache(requestCache), + 1 + ); } } @@ -1278,27 +1317,34 @@ public void testNestedInnerHits() throws Exception { .get(); refresh("test"); - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD)) - ) - .prepareSearch("test") - .setQuery( - QueryBuilders.nestedQuery("nested_field", QueryBuilders.termQuery("nested_field.field2", "value2"), ScoreMode.None) - .innerHit(new InnerHitBuilder()) - ) - .get(); - assertHitCount(response, 1); - assertSearchHits(response, "1"); - assertThat(response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(0).getId(), equalTo("1")); - assertThat(response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(0).getNestedIdentity().getOffset(), equalTo(0)); - assertThat( - response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(0).getSourceAsString(), - equalTo("{\"field2\":\"value2\"}") - ); - assertThat(response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(1).getNestedIdentity().getOffset(), equalTo(1)); - assertThat( - response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(1).getSourceAsString(), - equalTo("{\"field2\":[\"value2\",\"value3\"]}") + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) + .prepareSearch("test") + .setQuery( + QueryBuilders.nestedQuery("nested_field", QueryBuilders.termQuery("nested_field.field2", "value2"), ScoreMode.None) + .innerHit(new InnerHitBuilder()) + ), + response -> { + assertHitCount(response, 1); + assertSearchHits(response, "1"); + assertThat(response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(0).getId(), equalTo("1")); + assertThat( + response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(0).getNestedIdentity().getOffset(), + equalTo(0) + ); + assertThat( + response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(0).getSourceAsString(), + equalTo("{\"field2\":\"value2\"}") + ); + assertThat( + response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(1).getNestedIdentity().getOffset(), + equalTo(1) + ); + assertThat( + response.getHits().getAt(0).getInnerHits().get("nested_field").getAt(1).getSourceAsString(), + equalTo("{\"field2\":[\"value2\",\"value3\"]}") + ); + } ); } @@ -1342,16 +1388,19 @@ public void testSuggesters() throws Exception { ); // Term suggester: - SearchResponse response = prepareSearch("test").suggest( - new SuggestBuilder().setGlobalText("valeu").addSuggestion("_name1", new TermSuggestionBuilder("suggest_field1")) - ).get(); - assertNoFailures(response); - - TermSuggestion termSuggestion = response.getSuggest().getSuggestion("_name1"); - assertThat(termSuggestion, notNullValue()); - assertThat(termSuggestion.getEntries().size(), equalTo(1)); - assertThat(termSuggestion.getEntries().get(0).getOptions().size(), equalTo(1)); - assertThat(termSuggestion.getEntries().get(0).getOptions().get(0).getText().string(), equalTo("value")); + assertNoFailuresAndResponse( + prepareSearch("test").suggest( + new SuggestBuilder().setGlobalText("valeu").addSuggestion("_name1", new TermSuggestionBuilder("suggest_field1")) + ), + response -> { + + TermSuggestion termSuggestion = response.getSuggest().getSuggestion("_name1"); + assertThat(termSuggestion, notNullValue()); + assertThat(termSuggestion.getEntries().size(), equalTo(1)); + assertThat(termSuggestion.getEntries().get(0).getOptions().size(), equalTo(1)); + assertThat(termSuggestion.getEntries().get(0).getOptions().get(0).getText().string(), equalTo("value")); + } + ); final String[] indices = randomFrom( List.of(new String[] { "test" }, new String[] { "fls-index", "test" }, new String[] { "test", "fls-index" }) @@ -1367,17 +1416,19 @@ public void testSuggesters() throws Exception { assertThat(e.getMessage(), equalTo("Suggest isn't supported if document level security is enabled")); // Phrase suggester: - response = prepareSearch("test").suggest( - new SuggestBuilder().setGlobalText("valeu").addSuggestion("_name1", new PhraseSuggestionBuilder("suggest_field1")) - ).get(); - assertNoFailures(response); - - PhraseSuggestion phraseSuggestion = response.getSuggest().getSuggestion("_name1"); - assertThat(phraseSuggestion, notNullValue()); - assertThat(phraseSuggestion.getEntries().size(), equalTo(1)); - assertThat(phraseSuggestion.getEntries().get(0).getOptions().size(), equalTo(1)); - assertThat(phraseSuggestion.getEntries().get(0).getOptions().get(0).getText().string(), equalTo("value")); - + assertNoFailuresAndResponse( + prepareSearch("test").suggest( + new SuggestBuilder().setGlobalText("valeu").addSuggestion("_name1", new PhraseSuggestionBuilder("suggest_field1")) + ), + response -> { + + PhraseSuggestion phraseSuggestion = response.getSuggest().getSuggestion("_name1"); + assertThat(phraseSuggestion, notNullValue()); + assertThat(phraseSuggestion.getEntries().size(), equalTo(1)); + assertThat(phraseSuggestion.getEntries().get(0).getOptions().size(), equalTo(1)); + assertThat(phraseSuggestion.getEntries().get(0).getOptions().get(0).getText().string(), equalTo("value")); + } + ); e = expectThrows( ElasticsearchSecurityException.class, () -> client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD))) @@ -1388,16 +1439,18 @@ public void testSuggesters() throws Exception { assertThat(e.getMessage(), equalTo("Suggest isn't supported if document level security is enabled")); // Completion suggester: - response = prepareSearch("test").suggest( - new SuggestBuilder().setGlobalText("valu").addSuggestion("_name1", new CompletionSuggestionBuilder("suggest_field2")) - ).get(); - assertNoFailures(response); - - CompletionSuggestion completionSuggestion = response.getSuggest().getSuggestion("_name1"); - assertThat(completionSuggestion, notNullValue()); - assertThat(completionSuggestion.getEntries().size(), equalTo(1)); - assertThat(completionSuggestion.getEntries().get(0).getOptions().size(), equalTo(1)); - assertThat(completionSuggestion.getEntries().get(0).getOptions().get(0).getText().string(), equalTo("value")); + assertNoFailuresAndResponse( + prepareSearch("test").suggest( + new SuggestBuilder().setGlobalText("valu").addSuggestion("_name1", new CompletionSuggestionBuilder("suggest_field2")) + ), + response -> { + CompletionSuggestion completionSuggestion = response.getSuggest().getSuggestion("_name1"); + assertThat(completionSuggestion, notNullValue()); + assertThat(completionSuggestion.getEntries().size(), equalTo(1)); + assertThat(completionSuggestion.getEntries().get(0).getOptions().size(), equalTo(1)); + assertThat(completionSuggestion.getEntries().get(0).getOptions().get(0).getText().string(), equalTo("value")); + } + ); e = expectThrows( ElasticsearchSecurityException.class, @@ -1433,18 +1486,20 @@ public void testProfile() throws Exception { .setMapping("field1", "type=text", "other_field", "type=text", "yet_another", "type=text") ); - SearchResponse response = prepareSearch("test").setProfile(true).setQuery(new FuzzyQueryBuilder("other_field", "valeu")).get(); - assertNoFailures(response); - - assertThat(response.getProfileResults().size(), equalTo(1)); - SearchProfileShardResult shardResult = response.getProfileResults().get(response.getProfileResults().keySet().toArray()[0]); - assertThat(shardResult.getQueryProfileResults().size(), equalTo(1)); - QueryProfileShardResult queryProfileShardResult = shardResult.getQueryProfileResults().get(0); - assertThat(queryProfileShardResult.getQueryResults().size(), equalTo(1)); - logger.info("queryProfileShardResult=" + Strings.toString(queryProfileShardResult)); - assertThat( - queryProfileShardResult.getQueryResults().stream().map(ProfileResult::getLuceneDescription).sorted().collect(toList()), - equalTo(List.of("(other_field:value)^0.8")) + assertNoFailuresAndResponse( + prepareSearch("test").setProfile(true).setQuery(new FuzzyQueryBuilder("other_field", "valeu")), + response -> { + assertThat(response.getProfileResults().size(), equalTo(1)); + SearchProfileShardResult shardResult = response.getProfileResults().get(response.getProfileResults().keySet().toArray()[0]); + assertThat(shardResult.getQueryProfileResults().size(), equalTo(1)); + QueryProfileShardResult queryProfileShardResult = shardResult.getQueryProfileResults().get(0); + assertThat(queryProfileShardResult.getQueryResults().size(), equalTo(1)); + logger.info("queryProfileShardResult=" + Strings.toString(queryProfileShardResult)); + assertThat( + queryProfileShardResult.getQueryResults().stream().map(ProfileResult::getLuceneDescription).sorted().collect(toList()), + equalTo(List.of("(other_field:value)^0.8")) + ); + } ); final String[] indices = randomFrom( diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/FieldLevelSecurityRandomTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/FieldLevelSecurityRandomTests.java index 40672bf597b8c..34eecd57b53d5 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/FieldLevelSecurityRandomTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/FieldLevelSecurityRandomTests.java @@ -7,7 +7,6 @@ package org.elasticsearch.integration; import org.elasticsearch.action.index.IndexRequestBuilder; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.core.Strings; @@ -29,6 +28,7 @@ import static org.elasticsearch.index.query.QueryBuilders.matchQuery; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; import static org.hamcrest.Matchers.equalTo; @@ -194,64 +194,74 @@ public void testDuel() throws Exception { } indexRandom(true, requests); - SearchResponse actual = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)) - ) - .prepareSearch("test") - .addSort("id", SortOrder.ASC) - .setQuery( - QueryBuilders.boolQuery() - .should(QueryBuilders.termQuery("field1", "value")) - .should(QueryBuilders.termQuery("field2", "value")) - .should(QueryBuilders.termQuery("field3", "value")) + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addSort("id", SortOrder.ASC) + .setQuery( + QueryBuilders.boolQuery() + .should(QueryBuilders.termQuery("field1", "value")) + .should(QueryBuilders.termQuery("field2", "value")) + .should(QueryBuilders.termQuery("field3", "value")) + ), + actual -> assertResponse( + prepareSearch("test").addSort("id", SortOrder.ASC) + .setQuery(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("field1", "value"))), + expected -> { + assertThat(actual.getHits().getTotalHits().value, equalTo(expected.getHits().getTotalHits().value)); + assertThat(actual.getHits().getHits().length, equalTo(expected.getHits().getHits().length)); + for (int i = 0; i < actual.getHits().getHits().length; i++) { + assertThat(actual.getHits().getAt(i).getId(), equalTo(expected.getHits().getAt(i).getId())); + } + } ) - .get(); - SearchResponse expected = prepareSearch("test").addSort("id", SortOrder.ASC) - .setQuery(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("field1", "value"))) - .get(); - assertThat(actual.getHits().getTotalHits().value, equalTo(expected.getHits().getTotalHits().value)); - assertThat(actual.getHits().getHits().length, equalTo(expected.getHits().getHits().length)); - for (int i = 0; i < actual.getHits().getHits().length; i++) { - assertThat(actual.getHits().getAt(i).getId(), equalTo(expected.getHits().getAt(i).getId())); - } + ); - actual = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("test") - .addSort("id", SortOrder.ASC) - .setQuery( - QueryBuilders.boolQuery() - .should(QueryBuilders.termQuery("field1", "value")) - .should(QueryBuilders.termQuery("field2", "value")) - .should(QueryBuilders.termQuery("field3", "value")) + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("test") + .addSort("id", SortOrder.ASC) + .setQuery( + QueryBuilders.boolQuery() + .should(QueryBuilders.termQuery("field1", "value")) + .should(QueryBuilders.termQuery("field2", "value")) + .should(QueryBuilders.termQuery("field3", "value")) + ), + actual -> assertResponse( + prepareSearch("test").addSort("id", SortOrder.ASC) + .setQuery(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("field2", "value"))), + expected -> { + assertThat(actual.getHits().getTotalHits().value, equalTo(expected.getHits().getTotalHits().value)); + assertThat(actual.getHits().getHits().length, equalTo(expected.getHits().getHits().length)); + for (int i = 0; i < actual.getHits().getHits().length; i++) { + assertThat(actual.getHits().getAt(i).getId(), equalTo(expected.getHits().getAt(i).getId())); + } + } ) - .get(); - expected = prepareSearch("test").addSort("id", SortOrder.ASC) - .setQuery(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("field2", "value"))) - .get(); - assertThat(actual.getHits().getTotalHits().value, equalTo(expected.getHits().getTotalHits().value)); - assertThat(actual.getHits().getHits().length, equalTo(expected.getHits().getHits().length)); - for (int i = 0; i < actual.getHits().getHits().length; i++) { - assertThat(actual.getHits().getAt(i).getId(), equalTo(expected.getHits().getAt(i).getId())); - } + ); - actual = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) - .prepareSearch("test") - .addSort("id", SortOrder.ASC) - .setQuery( - QueryBuilders.boolQuery() - .should(QueryBuilders.termQuery("field1", "value")) - .should(QueryBuilders.termQuery("field2", "value")) - .should(QueryBuilders.termQuery("field3", "value")) + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) + .prepareSearch("test") + .addSort("id", SortOrder.ASC) + .setQuery( + QueryBuilders.boolQuery() + .should(QueryBuilders.termQuery("field1", "value")) + .should(QueryBuilders.termQuery("field2", "value")) + .should(QueryBuilders.termQuery("field3", "value")) + ), + actual -> assertResponse( + prepareSearch("test").addSort("id", SortOrder.ASC) + .setQuery(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("field3", "value"))), + expected -> { + assertThat(actual.getHits().getTotalHits().value, equalTo(expected.getHits().getTotalHits().value)); + assertThat(actual.getHits().getHits().length, equalTo(expected.getHits().getHits().length)); + for (int i = 0; i < actual.getHits().getHits().length; i++) { + assertThat(actual.getHits().getAt(i).getId(), equalTo(expected.getHits().getAt(i).getId())); + } + } ) - .get(); - expected = prepareSearch("test").addSort("id", SortOrder.ASC) - .setQuery(QueryBuilders.boolQuery().should(QueryBuilders.termQuery("field3", "value"))) - .get(); - assertThat(actual.getHits().getTotalHits().value, equalTo(expected.getHits().getTotalHits().value)); - assertThat(actual.getHits().getHits().length, equalTo(expected.getHits().getHits().length)); - for (int i = 0; i < actual.getHits().getHits().length; i++) { - assertThat(actual.getHits().getAt(i).getId(), equalTo(expected.getHits().getAt(i).getId())); - } + ); } } diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/FieldLevelSecurityTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/FieldLevelSecurityTests.java index 9c962095b3229..83be62beab4ec 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/FieldLevelSecurityTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/FieldLevelSecurityTests.java @@ -79,7 +79,7 @@ import static org.elasticsearch.join.query.JoinQueryBuilders.hasChildQuery; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCountAndNoFailures; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchHitsWithoutFailures; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER; @@ -424,11 +424,16 @@ public void testKnnSearch() throws IOException { KnnVectorQueryBuilder query = new KnnVectorQueryBuilder("vector", queryVector, 10, null); // user1 has access to vector field, so the query should match with the document: - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").setQuery(query).addFetchField("vector").get(); - assertHitCount(response, 1); - assertNotNull(response.getHits().getAt(0).field("vector")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(query) + .addFetchField("vector"), + response -> { + assertHitCount(response, 1); + assertNotNull(response.getHits().getAt(0).field("vector")); + } + ); // user2 has no access to vector field, so the query should not match with the document: assertHitCount( @@ -440,13 +445,15 @@ public void testKnnSearch() throws IOException { ); // check user2 cannot see the vector field, even when their search matches the document - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addFetchField("vector") - .get(); - assertHitCount(response, 1); - assertNull(response.getHits().getAt(0).field("vector")); - + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addFetchField("vector"), + response -> { + assertHitCount(response, 1); + assertNull(response.getHits().getAt(0).field("vector")); + } + ); // user1 can access field1, so the filtered query should match with the document: KnnVectorQueryBuilder filterQuery1 = new KnnVectorQueryBuilder("vector", queryVector, 10, null).addFilterQuery( QueryBuilders.matchQuery("field1", "value1") @@ -479,37 +486,38 @@ public void testPercolateQueryWithIndexedDocWithFLS() { {"field1": "value1", "field2": "A new bonsai tree in the office"}""", XContentType.JSON).setRefreshPolicy(IMMEDIATE).get(); QueryBuilder percolateQuery = new PercolateQueryBuilder("query", "doc_index", "1", null, null, null); // user7 sees everything - SearchResponse result = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD)) - ).prepareSearch("query_index").setQuery(percolateQuery).get(); - assertNoFailures(result); - assertHitCount(result, 1); - result = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("query_index") - .setQuery(QueryBuilders.matchAllQuery()) - .get(); - assertNoFailures(result); - assertHitCount(result, 1); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD))) + .prepareSearch("query_index") + .setQuery(percolateQuery), + 1 + ); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("query_index") + .setQuery(QueryBuilders.matchAllQuery()), + 1 + ); // user 3 can see the fields of the percolated document, but not the "query" field of the indexed query - result = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("query_index") - .setQuery(percolateQuery) - .get(); - assertNoFailures(result); - assertHitCount(result, 0); - result = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user9", USERS_PASSWD))) - .prepareSearch("query_index") - .setQuery(QueryBuilders.matchAllQuery()) - .get(); - assertNoFailures(result); - assertHitCount(result, 1); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("query_index") + .setQuery(percolateQuery), + 0 + ); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user9", USERS_PASSWD))) + .prepareSearch("query_index") + .setQuery(QueryBuilders.matchAllQuery()), + 1 + ); // user 9 can see the fields of the index query, but not the field of the indexed document to be percolated - result = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user9", USERS_PASSWD))) - .prepareSearch("query_index") - .setQuery(percolateQuery) - .get(); - assertNoFailures(result); - assertHitCount(result, 0); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user9", USERS_PASSWD))) + .prepareSearch("query_index") + .setQuery(percolateQuery), + 0 + ); } public void testGeoQueryWithIndexedShapeWithFLS() { @@ -556,7 +564,6 @@ public void testGeoQueryWithIndexedShapeWithFLS() { ] } }""", XContentType.JSON).setRefreshPolicy(IMMEDIATE).get(); - SearchResponse result; // user sees both the querying shape and the queried point SearchRequestBuilder requestBuilder = client().filterWithHeader( Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD)) @@ -569,9 +576,7 @@ public void testGeoQueryWithIndexedShapeWithFLS() { } else { requestBuilder.setQuery(shapeQuery1); } - result = requestBuilder.get(); - assertNoFailures(result); - assertHitCount(result, 1); + assertHitCountAndNoFailures(requestBuilder, 1); // user sees the queried point but not the querying shape final ShapeQueryBuilder shapeQuery2 = new ShapeQueryBuilder("field", "2").relation(ShapeRelation.WITHIN) .indexedShapeIndex("shape_index") @@ -607,9 +612,7 @@ public void testGeoQueryWithIndexedShapeWithFLS() { } else { requestBuilder.setQuery(shapeQuery3); } - result = requestBuilder.get(); - assertNoFailures(result); - assertHitCount(result, 0); + assertHitCountAndNoFailures(requestBuilder, 0); } public void testTermsLookupOnIndexWithFLS() { @@ -1118,6 +1121,7 @@ public void testScroll() throws Exception { break; } + response.decRef(); response = client().filterWithHeader( Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) ).prepareSearchScroll(response.getScrollId()).setScroll(TimeValue.timeValueMinutes(1L)).get(); @@ -1126,6 +1130,7 @@ public void testScroll() throws Exception { } finally { if (response != null) { String scrollId = response.getScrollId(); + response.decRef(); if (scrollId != null) { client().prepareClearScroll().addScrollId(scrollId).get(); } @@ -1155,23 +1160,23 @@ public void testPointInTimeId() throws Exception { refresh("test"); String pitId = openPointInTime("user1", TimeValue.timeValueMinutes(1), "test"); - SearchResponse response = null; try { for (int from = 0; from < numDocs; from++) { - response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ) - .prepareSearch() - .setPointInTime(new PointInTimeBuilder(pitId)) - .setSize(1) - .setFrom(from) - .setQuery(constantScoreQuery(termQuery("field1", "value1"))) - .setFetchSource(true) - .get(); - assertThat(response.getHits().getTotalHits().value, is((long) numDocs)); - assertThat(response.getHits().getHits().length, is(1)); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), is(1)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), is("value1")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch() + .setPointInTime(new PointInTimeBuilder(pitId)) + .setSize(1) + .setFrom(from) + .setQuery(constantScoreQuery(termQuery("field1", "value1"))) + .setFetchSource(true), + response -> { + assertThat(response.getHits().getTotalHits().value, is((long) numDocs)); + assertThat(response.getHits().getHits().length, is(1)); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), is(1)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), is("value1")); + } + ); } } finally { client().execute(TransportClosePointInTimeAction.TYPE, new ClosePointInTimeRequest(pitId)).actionGet(); @@ -1191,26 +1196,35 @@ public void testQueryCache() throws Exception { int max = scaledRandomIntBetween(4, 32); for (int i = 0; i < max; i++) { - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").setQuery(constantScoreQuery(termQuery("field1", "value1"))).get(); - assertHitCount(response, 1); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), is(1)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), is("value1")); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(constantScoreQuery(termQuery("field1", "value1"))) - .get(); - assertHitCount(response, 0); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(constantScoreQuery(termQuery("field1", "value1"))), + response -> { + assertHitCount(response, 1); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), is(1)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), is("value1")); + } + ); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(constantScoreQuery(termQuery("field1", "value1"))), + 0 + ); String multipleFieldsUser = randomFrom("user5", "user6", "user7"); - response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue(multipleFieldsUser, USERS_PASSWD)) - ).prepareSearch("test").setQuery(constantScoreQuery(termQuery("field1", "value1"))).get(); - assertHitCount(response, 1); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), is(3)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), is("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2"), is("value2")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field3"), is("value3")); + assertResponse( + client().filterWithHeader( + Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue(multipleFieldsUser, USERS_PASSWD)) + ).prepareSearch("test").setQuery(constantScoreQuery(termQuery("field1", "value1"))), + response -> { + assertHitCount(response, 1); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), is(3)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1"), is("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2"), is("value2")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field3"), is("value3")); + } + ); } } @@ -1250,6 +1264,7 @@ public void testScrollWithQueryCache() { assertThat(user2SearchResponse.getHits().getTotalHits().value, is((long) 0)); assertThat(user2SearchResponse.getHits().getHits().length, is(0)); } else { + user2SearchResponse.decRef(); // make sure scroll is empty user2SearchResponse = client().filterWithHeader( Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)) @@ -1259,6 +1274,7 @@ public void testScrollWithQueryCache() { if (randomBoolean()) { // maybe reuse the scroll even if empty client().prepareClearScroll().addScrollId(user2SearchResponse.getScrollId()).get(); + user2SearchResponse.decRef(); user2SearchResponse = null; } } @@ -1279,6 +1295,7 @@ public void testScrollWithQueryCache() { assertThat(user1SearchResponse.getHits().getAt(0).getSourceAsMap().get("field1"), is("value1")); scrolledDocsUser1++; } else { + user1SearchResponse.decRef(); user1SearchResponse = client().filterWithHeader( Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) ).prepareSearchScroll(user1SearchResponse.getScrollId()).setScroll(TimeValue.timeValueMinutes(10L)).get(); @@ -1295,6 +1312,7 @@ public void testScrollWithQueryCache() { if (user1SearchResponse.getScrollId() != null) { client().prepareClearScroll().addScrollId(user1SearchResponse.getScrollId()).get(); } + user1SearchResponse.decRef(); user1SearchResponse = null; scrolledDocsUser1 = 0; } @@ -1305,12 +1323,14 @@ public void testScrollWithQueryCache() { } finally { if (user1SearchResponse != null) { String scrollId = user1SearchResponse.getScrollId(); + user1SearchResponse.decRef(); if (scrollId != null) { client().prepareClearScroll().addScrollId(scrollId).get(); } } if (user2SearchResponse != null) { String scrollId = user2SearchResponse.getScrollId(); + user2SearchResponse.decRef(); if (scrollId != null) { client().prepareClearScroll().addScrollId(scrollId).get(); } @@ -1329,25 +1349,29 @@ public void testRequestCache() throws Exception { int max = scaledRandomIntBetween(4, 32); for (int i = 0; i < max; i++) { Boolean requestCache = randomFrom(true, null); - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").setSize(0).setQuery(termQuery("field1", "value1")).setRequestCache(requestCache).get(); - assertNoFailures(response); - assertHitCount(response, 1); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .setSize(0) - .setQuery(termQuery("field1", "value1")) - .setRequestCache(requestCache) - .get(); - assertNoFailures(response); - assertHitCount(response, 0); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setSize(0) + .setQuery(termQuery("field1", "value1")) + .setRequestCache(requestCache), + 1 + ); + assertHitCountAndNoFailures( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .setSize(0) + .setQuery(termQuery("field1", "value1")) + .setRequestCache(requestCache), + 0 + ); String multipleFieldsUser = randomFrom("user5", "user6", "user7"); - response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue(multipleFieldsUser, USERS_PASSWD)) - ).prepareSearch("test").setSize(0).setQuery(termQuery("field1", "value1")).setRequestCache(requestCache).get(); - assertNoFailures(response); - assertHitCount(response, 1); + assertHitCountAndNoFailures( + client().filterWithHeader( + Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue(multipleFieldsUser, USERS_PASSWD)) + ).prepareSearch("test").setSize(0).setQuery(termQuery("field1", "value1")).setRequestCache(requestCache), + 1 + ); } } @@ -1371,103 +1395,132 @@ public void testFields() throws Exception { .get(); // user1 is granted access to field1 only: - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").addStoredField("field1").addStoredField("field2").addStoredField("field3").get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(1)); - assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("field1") + .addStoredField("field2") + .addStoredField("field3"), + response -> { + assertThat(response.getHits().getAt(0).getFields().size(), equalTo(1)); + assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); + } + ); // user2 is granted access to field2 only: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addStoredField("field1") - .addStoredField("field2") - .addStoredField("field3") - .get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(1)); - assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("field1") + .addStoredField("field2") + .addStoredField("field3"), + response -> { + assertThat(response.getHits().getAt(0).getFields().size(), equalTo(1)); + assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); + } + ); // user3 is granted access to field1 and field2: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("test") - .addStoredField("field1") - .addStoredField("field2") - .addStoredField("field3") - .get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("field1") + .addStoredField("field2") + .addStoredField("field3"), + response -> { + assertThat(response.getHits().getAt(0).getFields().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); + } + ); // user4 is granted access to no fields: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) - .prepareSearch("test") - .addStoredField("field1") - .addStoredField("field2") - .addStoredField("field3") - .get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(0)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("field1") + .addStoredField("field2") + .addStoredField("field3"), + response -> assertThat(response.getHits().getAt(0).getFields().size(), equalTo(0)) + ); // user5 has no field level security configured: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD))) - .prepareSearch("test") - .addStoredField("field1") - .addStoredField("field2") - .addStoredField("field3") - .get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(3)); - assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); - assertThat(response.getHits().getAt(0).getFields().get("field3").getValue(), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("field1") + .addStoredField("field2") + .addStoredField("field3"), + response -> { + assertThat(response.getHits().getAt(0).getFields().size(), equalTo(3)); + assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); + assertThat(response.getHits().getAt(0).getFields().get("field3").getValue(), equalTo("value3")); + } + ); // user6 has field level security configured with access to field*: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD))) - .prepareSearch("test") - .addStoredField("field1") - .addStoredField("field2") - .addStoredField("field3") - .get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(3)); - assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); - assertThat(response.getHits().getAt(0).getFields().get("field3").getValue(), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("field1") + .addStoredField("field2") + .addStoredField("field3"), + response -> { + assertThat(response.getHits().getAt(0).getFields().size(), equalTo(3)); + assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); + assertThat(response.getHits().getAt(0).getFields().get("field3").getValue(), equalTo("value3")); + } + ); // user7 has access to all fields due to a mix of roles without field level security and with: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD))) - .prepareSearch("test") - .addStoredField("field1") - .addStoredField("field2") - .addStoredField("field3") - .get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(3)); - assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); - assertThat(response.getHits().getAt(0).getFields().get("field3").getValue(), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("field1") + .addStoredField("field2") + .addStoredField("field3"), + response -> { + assertThat(response.getHits().getAt(0).getFields().size(), equalTo(3)); + assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); + assertThat(response.getHits().getAt(0).getFields().get("field3").getValue(), equalTo("value3")); + } + ); // user8 has field level security configured with access to field1 and field2: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD))) - .prepareSearch("test") - .addStoredField("field1") - .addStoredField("field2") - .addStoredField("field3") - .get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("field1") + .addStoredField("field2") + .addStoredField("field3"), + response -> { + assertThat(response.getHits().getAt(0).getFields().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getFields().get("field1").getValue(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getFields().get("field2").getValue(), equalTo("value2")); + } + ); // user1 is granted access to field1 only, and so should be able to load it by alias: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("test") - .addStoredField("alias") - .get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(1)); - assertThat(response.getHits().getAt(0).getFields().get("alias").getValue(), equalTo("value1")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("alias"), + response -> { + assertThat(response.getHits().getAt(0).getFields().size(), equalTo(1)); + assertThat(response.getHits().getAt(0).getFields().get("alias").getValue(), equalTo("value1")); + } + ); // user2 is not granted access to field1, and so should not be able to load it by alias: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addStoredField("alias") - .get(); - assertThat(response.getHits().getAt(0).getFields().size(), equalTo(0)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addStoredField("alias"), + response -> assertThat(response.getHits().getAt(0).getFields().size(), equalTo(0)) + ); } public void testSource() throws Exception { @@ -1478,67 +1531,89 @@ public void testSource() throws Exception { .get(); // user1 is granted access to field1 only: - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").get(); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(1)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(1)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + } + ); // user2 is granted access to field2 only: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(1)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(1)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + } + ); // user3 is granted access to field1 and field2: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + } + ); // user4 is granted access to no fields: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(0)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD))) + .prepareSearch("test"), + response -> assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(0)) + ); // user5 has no field level security configured: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(3)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field3").toString(), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(3)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field3").toString(), equalTo("value3")); + } + ); // user6 has field level security configured with access to field*: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(3)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field3").toString(), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(3)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field3").toString(), equalTo("value3")); + } + ); // user7 has access to all fields - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(3)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field3").toString(), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(3)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field3").toString(), equalTo("value3")); + } + ); // user8 has field level security configured with access to field1 and field2: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD))) - .prepareSearch("test") - .get(); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD))) + .prepareSearch("test"), + response -> { + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + } + ); } public void testSort() { @@ -1548,45 +1623,52 @@ public void testSort() { prepareIndex("test").setId("1").setSource("field1", 1d, "field2", 2d).setRefreshPolicy(IMMEDIATE).get(); // user1 is granted to use field1, so it is included in the sort_values - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").addSort("field1", SortOrder.ASC).get(); - assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(1L)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .addSort("field1", SortOrder.ASC), + response -> assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(1L)) + ); // user2 is not granted to use field1, so the default missing sort value is included - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addSort("field1", SortOrder.ASC) - .get(); - assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(Long.MAX_VALUE)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addSort("field1", SortOrder.ASC), + response -> assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(Long.MAX_VALUE)) + ); // user1 is not granted to use field2, so the default missing sort value is included - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("test") - .addSort("field2", SortOrder.ASC) - .get(); - assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(Long.MAX_VALUE)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .addSort("field2", SortOrder.ASC), + response -> assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(Long.MAX_VALUE)) + ); // user2 is granted to use field2, so it is included in the sort_values - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addSort("field2", SortOrder.ASC) - .get(); - assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(2L)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addSort("field2", SortOrder.ASC), + response -> assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(2L)) + ); // user1 is granted to use field1, so it is included in the sort_values when using its alias: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("test") - .addSort("alias", SortOrder.ASC) - .get(); - assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(1L)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .addSort("alias", SortOrder.ASC), + response -> assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(1L)) + ); // user2 is not granted to use field1, so the default missing sort value is included when using its alias: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addSort("alias", SortOrder.ASC) - .get(); - assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(Long.MAX_VALUE)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addSort("alias", SortOrder.ASC), + response -> assertThat(response.getHits().getAt(0).getSortValues()[0], equalTo(Long.MAX_VALUE)) + ); } public void testHighlighting() { @@ -1600,42 +1682,56 @@ public void testHighlighting() { .get(); // user1 has access to field1, so the highlight should be visible: - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").setQuery(matchQuery("field1", "value1")).highlighter(new HighlightBuilder().field("field1")).get(); - assertHitCount(response, 1); - SearchHit hit = response.getHits().iterator().next(); - assertEquals(hit.getHighlightFields().size(), 1); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(matchQuery("field1", "value1")) + .highlighter(new HighlightBuilder().field("field1")), + response -> { + assertHitCount(response, 1); + SearchHit hit = response.getHits().iterator().next(); + assertEquals(hit.getHighlightFields().size(), 1); + } + ); // user2 has no access to field1, so the highlight should not be visible: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(matchQuery("field2", "value2")) - .highlighter(new HighlightBuilder().field("field1")) - .get(); - assertHitCount(response, 1); - hit = response.getHits().iterator().next(); - assertEquals(hit.getHighlightFields().size(), 0); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(matchQuery("field2", "value2")) + .highlighter(new HighlightBuilder().field("field1")), + response -> { + assertHitCount(response, 1); + var hit = response.getHits().iterator().next(); + assertEquals(hit.getHighlightFields().size(), 0); + } + ); // user1 has access to field1, so the highlight on its alias should be visible: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(matchQuery("field1", "value1")) - .highlighter(new HighlightBuilder().field("alias")) - .get(); - assertHitCount(response, 1); - hit = response.getHits().iterator().next(); - assertEquals(hit.getHighlightFields().size(), 1); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(matchQuery("field1", "value1")) + .highlighter(new HighlightBuilder().field("alias")), + response -> { + assertHitCount(response, 1); + var hit = response.getHits().iterator().next(); + assertEquals(hit.getHighlightFields().size(), 1); + } + ); // user2 has no access to field1, so the highlight on its alias should not be visible: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(matchQuery("field2", "value2")) - .highlighter(new HighlightBuilder().field("alias")) - .get(); - assertHitCount(response, 1); - hit = response.getHits().iterator().next(); - assertEquals(hit.getHighlightFields().size(), 0); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(matchQuery("field2", "value2")) + .highlighter(new HighlightBuilder().field("alias")), + response -> { + assertHitCount(response, 1); + var hit = response.getHits().iterator().next(); + assertEquals(hit.getHighlightFields().size(), 0); + } + ); } public void testAggs() { @@ -1646,45 +1742,52 @@ public void testAggs() { prepareIndex("test").setId("1").setSource("field1", "value1", "field2", "value2").setRefreshPolicy(IMMEDIATE).get(); // user1 is authorized to use field1, so buckets are include for a term agg on field1 - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").addAggregation(AggregationBuilders.terms("_name").field("field1")).get(); - assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value1").getDocCount(), equalTo(1L)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .addAggregation(AggregationBuilders.terms("_name").field("field1")), + response -> assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value1").getDocCount(), equalTo(1L)) + ); // user2 is not authorized to use field1, so no buckets are include for a term agg on field1 - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addAggregation(AggregationBuilders.terms("_name").field("field1")) - .get(); - assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value1"), nullValue()); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addAggregation(AggregationBuilders.terms("_name").field("field1")), + response -> assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value1"), nullValue()) + ); // user1 is not authorized to use field2, so no buckets are include for a term agg on field2 - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("test") - .addAggregation(AggregationBuilders.terms("_name").field("field2")) - .get(); - assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value2"), nullValue()); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .addAggregation(AggregationBuilders.terms("_name").field("field2")), + response -> assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value2"), nullValue()) + ); // user2 is authorized to use field2, so buckets are include for a term agg on field2 - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addAggregation(AggregationBuilders.terms("_name").field("field2")) - .get(); - assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value2").getDocCount(), equalTo(1L)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addAggregation(AggregationBuilders.terms("_name").field("field2")), + response -> assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value2").getDocCount(), equalTo(1L)) + ); // user1 is authorized to use field1, so buckets are include for a term agg on its alias: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("test") - .addAggregation(AggregationBuilders.terms("_name").field("alias")) - .get(); - assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value1").getDocCount(), equalTo(1L)); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .addAggregation(AggregationBuilders.terms("_name").field("alias")), + response -> assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value1").getDocCount(), equalTo(1L)) + ); // user2 is not authorized to use field1, so no buckets are include for a term agg on its alias: - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) - .prepareSearch("test") - .addAggregation(AggregationBuilders.terms("_name").field("alias")) - .get(); - assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value1"), nullValue()); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) + .prepareSearch("test") + .addAggregation(AggregationBuilders.terms("_name").field("alias")), + response -> assertThat(((Terms) response.getAggregations().get("_name")).getBucketByKey("value1"), nullValue()) + ); } public void testTVApi() throws Exception { @@ -1913,12 +2016,16 @@ public void testParentChild() throws Exception { } private void verifyParentChild() { - SearchResponse searchResponse = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").setQuery(hasChildQuery("child", termQuery("field1", "yellow"), ScoreMode.None)).get(); - assertHitCount(searchResponse, 1L); - assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L)); - assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("p1")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(hasChildQuery("child", termQuery("field1", "yellow"), ScoreMode.None)), + searchResponse -> { + assertHitCount(searchResponse, 1L); + assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L)); + assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("p1")); + } + ); assertHitCount( client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) @@ -1928,13 +2035,16 @@ private void verifyParentChild() { ); // Perform the same checks, but using an alias for field1. - searchResponse = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(hasChildQuery("child", termQuery("alias", "yellow"), ScoreMode.None)) - .get(); - assertHitCount(searchResponse, 1L); - assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L)); - assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("p1")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(hasChildQuery("child", termQuery("alias", "yellow"), ScoreMode.None)), + searchResponse -> { + assertHitCount(searchResponse, 1L); + assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L)); + assertThat(searchResponse.getHits().getAt(0).getId(), equalTo("p1")); + } + ); assertHitCount( client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD))) @@ -1991,22 +2101,29 @@ public void testQuery_withRoleWithFieldWildcards() { prepareIndex("test").setId("1").setSource("field1", "value1", "field2", "value2").setRefreshPolicy(IMMEDIATE).get(); // user6 has access to all fields, so the query should match with the document: - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD)) - ).prepareSearch("test").setQuery(matchQuery("field1", "value1")).get(); - assertHitCount(response, 1); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(matchQuery("field1", "value1")), + response -> { + assertHitCount(response, 1); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + } + ); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD))) - .prepareSearch("test") - .setQuery(matchQuery("field2", "value2")) - .get(); - assertHitCount(response, 1); - assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); - assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(matchQuery("field2", "value2")), + response -> { + assertHitCount(response, 1); + assertThat(response.getHits().getAt(0).getSourceAsMap().size(), equalTo(2)); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field1").toString(), equalTo("value1")); + assertThat(response.getHits().getAt(0).getSourceAsMap().get("field2").toString(), equalTo("value2")); + } + ); } public void testExistQuery() { @@ -2140,76 +2257,83 @@ public void testLookupRuntimeFields() throws Exception { .sort("field1") .runtimeMappings(Map.of("host", lookupField)) ); - SearchResponse response; // user1 has access to field1 - response = client().filterWithHeader(Map.of(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .search(request) - .actionGet(); - assertHitCount(response, 2); - { - SearchHit hit0 = response.getHits().getHits()[0]; - assertThat(hit0.getDocumentFields().keySet(), equalTo(Set.of("field1", "host"))); - assertThat(hit0.field("field1").getValues(), equalTo(List.of("192.168.1.1"))); - assertThat(hit0.field("host").getValues(), equalTo(List.of(Map.of("field1", List.of("192.168.1.1"))))); - } - { - SearchHit hit1 = response.getHits().getHits()[1]; - assertThat(hit1.getDocumentFields().keySet(), equalTo(Set.of("field1", "host"))); - assertThat(hit1.field("field1").getValues(), equalTo(List.of("192.168.1.2"))); - assertThat(hit1.field("host").getValues(), equalTo(List.of(Map.of("field1", List.of("192.168.1.2"))))); - } + assertResponse( + client().filterWithHeader(Map.of(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))).search(request), + response -> { + assertHitCount(response, 2); + { + SearchHit hit0 = response.getHits().getHits()[0]; + assertThat(hit0.getDocumentFields().keySet(), equalTo(Set.of("field1", "host"))); + assertThat(hit0.field("field1").getValues(), equalTo(List.of("192.168.1.1"))); + assertThat(hit0.field("host").getValues(), equalTo(List.of(Map.of("field1", List.of("192.168.1.1"))))); + } + { + SearchHit hit1 = response.getHits().getHits()[1]; + assertThat(hit1.getDocumentFields().keySet(), equalTo(Set.of("field1", "host"))); + assertThat(hit1.field("field1").getValues(), equalTo(List.of("192.168.1.2"))); + assertThat(hit1.field("host").getValues(), equalTo(List.of(Map.of("field1", List.of("192.168.1.2"))))); + } + } + ); // user3 has access to field1, field2 - response = client().filterWithHeader(Map.of(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))) - .search(request) - .actionGet(); - assertHitCount(response, 2); - { - SearchHit hit0 = response.getHits().getHits()[0]; - assertThat(hit0.getDocumentFields().keySet(), equalTo(Set.of("field1", "field2", "host"))); - assertThat(hit0.field("field1").getValues(), equalTo(List.of("192.168.1.1"))); - assertThat(hit0.field("field2").getValues(), equalTo(List.of("out of memory"))); - assertThat( - hit0.field("host").getValues(), - equalTo(List.of(Map.of("field1", List.of("192.168.1.1"), "field2", List.of("windows")))) - ); - } - { - SearchHit hit1 = response.getHits().getHits()[1]; - assertThat(hit1.getDocumentFields().keySet(), equalTo(Set.of("field1", "field2", "host"))); - assertThat(hit1.field("field1").getValues(), equalTo(List.of("192.168.1.2"))); - assertThat(hit1.field("field2").getValues(), equalTo(List.of("authentication fails"))); - assertThat( - hit1.field("host").getValues(), - equalTo(List.of(Map.of("field1", List.of("192.168.1.2"), "field2", List.of("macos")))) - ); - } + assertResponse( + client().filterWithHeader(Map.of(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD))).search(request), + response -> { + assertHitCount(response, 2); + { + SearchHit hit0 = response.getHits().getHits()[0]; + assertThat(hit0.getDocumentFields().keySet(), equalTo(Set.of("field1", "field2", "host"))); + assertThat(hit0.field("field1").getValues(), equalTo(List.of("192.168.1.1"))); + assertThat(hit0.field("field2").getValues(), equalTo(List.of("out of memory"))); + assertThat( + hit0.field("host").getValues(), + equalTo(List.of(Map.of("field1", List.of("192.168.1.1"), "field2", List.of("windows")))) + ); + } + { + SearchHit hit1 = response.getHits().getHits()[1]; + assertThat(hit1.getDocumentFields().keySet(), equalTo(Set.of("field1", "field2", "host"))); + assertThat(hit1.field("field1").getValues(), equalTo(List.of("192.168.1.2"))); + assertThat(hit1.field("field2").getValues(), equalTo(List.of("authentication fails"))); + assertThat( + hit1.field("host").getValues(), + equalTo(List.of(Map.of("field1", List.of("192.168.1.2"), "field2", List.of("macos")))) + ); + } + } + ); // user6 has access to field1, field2, and field3 - response = client().filterWithHeader(Map.of(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD))) - .search(request) - .actionGet(); - assertHitCount(response, 2); - { - SearchHit hit0 = response.getHits().getHits()[0]; - assertThat(hit0.getDocumentFields().keySet(), equalTo(Set.of("field1", "field2", "field3", "host"))); - assertThat(hit0.field("field1").getValues(), equalTo(List.of("192.168.1.1"))); - assertThat(hit0.field("field2").getValues(), equalTo(List.of("out of memory"))); - assertThat(hit0.field("field3").getValues(), equalTo(List.of("2021-01-20"))); - assertThat( - hit0.field("host").getValues(), - equalTo(List.of(Map.of("field1", List.of("192.168.1.1"), "field2", List.of("windows"), "field3", List.of("canada")))) - ); - } - { - SearchHit hit1 = response.getHits().getHits()[1]; - assertThat(hit1.getDocumentFields().keySet(), equalTo(Set.of("field1", "field2", "field3", "host"))); - assertThat(hit1.field("field1").getValues(), equalTo(List.of("192.168.1.2"))); - assertThat(hit1.field("field2").getValues(), equalTo(List.of("authentication fails"))); - assertThat(hit1.field("field3").getValues(), equalTo(List.of("2021-01-21"))); - assertThat( - hit1.field("host").getValues(), - equalTo(List.of(Map.of("field1", List.of("192.168.1.2"), "field2", List.of("macos"), "field3", List.of("us")))) - ); - } + assertResponse( + client().filterWithHeader(Map.of(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD))).search(request), + response -> { + assertHitCount(response, 2); + { + SearchHit hit0 = response.getHits().getHits()[0]; + assertThat(hit0.getDocumentFields().keySet(), equalTo(Set.of("field1", "field2", "field3", "host"))); + assertThat(hit0.field("field1").getValues(), equalTo(List.of("192.168.1.1"))); + assertThat(hit0.field("field2").getValues(), equalTo(List.of("out of memory"))); + assertThat(hit0.field("field3").getValues(), equalTo(List.of("2021-01-20"))); + assertThat( + hit0.field("host").getValues(), + equalTo( + List.of(Map.of("field1", List.of("192.168.1.1"), "field2", List.of("windows"), "field3", List.of("canada"))) + ) + ); + } + { + SearchHit hit1 = response.getHits().getHits()[1]; + assertThat(hit1.getDocumentFields().keySet(), equalTo(Set.of("field1", "field2", "field3", "host"))); + assertThat(hit1.field("field1").getValues(), equalTo(List.of("192.168.1.2"))); + assertThat(hit1.field("field2").getValues(), equalTo(List.of("authentication fails"))); + assertThat(hit1.field("field3").getValues(), equalTo(List.of("2021-01-21"))); + assertThat( + hit1.field("host").getValues(), + equalTo(List.of(Map.of("field1", List.of("192.168.1.2"), "field2", List.of("macos"), "field3", List.of("us")))) + ); + } + } + ); } } diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/IndicesPermissionsWithAliasesWildcardsAndRegexsTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/IndicesPermissionsWithAliasesWildcardsAndRegexsTests.java index 0e799589409f8..0566784e28153 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/IndicesPermissionsWithAliasesWildcardsAndRegexsTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/IndicesPermissionsWithAliasesWildcardsAndRegexsTests.java @@ -11,7 +11,6 @@ import org.elasticsearch.action.admin.indices.template.put.PutComposableIndexTemplateAction; import org.elasticsearch.action.datastreams.CreateDataStreamAction; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; import org.elasticsearch.cluster.metadata.Template; import org.elasticsearch.common.settings.SecureString; @@ -35,6 +34,7 @@ import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.cluster.metadata.MetadataIndexTemplateService.DEFAULT_TIMESTAMP_FIELD; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; import static org.hamcrest.Matchers.equalTo; @@ -134,52 +134,67 @@ public void testSearchResolveWildcardsRegexs() throws Exception { .setRefreshPolicy(IMMEDIATE) .get(); - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").setQuery(QueryBuilders.termQuery("_id", "1")).get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - Map source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(1)); - assertThat((String) source.get("field1"), equalTo("value1")); - - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("my_alias") - .setQuery(QueryBuilders.termQuery("_id", "1")) - .get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(1)); - assertThat((String) source.get("field2"), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + Map source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(1)); + assertThat((String) source.get("field1"), equalTo("value1")); + } + ); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("my_alias") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + var source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(1)); + assertThat((String) source.get("field2"), equalTo("value2")); + } + ); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("an_alias") - .setQuery(QueryBuilders.termQuery("_id", "1")) - .get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(1)); - assertThat((String) source.get("field3"), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("an_alias") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + var source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(1)); + assertThat((String) source.get("field3"), equalTo("value3")); + } + ); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("*_alias") - .setQuery(QueryBuilders.termQuery("_id", "1")) - .get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(2)); - assertThat((String) source.get("field2"), equalTo("value2")); - assertThat((String) source.get("field3"), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("*_alias") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + var source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(2)); + assertThat((String) source.get("field2"), equalTo("value2")); + assertThat((String) source.get("field3"), equalTo("value3")); + } + ); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("*_alias", "t*") - .setQuery(QueryBuilders.termQuery("_id", "1")) - .get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(3)); - assertThat((String) source.get("field1"), equalTo("value1")); - assertThat((String) source.get("field2"), equalTo("value2")); - assertThat((String) source.get("field3"), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("*_alias", "t*") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + var source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(3)); + assertThat((String) source.get("field1"), equalTo("value1")); + assertThat((String) source.get("field2"), equalTo("value2")); + assertThat((String) source.get("field3"), equalTo("value3")); + } + ); } public void testSearchResolveDataStreams() throws Exception { @@ -201,52 +216,68 @@ public void testSearchResolveDataStreams() throws Exception { .setRefreshPolicy(IMMEDIATE) .get(); - SearchResponse response = client().filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)) - ).prepareSearch("test").setQuery(QueryBuilders.termQuery("_id", "1")).get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - Map source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(1)); - assertThat((String) source.get("field1"), equalTo("value1")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("test") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + Map source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(1)); + assertThat((String) source.get("field1"), equalTo("value1")); + } + ); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("my_alias") - .setQuery(QueryBuilders.termQuery("_id", "1")) - .get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(1)); - assertThat((String) source.get("field2"), equalTo("value2")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("my_alias") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + var source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(1)); + assertThat((String) source.get("field2"), equalTo("value2")); + } + ); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("an_alias") - .setQuery(QueryBuilders.termQuery("_id", "1")) - .get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(1)); - assertThat((String) source.get("field3"), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("an_alias") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + var source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(1)); + assertThat((String) source.get("field3"), equalTo("value3")); + } + ); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("*_alias") - .setQuery(QueryBuilders.termQuery("_id", "1")) - .get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(2)); - assertThat((String) source.get("field2"), equalTo("value2")); - assertThat((String) source.get("field3"), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("*_alias") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + var source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(2)); + assertThat((String) source.get("field2"), equalTo("value2")); + assertThat((String) source.get("field3"), equalTo("value3")); + } + ); - response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) - .prepareSearch("*_alias", "t*") - .setQuery(QueryBuilders.termQuery("_id", "1")) - .get(); - assertThat(response.getHits().getHits().length, equalTo(1)); - source = response.getHits().getHits()[0].getSourceAsMap(); - assertThat(source.size(), equalTo(3)); - assertThat((String) source.get("field1"), equalTo("value1")); - assertThat((String) source.get("field2"), equalTo("value2")); - assertThat((String) source.get("field3"), equalTo("value3")); + assertResponse( + client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD))) + .prepareSearch("*_alias", "t*") + .setQuery(QueryBuilders.termQuery("_id", "1")), + response -> { + assertThat(response.getHits().getHits().length, equalTo(1)); + var source = response.getHits().getHits()[0].getSourceAsMap(); + assertThat(source.size(), equalTo(3)); + assertThat((String) source.get("field1"), equalTo("value1")); + assertThat((String) source.get("field2"), equalTo("value2")); + assertThat((String) source.get("field3"), equalTo("value3")); + } + ); } private void putComposableIndexTemplate(String id, List patterns) throws IOException { diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java index afe9e68716579..d4375d15e6a6d 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/KibanaUserRoleIntegTests.java @@ -12,7 +12,6 @@ import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.action.admin.indices.validate.query.ValidateQueryResponse; import org.elasticsearch.action.search.MultiSearchResponse; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.cluster.metadata.MappingMetadata; import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.core.Strings; @@ -24,6 +23,7 @@ import java.util.Map; import static java.util.Collections.singletonMap; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.hamcrest.Matchers.arrayContaining; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; @@ -102,32 +102,34 @@ public void testSearchAndMSearch() throws Exception { final String field = "foo"; indexRandom(true, prepareIndex(index).setSource(field, "bar")); - SearchResponse response = prepareSearch(index).setQuery(QueryBuilders.matchAllQuery()).get(); - final long hits = response.getHits().getTotalHits().value; - assertThat(hits, greaterThan(0L)); - response = client().filterWithHeader( - singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD)) - ).prepareSearch(index).setQuery(QueryBuilders.matchAllQuery()).get(); - assertEquals(response.getHits().getTotalHits().value, hits); - - final long multiHits; - MultiSearchResponse multiSearchResponse = client().prepareMultiSearch() - .add(prepareSearch(index).setQuery(QueryBuilders.matchAllQuery())) - .get(); - try { - multiHits = multiSearchResponse.getResponses()[0].getResponse().getHits().getTotalHits().value; + assertResponse(prepareSearch(index).setQuery(QueryBuilders.matchAllQuery()), response -> { + final long hits = response.getHits().getTotalHits().value; assertThat(hits, greaterThan(0L)); - } finally { - multiSearchResponse.decRef(); - } - multiSearchResponse = client().filterWithHeader( - singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD)) - ).prepareMultiSearch().add(prepareSearch(index).setQuery(QueryBuilders.matchAllQuery())).get(); - try { - assertEquals(multiSearchResponse.getResponses()[0].getResponse().getHits().getTotalHits().value, multiHits); - } finally { - multiSearchResponse.decRef(); - } + assertResponse( + client().filterWithHeader( + singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD)) + ).prepareSearch(index).setQuery(QueryBuilders.matchAllQuery()), + response2 -> assertEquals(response2.getHits().getTotalHits().value, hits) + ); + final long multiHits; + MultiSearchResponse multiSearchResponse = client().prepareMultiSearch() + .add(prepareSearch(index).setQuery(QueryBuilders.matchAllQuery())) + .get(); + try { + multiHits = multiSearchResponse.getResponses()[0].getResponse().getHits().getTotalHits().value; + assertThat(hits, greaterThan(0L)); + } finally { + multiSearchResponse.decRef(); + } + multiSearchResponse = client().filterWithHeader( + singletonMap("Authorization", UsernamePasswordToken.basicAuthHeaderValue("kibana_user", USERS_PASSWD)) + ).prepareMultiSearch().add(prepareSearch(index).setQuery(QueryBuilders.matchAllQuery())).get(); + try { + assertEquals(multiSearchResponse.getResponses()[0].getResponse().getHits().getTotalHits().value, multiHits); + } finally { + multiSearchResponse.decRef(); + } + }); } public void testGetIndex() throws Exception { diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/MultipleIndicesPermissionsTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/MultipleIndicesPermissionsTests.java index 2e5d92839d3f7..08fb0c79a076c 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/MultipleIndicesPermissionsTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/MultipleIndicesPermissionsTests.java @@ -15,7 +15,6 @@ import org.elasticsearch.action.admin.indices.shards.IndicesShardStoresResponse; import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; import org.elasticsearch.action.search.MultiSearchResponse; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.Response; @@ -39,7 +38,9 @@ import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCountAndNoFailures; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; @@ -144,19 +145,13 @@ public void testSingleRole() throws Exception { Client client = client(); // no specifying an index, should replace indices with the permitted ones (test & test1) - SearchResponse searchResponse = client.prepareSearch().setQuery(matchAllQuery()).get(); - assertNoFailures(searchResponse); - assertHitCount(searchResponse, 2); + assertHitCountAndNoFailures(prepareSearch().setQuery(matchAllQuery()), 2); // _all should expand to all the permitted indices - searchResponse = client.prepareSearch("_all").setQuery(matchAllQuery()).get(); - assertNoFailures(searchResponse); - assertHitCount(searchResponse, 2); + assertHitCountAndNoFailures(client.prepareSearch("_all").setQuery(matchAllQuery()), 2); // wildcards should expand to all the permitted indices - searchResponse = client.prepareSearch("test*").setQuery(matchAllQuery()).get(); - assertNoFailures(searchResponse); - assertHitCount(searchResponse, 2); + assertHitCountAndNoFailures(client.prepareSearch("test*").setQuery(matchAllQuery()), 2); try { client.prepareSearch("test", "test2").setQuery(matchAllQuery()).get(); @@ -174,7 +169,7 @@ public void testSingleRole() throws Exception { MultiSearchResponse.Item[] items = msearchResponse.getResponses(); assertThat(items.length, is(2)); assertThat(items[0].isFailure(), is(false)); - searchResponse = items[0].getResponse(); + var searchResponse = items[0].getResponse(); assertNoFailures(searchResponse); assertHitCount(searchResponse, 1); assertThat(items[1].isFailure(), is(false)); @@ -252,18 +247,18 @@ public void testMultipleRoles() throws Exception { Client client = client(); - SearchResponse response = client.filterWithHeader( - Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_a", USERS_PASSWD)) - ).prepareSearch("a").get(); - assertNoFailures(response); - assertHitCount(response, 1); + assertHitCountAndNoFailures( + client.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_a", USERS_PASSWD))) + .prepareSearch("a"), + 1 + ); String[] indices = randomDouble() < 0.3 ? new String[] { "_all" } : randomBoolean() ? new String[] { "*" } : new String[] {}; - response = client.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_a", USERS_PASSWD))) - .prepareSearch(indices) - .get(); - assertNoFailures(response); - assertHitCount(response, 1); + assertHitCountAndNoFailures( + client.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_a", USERS_PASSWD))) + .prepareSearch(indices), + 1 + ); try { indices = randomBoolean() ? new String[] { "a", "b" } : new String[] { "b", "a" }; @@ -279,25 +274,25 @@ public void testMultipleRoles() throws Exception { assertThat(e.status(), is(RestStatus.FORBIDDEN)); } - response = client.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_ab", USERS_PASSWD))) - .prepareSearch("b") - .get(); - assertNoFailures(response); - assertHitCount(response, 1); + assertHitCountAndNoFailures( + client.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_ab", USERS_PASSWD))) + .prepareSearch("b"), + 1 + ); indices = randomBoolean() ? new String[] { "a", "b" } : new String[] { "b", "a" }; - response = client.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_ab", USERS_PASSWD))) - .prepareSearch(indices) - .get(); - assertNoFailures(response); - assertHitCount(response, 2); + assertHitCountAndNoFailures( + client.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_ab", USERS_PASSWD))) + .prepareSearch(indices), + 2 + ); indices = randomDouble() < 0.3 ? new String[] { "_all" } : randomBoolean() ? new String[] { "*" } : new String[] {}; - response = client.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_ab", USERS_PASSWD))) - .prepareSearch(indices) - .get(); - assertNoFailures(response); - assertHitCount(response, 2); + assertHitCountAndNoFailures( + client.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_ab", USERS_PASSWD))) + .prepareSearch(indices), + 2 + ); } public void testMultiNamesWorkCorrectly() { @@ -313,8 +308,10 @@ public void testMultiNamesWorkCorrectly() { Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user_a", USERS_PASSWD)) ); - final SearchResponse searchResponse = userAClient.prepareSearch("alias1").setSize(0).get(); - assertThat(searchResponse.getHits().getTotalHits().value, equalTo(0L)); + assertResponse( + userAClient.prepareSearch("alias1").setSize(0), + searchResponse -> assertThat(searchResponse.getHits().getTotalHits().value, equalTo(0L)) + ); final ElasticsearchSecurityException e1 = expectThrows( ElasticsearchSecurityException.class, diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/SecurityCachePermissionTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/SecurityCachePermissionTests.java index 30f8507325a7e..82622b03d8d52 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/SecurityCachePermissionTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/integration/SecurityCachePermissionTests.java @@ -7,7 +7,6 @@ package org.elasticsearch.integration; import org.elasticsearch.ElasticsearchSecurityException; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.indices.TermsLookup; import org.elasticsearch.test.SecurityIntegTestCase; @@ -16,6 +15,7 @@ import org.junit.Before; import static java.util.Collections.singletonMap; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; @@ -47,15 +47,19 @@ public void loadData() { } public void testThatTermsFilterQueryDoesntLeakData() { - SearchResponse response = prepareSearch("data").setQuery( - QueryBuilders.constantScoreQuery(QueryBuilders.termsLookupQuery("token", new TermsLookup("tokens", "1", "tokens"))) - ).get(); - assertThat(response.isTimedOut(), is(false)); - assertThat(response.getHits().getHits().length, is(1)); + assertResponse( + prepareSearch("data").setQuery( + QueryBuilders.constantScoreQuery(QueryBuilders.termsLookupQuery("token", new TermsLookup("tokens", "1", "tokens"))) + ), + response -> { + assertThat(response.isTimedOut(), is(false)); + assertThat(response.getHits().getHits().length, is(1)); + } + ); // Repeat with unauthorized user!!!! try { - response = client().filterWithHeader( + var response = client().filterWithHeader( singletonMap( "Authorization", basicAuthHeaderValue(READ_ONE_IDX_USER, SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING) diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ScrollHelperIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ScrollHelperIntegTests.java index c1925b71608c1..7fc4c1520f9c6 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ScrollHelperIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/ScrollHelperIntegTests.java @@ -92,21 +92,14 @@ public void testFetchAllByEntityWithBrokenScroll() { false, 1 ); - SearchResponse response = new SearchResponse( - internalResponse, - scrollId, - 1, - 1, - 0, - 0, - ShardSearchFailure.EMPTY_ARRAY, - SearchResponse.Clusters.EMPTY - ); Answer returnResponse = invocation -> { @SuppressWarnings("unchecked") ActionListener listener = (ActionListener) invocation.getArguments()[1]; - listener.onResponse(response); + ActionListener.respondAndRelease( + listener, + new SearchResponse(internalResponse, scrollId, 1, 1, 0, 0, ShardSearchFailure.EMPTY_ARRAY, SearchResponse.Clusters.EMPTY) + ); return null; }; doAnswer(returnResponse).when(client).search(eq(request), any()); diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealmIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealmIntegTests.java index cb07cd76a5faa..d6aea4c64b246 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealmIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealmIntegTests.java @@ -13,7 +13,6 @@ import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexResponse; import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.client.internal.Client; import org.elasticsearch.common.Strings; @@ -81,6 +80,7 @@ import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoTimeout; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; import static org.elasticsearch.xpack.core.security.test.TestRestrictedIndices.INTERNAL_SECURITY_MAIN_INDEX_7; import static org.elasticsearch.xpack.security.support.SecuritySystemIndices.SECURITY_MAIN_ALIAS; @@ -319,9 +319,10 @@ private void testAddUserAndRoleThenAuth(String username, String roleName) { prepareIndex("idx").setId("1").setSource("body", "foo").setRefreshPolicy(IMMEDIATE).get(); String token = basicAuthHeaderValue(username, new SecureString("s3krit-password")); - SearchResponse searchResp = client().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("idx").get(); - - assertEquals(1L, searchResp.getHits().getTotalHits().value); + assertResponse( + client().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("idx"), + searchResp -> assertEquals(1L, searchResp.getHits().getTotalHits().value) + ); assertClusterHealthOnlyAuthorizesWhenAnonymousRoleActive(token); } @@ -341,9 +342,10 @@ public void testUpdatingUserAndAuthentication() throws Exception { // Index a document with the default test user prepareIndex("idx").setId("1").setSource("body", "foo").setRefreshPolicy(IMMEDIATE).get(); String token = basicAuthHeaderValue("joe", new SecureString("s3krit-password")); - SearchResponse searchResp = client().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("idx").get(); - - assertEquals(1L, searchResp.getHits().getTotalHits().value); + assertResponse( + client().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("idx"), + searchResp -> assertEquals(1L, searchResp.getHits().getTotalHits().value) + ); preparePutUser("joe", "s3krit-password2", hasher, SecuritySettingsSource.TEST_ROLE).get(); @@ -356,8 +358,10 @@ public void testUpdatingUserAndAuthentication() throws Exception { } token = basicAuthHeaderValue("joe", new SecureString("s3krit-password2")); - searchResp = client().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("idx").get(); - assertEquals(1L, searchResp.getHits().getTotalHits().value); + assertResponse( + client().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("idx"), + searchResp -> assertEquals(1L, searchResp.getHits().getTotalHits().value) + ); } public void testCreateDeleteAuthenticate() { @@ -375,9 +379,10 @@ public void testCreateDeleteAuthenticate() { // Index a document with the default test user prepareIndex("idx").setId("1").setSource("body", "foo").setRefreshPolicy(IMMEDIATE).get(); String token = basicAuthHeaderValue("joe", new SecureString("s3krit-password")); - SearchResponse searchResp = client().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("idx").get(); - - assertEquals(1L, searchResp.getHits().getTotalHits().value); + assertResponse( + client().filterWithHeader(Collections.singletonMap("Authorization", token)).prepareSearch("idx"), + searchResp -> assertEquals(1L, searchResp.getHits().getTotalHits().value) + ); DeleteUserResponse response = new DeleteUserRequestBuilder(client()).username("joe").get(); assertThat(response.found(), is(true)); diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/ReadActionsTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/ReadActionsTests.java index 7e5fd3a8717e2..f34983f7f125c 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/ReadActionsTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/ReadActionsTests.java @@ -442,12 +442,7 @@ private static T expectThrows(Class expectedType, Searc } private static void assertReturnedIndices(SearchRequestBuilder searchRequestBuilder, String... indices) { - var searchResponse = searchRequestBuilder.get(); - try { - assertReturnedIndices(searchResponse, indices); - } finally { - searchResponse.decRef(); - } + assertResponse(searchRequestBuilder, searchResponse -> assertReturnedIndices(searchResponse, indices)); } private static void assertReturnedIndices(SearchResponse searchResponse, String... indices) { diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/SecurityScrollTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/SecurityScrollTests.java index c5da26deaf03d..1b62c79236a9c 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/SecurityScrollTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/authz/SecurityScrollTests.java @@ -24,6 +24,7 @@ import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; @@ -46,29 +47,32 @@ public void testScrollIsPerUser() throws Exception { } indexRandom(true, docs); - SearchResponse response = prepareSearch("foo").setScroll(TimeValue.timeValueSeconds(5L)).setQuery(matchAllQuery()).setSize(1).get(); - assertEquals(numDocs, response.getHits().getTotalHits().value); - assertEquals(1, response.getHits().getHits().length); - - if (randomBoolean()) { - response = client().prepareSearchScroll(response.getScrollId()).setScroll(TimeValue.timeValueSeconds(5L)).get(); + assertResponse(prepareSearch("foo").setScroll(TimeValue.timeValueSeconds(5L)).setQuery(matchAllQuery()).setSize(1), response -> { assertEquals(numDocs, response.getHits().getTotalHits().value); assertEquals(1, response.getHits().getHits().length); - } - - final String scrollId = response.getScrollId(); - SearchPhaseExecutionException e = expectThrows( - SearchPhaseExecutionException.class, - () -> client().filterWithHeader( - Collections.singletonMap( - "Authorization", - UsernamePasswordToken.basicAuthHeaderValue("other", SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING) - ) - ).prepareSearchScroll(scrollId).get() - ); - for (ShardSearchFailure failure : e.shardFailures()) { - assertThat(ExceptionsHelper.unwrapCause(failure.getCause()), instanceOf(SearchContextMissingException.class)); - } + if (randomBoolean()) { + assertResponse( + client().prepareSearchScroll(response.getScrollId()).setScroll(TimeValue.timeValueSeconds(5L)), + response2 -> { + assertEquals(numDocs, response2.getHits().getTotalHits().value); + assertEquals(1, response2.getHits().getHits().length); + } + ); + } + final String scrollId = response.getScrollId(); + SearchPhaseExecutionException e = expectThrows( + SearchPhaseExecutionException.class, + () -> client().filterWithHeader( + Collections.singletonMap( + "Authorization", + UsernamePasswordToken.basicAuthHeaderValue("other", SecuritySettingsSourceField.TEST_PASSWORD_SECURE_STRING) + ) + ).prepareSearchScroll(scrollId).get() + ); + for (ShardSearchFailure failure : e.shardFailures()) { + assertThat(ExceptionsHelper.unwrapCause(failure.getCause()), instanceOf(SearchContextMissingException.class)); + } + }); } public void testSearchAndClearScroll() throws Exception { @@ -87,12 +91,14 @@ public void testSearchAndClearScroll() throws Exception { do { assertHitCount(response, docs.length); hits += response.getHits().getHits().length; + response.decRef(); response = client().prepareSearchScroll(response.getScrollId()).setScroll(TimeValue.timeValueSeconds(5L)).get(); } while (response.getHits().getHits().length != 0); assertThat(hits, equalTo(docs.length)); } finally { clearScroll(response.getScrollId()); + response.decRef(); } } diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/profile/SecurityDomainIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/profile/SecurityDomainIntegTests.java index 66c5b9fa02ab4..f43275c2d8b70 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/profile/SecurityDomainIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/profile/SecurityDomainIntegTests.java @@ -8,7 +8,6 @@ package org.elasticsearch.xpack.security.profile; import org.elasticsearch.ElasticsearchSecurityException; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.bytes.BytesArray; import org.elasticsearch.common.settings.MockSecureSettings; import org.elasticsearch.common.settings.Settings; @@ -47,6 +46,7 @@ import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.NONE; import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.WAIT_UNTIL; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; import static org.elasticsearch.xpack.security.support.SecuritySystemIndices.SECURITY_MAIN_ALIAS; import static org.hamcrest.Matchers.containsString; @@ -368,26 +368,31 @@ public void testDomainCaptureForServiceToken() throws IOException { .get(); } - private void assertAccessToken(CreateTokenResponse createTokenResponse) throws IOException { + private void assertAccessToken(CreateTokenResponse createTokenResponse) { client().filterWithHeader(Map.of("Authorization", "Bearer " + createTokenResponse.getTokenString())) .admin() .cluster() .prepareHealth() .get(); - final SearchResponse searchResponse = prepareSearch(SecuritySystemIndices.SECURITY_TOKENS_ALIAS).get(); - - final String encodedAuthentication = createTokenResponse.getAuthentication().encode(); - for (SearchHit searchHit : searchResponse.getHits().getHits()) { - final XContentTestUtils.JsonMapView responseView = XContentTestUtils.createJsonMapView( - new ByteArrayInputStream(searchHit.getSourceAsString().getBytes(StandardCharsets.UTF_8)) - ); - if (encodedAuthentication.equals(responseView.get("access_token.user_token.authentication"))) { - if (isOtherDomain) { - assertThat(responseView.get("access_token.realm_domain"), equalTo(OTHER_DOMAIN_REALM_MAP)); - } else { - assertThat(responseView.get("access_token.realm_domain"), nullValue()); + assertResponse(prepareSearch(SecuritySystemIndices.SECURITY_TOKENS_ALIAS), searchResponse -> { + final String encodedAuthentication; + try { + encodedAuthentication = createTokenResponse.getAuthentication().encode(); + } catch (IOException e) { + throw new AssertionError(e); + } + for (SearchHit searchHit : searchResponse.getHits().getHits()) { + final XContentTestUtils.JsonMapView responseView = XContentTestUtils.createJsonMapView( + new ByteArrayInputStream(searchHit.getSourceAsString().getBytes(StandardCharsets.UTF_8)) + ); + if (encodedAuthentication.equals(responseView.get("access_token.user_token.authentication"))) { + if (isOtherDomain) { + assertThat(responseView.get("access_token.realm_domain"), equalTo(OTHER_DOMAIN_REALM_MAP)); + } else { + assertThat(responseView.get("access_token.realm_domain"), nullValue()); + } } } - } + }); } } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlInvalidateSessionActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlInvalidateSessionActionTests.java index eb702ed281014..8743453d33a35 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlInvalidateSessionActionTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/action/saml/TransportSamlInvalidateSessionActionTests.java @@ -198,47 +198,51 @@ protected void SearchRequest searchRequest = (SearchRequest) request; searchRequests.add(searchRequest); final SearchHit[] hits = searchFunction.apply(searchRequest); - final SearchResponse response = new SearchResponse( - new SearchResponseSections( - new SearchHits(hits, new TotalHits(hits.length, TotalHits.Relation.EQUAL_TO), 0f), + ActionListener.respondAndRelease( + listener, + (Response) new SearchResponse( + new SearchResponseSections( + new SearchHits(hits, new TotalHits(hits.length, TotalHits.Relation.EQUAL_TO), 0f), + null, + null, + false, + false, + null, + 1 + ), + "_scrollId1", + 1, + 1, + 0, + 1, null, - null, - false, - false, - null, - 1 - ), - "_scrollId1", - 1, - 1, - 0, - 1, - null, - null + null + ) ); - listener.onResponse((Response) response); } else if (TransportSearchScrollAction.TYPE.name().equals(action.name())) { assertThat(request, instanceOf(SearchScrollRequest.class)); final SearchHit[] hits = new SearchHit[0]; - final SearchResponse response = new SearchResponse( - new SearchResponseSections( - new SearchHits(hits, new TotalHits(hits.length, TotalHits.Relation.EQUAL_TO), 0f), + ActionListener.respondAndRelease( + listener, + (Response) new SearchResponse( + new SearchResponseSections( + new SearchHits(hits, new TotalHits(hits.length, TotalHits.Relation.EQUAL_TO), 0f), + null, + null, + false, + false, + null, + 1 + ), + "_scrollId1", + 1, + 1, + 0, + 1, null, - null, - false, - false, - null, - 1 - ), - "_scrollId1", - 1, - 1, - 0, - 1, - null, - null + null + ) ); - listener.onResponse((Response) response); } else if (TransportClearScrollAction.NAME.equals(action.name())) { assertThat(request, instanceOf(ClearScrollRequest.class)); ClearScrollRequest scrollRequest = (ClearScrollRequest) request; diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java index 2031cd4f7685b..25194ca1e0234 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java @@ -275,7 +275,7 @@ public void testGetApiKeys() throws Exception { doAnswer(invocationOnMock -> { searchRequest.set((SearchRequest) invocationOnMock.getArguments()[0]); ActionListener listener = (ActionListener) invocationOnMock.getArguments()[1]; - listener.onResponse(SearchResponse.empty(() -> 1L, SearchResponse.Clusters.EMPTY)); + ActionListener.respondAndRelease(listener, SearchResponse.empty(() -> 1L, SearchResponse.Clusters.EMPTY)); return null; }).when(client).search(any(SearchRequest.class), anyActionListener()); String[] realmNames = generateRandomStringArray(4, 4, true, true); @@ -336,7 +336,7 @@ public void testInvalidateApiKeys() throws Exception { doAnswer(invocationOnMock -> { searchRequest.set((SearchRequest) invocationOnMock.getArguments()[0]); ActionListener listener = (ActionListener) invocationOnMock.getArguments()[1]; - listener.onResponse(SearchResponse.empty(() -> 1L, SearchResponse.Clusters.EMPTY)); + ActionListener.respondAndRelease(listener, SearchResponse.empty(() -> 1L, SearchResponse.Clusters.EMPTY)); return null; }).when(client).search(any(SearchRequest.class), anyActionListener()); PlainActionFuture listener = new PlainActionFuture<>(); @@ -427,17 +427,10 @@ public void testInvalidateApiKeysWillSetInvalidatedFlagAndRecordTimestamp() { null, 0 ); - final var searchResponse = new SearchResponse( - internalSearchResponse, - randomAlphaOfLengthBetween(3, 8), - 1, - 1, - 0, - 10, - null, - null + ActionListener.respondAndRelease( + listener, + new SearchResponse(internalSearchResponse, randomAlphaOfLengthBetween(3, 8), 1, 1, 0, 10, null, null) ); - listener.onResponse(searchResponse); return null; }).when(client).search(any(SearchRequest.class), anyActionListener()); @@ -756,33 +749,35 @@ public void testCrossClusterApiKeyUsageStats() { final AtomicReference searchRequest = new AtomicReference<>(); doAnswer(invocationOnMock -> { searchRequest.set(invocationOnMock.getArgument(0)); - final var searchResponse = new SearchResponse( - new InternalSearchResponse( - new SearchHits( - searchHits.toArray(SearchHit[]::new), - new TotalHits(searchHits.size(), TotalHits.Relation.EQUAL_TO), - randomFloat(), + final ActionListener listener = invocationOnMock.getArgument(1); + ActionListener.respondAndRelease( + listener, + new SearchResponse( + new InternalSearchResponse( + new SearchHits( + searchHits.toArray(SearchHit[]::new), + new TotalHits(searchHits.size(), TotalHits.Relation.EQUAL_TO), + randomFloat(), + null, + null, + null + ), + null, null, null, - null + false, + null, + 0 ), + randomAlphaOfLengthBetween(3, 8), + 1, + 1, + 0, + 10, null, - null, - null, - false, - null, - 0 - ), - randomAlphaOfLengthBetween(3, 8), - 1, - 1, - 0, - 10, - null, - null + null + ) ); - final ActionListener listener = invocationOnMock.getArgument(1); - listener.onResponse(searchResponse); return null; }).when(client).search(any(SearchRequest.class), anyActionListener()); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/IndexServiceAccountTokenStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/IndexServiceAccountTokenStoreTests.java index 2dec4eb8ea2b5..8d5d89b4c5054 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/IndexServiceAccountTokenStoreTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/service/IndexServiceAccountTokenStoreTests.java @@ -280,18 +280,10 @@ public void testFindTokensFor() { null, 0 ); - - final SearchResponse searchResponse = new SearchResponse( - internalSearchResponse, - randomAlphaOfLengthBetween(3, 8), - 1, - 1, - 0, - 10, - null, - null + ActionListener.respondAndRelease( + l, + new SearchResponse(internalSearchResponse, randomAlphaOfLengthBetween(3, 8), 1, 1, 0, 10, null, null) ); - l.onResponse(searchResponse); } else if (r instanceof ClearScrollRequest) { l.onResponse(new ClearScrollResponse(true, 1)); } else { diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/mapper/NativeRoleMappingStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/mapper/NativeRoleMappingStoreTests.java index bcb335c7cf9bc..3b52f86c00ba8 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/mapper/NativeRoleMappingStoreTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/mapper/NativeRoleMappingStoreTests.java @@ -371,17 +371,10 @@ private void doAnswerWithSearchResult(Client client, ExpressionRoleMapping mappi null, 0 ); - final var searchResponse = new SearchResponse( - internalSearchResponse, - randomAlphaOfLengthBetween(3, 8), - 1, - 1, - 0, - 10, - null, - null + ActionListener.respondAndRelease( + listener, + new SearchResponse(internalSearchResponse, randomAlphaOfLengthBetween(3, 8), 1, 1, 0, 10, null, null) ); - listener.onResponse(searchResponse); return null; }).when(client).search(any(SearchRequest.class), anyActionListener()); } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/NativePrivilegeStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/NativePrivilegeStoreTests.java index 53df6e6157282..d229124419cb2 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/NativePrivilegeStoreTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/NativePrivilegeStoreTests.java @@ -134,7 +134,7 @@ protected void @Override public void searchScroll(SearchScrollRequest request, ActionListener listener) { - listener.onResponse(SearchResponse.empty(() -> 1L, SearchResponse.Clusters.EMPTY)); + ActionListener.respondAndRelease(listener, SearchResponse.empty(() -> 1L, SearchResponse.Clusters.EMPTY)); } }; securityIndex = mock(SecurityIndexManager.class); @@ -189,7 +189,7 @@ public void testGetSinglePrivilegeByName() throws Exception { {"term":{"type":{"value":"application-privilege\"""")); final SearchHit[] hits = buildHits(sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); assertResult(sourcePrivileges, future); } @@ -198,7 +198,7 @@ public void testGetMissingPrivilege() throws InterruptedException, ExecutionExce final PlainActionFuture> future = new PlainActionFuture<>(); store.getPrivileges(List.of("myapp"), List.of("admin"), future); final SearchHit[] hits = new SearchHit[0]; - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); final Collection applicationPrivilegeDescriptors = future.get(1, TimeUnit.SECONDS); assertThat(applicationPrivilegeDescriptors, empty()); @@ -225,7 +225,7 @@ public void testGetPrivilegesByApplicationName() throws Exception { {"term":{"type":{"value":"application-privilege\"""")); final SearchHit[] hits = buildHits(sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); assertResult(sourcePrivileges, future); } @@ -283,7 +283,7 @@ public void testGetPrivilegesByWildcardApplicationName() throws Exception { } final SearchHit[] hits = buildHits(allowExpensiveQueries ? sourcePrivileges.subList(1, 4) : sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); // The first and last privilege should not be retrieved assertResult(sourcePrivileges.subList(1, 4), future); } @@ -300,7 +300,7 @@ public void testGetPrivilegesByStarApplicationName() throws Exception { assertThat(query, containsString("{\"term\":{\"type\":{\"value\":\"application-privilege\"")); final SearchHit[] hits = new SearchHit[0]; - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); } public void testGetAllPrivileges() throws Exception { @@ -321,7 +321,7 @@ public void testGetAllPrivileges() throws Exception { assertThat(query, not(containsString("{\"terms\""))); final SearchHit[] hits = buildHits(sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); assertResult(sourcePrivileges, future); } @@ -337,7 +337,7 @@ public void testGetPrivilegesCacheByApplicationNames() throws Exception { store.getPrivileges(List.of("myapp", "yourapp"), null, future); final SearchHit[] hits = buildHits(sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); assertEquals(Set.of("myapp"), store.getApplicationNamesCache().get(Set.of("myapp", "yourapp"))); assertEquals(Set.copyOf(sourcePrivileges), store.getDescriptorsCache().get("myapp")); @@ -369,7 +369,7 @@ public void testGetPrivilegesCacheWithApplicationAndPrivilegeName() throws Excep store.getPrivileges(Collections.singletonList("myapp"), singletonList("user"), future); final SearchHit[] hits = buildHits(sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); // Not caching names with no wildcard assertNull(store.getApplicationNamesCache().get(singleton("myapp"))); @@ -388,7 +388,7 @@ public void testGetPrivilegesCacheWithNonExistentApplicationName() throws Except final PlainActionFuture> future = new PlainActionFuture<>(); store.getPrivileges(Collections.singletonList("no-such-app"), null, future); final SearchHit[] hits = buildHits(emptyList()); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); assertEquals(emptySet(), store.getApplicationNamesCache().get(singleton("no-such-app"))); assertEquals(0, store.getDescriptorsCache().count()); @@ -405,7 +405,7 @@ public void testGetPrivilegesCacheWithDifferentMatchAllApplicationNames() throws final PlainActionFuture> future = new PlainActionFuture<>(); store.getPrivileges(emptyList(), null, future); final SearchHit[] hits = buildHits(emptyList()); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); assertEquals(emptySet(), store.getApplicationNamesCache().get(singleton("*"))); assertEquals(1, store.getApplicationNamesCache().count()); assertResult(emptyList(), future); @@ -442,7 +442,7 @@ public void testCacheIsClearedByApplicationNameWhenPrivilegesAreModified() throw new ApplicationPrivilegeDescriptor("app2", "priv2b", Set.of("action:2b"), Map.of()) ); final SearchHit[] hits = buildHits(sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); assertEquals(Set.of("app1", "app2"), store.getApplicationNamesCache().get(singleton("*"))); assertResult(sourcePrivileges, getFuture); @@ -505,7 +505,7 @@ public void testStaleResultsWillNotBeCached() { // Before the results can be cached, invalidate the cache to simulate stale search results store.getDescriptorsAndApplicationNamesCache().invalidateAll(); final SearchHit[] hits = buildHits(sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); // Nothing should be cached since the results are stale assertEquals(0, store.getApplicationNamesCache().count()); @@ -553,7 +553,7 @@ protected void cacheFetchedDescriptors( final PlainActionFuture> future = new PlainActionFuture<>(); store1.getPrivileges(null, null, future); final SearchHit[] hits = buildHits(sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); // Make sure the caching is about to happen getPrivilegeCountDown.await(5, TimeUnit.SECONDS); @@ -779,7 +779,7 @@ public void testGetPrivilegesWorkWithoutCache() throws Exception { final PlainActionFuture> future = new PlainActionFuture<>(); store1.getPrivileges(singletonList("myapp"), null, future); final SearchHit[] hits = buildHits(sourcePrivileges); - listener.get().onResponse(buildSearchResponse(hits)); + ActionListener.respondAndRelease(listener.get(), buildSearchResponse(hits)); assertResult(sourcePrivileges, future); }