diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/accesscontrol/IndicesAccessControl.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/accesscontrol/IndicesAccessControl.java
index 1bec72f80af..0749705757e 100644
--- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/accesscontrol/IndicesAccessControl.java
+++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/accesscontrol/IndicesAccessControl.java
@@ -94,8 +94,9 @@ public class IndicesAccessControl {
// this code is a bit of a pita, but right now we can't just initialize an empty set,
// because an empty Set means no permissions on fields and
// null
means no field level security
+ // Also, if one grants no access to fields and the other grants all access, merging should result in all access...
Set fields = null;
- if (this.fields != null || other.getFields() != null) {
+ if (this.fields != null && other.getFields() != null) {
fields = new HashSet<>();
if (this.fields != null) {
fields.addAll(this.fields);
@@ -106,7 +107,7 @@ public class IndicesAccessControl {
fields = unmodifiableSet(fields);
}
Set queries = null;
- if (this.queries != null || other.getQueries() != null) {
+ if (this.queries != null && other.getQueries() != null) {
queries = new HashSet<>();
if (this.queries != null) {
queries.addAll(this.queries);
diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/accesscontrol/ShieldIndexSearcherWrapper.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/accesscontrol/ShieldIndexSearcherWrapper.java
index 8cc2410a40b..b7fc1e6b511 100644
--- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/accesscontrol/ShieldIndexSearcherWrapper.java
+++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/accesscontrol/ShieldIndexSearcherWrapper.java
@@ -12,6 +12,7 @@ import org.apache.lucene.search.BulkScorer;
import org.apache.lucene.search.CollectionTerminatedException;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.ConjunctionDISI;
+import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.LeafCollector;
@@ -52,7 +53,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import static org.apache.lucene.search.BooleanClause.Occur.FILTER;
+import static org.apache.lucene.search.BooleanClause.Occur.SHOULD;
/**
* An {@link IndexSearcherWrapper} implementation that is used for field and document level security.
@@ -116,13 +117,15 @@ public class ShieldIndexSearcherWrapper extends IndexSearcherWrapper {
}
if (permissions.getQueries() != null) {
- BooleanQuery.Builder roleQuery = new BooleanQuery.Builder();
+ BooleanQuery.Builder filter = new BooleanQuery.Builder();
for (BytesReference bytesReference : permissions.getQueries()) {
QueryShardContext queryShardContext = copyQueryShardContext(this.queryShardContext);
ParsedQuery parsedQuery = queryShardContext.parse(bytesReference);
- roleQuery.add(parsedQuery.query(), FILTER);
+ filter.add(parsedQuery.query(), SHOULD);
}
- reader = DocumentSubsetReader.wrap(reader, bitsetFilterCache, roleQuery.build());
+ // at least one of the queries should match
+ filter.setMinimumNumberShouldMatch(1);
+ reader = DocumentSubsetReader.wrap(reader, bitsetFilterCache, new ConstantScoreQuery(filter.build()));
}
if (permissions.getFields() != null) {
diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentAndFieldLevelSecurityTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentAndFieldLevelSecurityTests.java
index c0b24daf45b..bb685de20bf 100644
--- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentAndFieldLevelSecurityTests.java
+++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentAndFieldLevelSecurityTests.java
@@ -35,15 +35,16 @@ public class DocumentAndFieldLevelSecurityTests extends ShieldIntegTestCase {
return super.configUsers() +
"user1:" + USERS_PASSWD_HASHED + "\n" +
"user2:" + USERS_PASSWD_HASHED + "\n" +
- "user3:" + USERS_PASSWD_HASHED + "\n" ;
+ "user3:" + USERS_PASSWD_HASHED + "\n" +
+ "user4:" + USERS_PASSWD_HASHED + "\n";
}
@Override
protected String configUsersRoles() {
return super.configUsersRoles() +
- "role1:user1\n" +
- "role2:user2\n" +
- "role3:user3\n";
+ "role1:user1,user4\n" +
+ "role2:user2,user4\n" +
+ "role3:user3,user4\n";
}
@Override
@@ -107,6 +108,14 @@ public class DocumentAndFieldLevelSecurityTests extends ShieldIntegTestCase {
assertSearchHits(response, "2");
assertThat(response.getHits().getAt(0).getSource().size(), equalTo(1));
assertThat(response.getHits().getAt(0).getSource().get("field2").toString(), equalTo("value2"));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD)))
+ .prepareSearch("test")
+ .get();
+ assertHitCount(response, 2);
+ assertSearchHits(response, "1", "2");
+ assertThat(response.getHits().getAt(0).getSource().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getHits().getAt(1).getSource().get("field2").toString(), equalTo("value2"));
}
public void testQueryCache() throws Exception {
@@ -149,6 +158,19 @@ public class DocumentAndFieldLevelSecurityTests extends ShieldIntegTestCase {
assertHitCount(response, 1);
assertThat(response.getHits().getAt(0).getId(), equalTo("2"));
assertThat(response.getHits().getAt(0).sourceAsMap().size(), equalTo(0));
+
+ // user4 has all roles
+ response = client().filterWithHeader(
+ Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD)))
+ .prepareSearch("test")
+ .get();
+ assertHitCount(response, 2);
+ assertThat(response.getHits().getAt(0).getId(), equalTo("1"));
+ assertThat(response.getHits().getAt(0).sourceAsMap().size(), equalTo(1));
+ assertThat(response.getHits().getAt(0).sourceAsMap().get("field1"), equalTo("value1"));
+ assertThat(response.getHits().getAt(1).getId(), equalTo("2"));
+ assertThat(response.getHits().getAt(1).sourceAsMap().size(), equalTo(1));
+ assertThat(response.getHits().getAt(1).sourceAsMap().get("field2"), equalTo("value2"));
}
}
diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentLevelSecurityTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentLevelSecurityTests.java
index ea658189b7a..38b6475eeaa 100644
--- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentLevelSecurityTests.java
+++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentLevelSecurityTests.java
@@ -16,6 +16,7 @@ import org.elasticsearch.action.termvectors.TermVectorsRequest;
import org.elasticsearch.action.termvectors.TermVectorsResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.indices.IndicesRequestCache;
import org.elasticsearch.rest.RestStatus;
@@ -56,15 +57,17 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
protected String configUsers() {
return super.configUsers() +
"user1:" + USERS_PASSWD_HASHED + "\n" +
- "user2:" + USERS_PASSWD_HASHED + "\n" ;
+ "user2:" + USERS_PASSWD_HASHED + "\n" +
+ "user3:" + USERS_PASSWD_HASHED + "\n" ;
}
@Override
protected String configUsersRoles() {
return super.configUsersRoles() +
- "role1:user1\n" +
- "role2:user2\n";
+ "role1:user1,user3\n" +
+ "role2:user2,user3\n";
}
+
@Override
protected String configRoles() {
return super.configRoles() +
@@ -94,7 +97,7 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
public void testSimpleQuery() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
client().prepareIndex("test", "type1", "1").setSource("field1", "value1")
.setRefresh(true)
@@ -102,6 +105,9 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
client().prepareIndex("test", "type1", "2").setSource("field2", "value2")
.setRefresh(true)
.get();
+ client().prepareIndex("test", "type1", "3").setSource("field3", "value3")
+ .setRefresh(true)
+ .get();
SearchResponse response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
@@ -110,24 +116,36 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
.get();
assertHitCount(response, 1);
assertSearchHits(response, "1");
+
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.prepareSearch("test")
.setQuery(randomBoolean() ? QueryBuilders.termQuery("field2", "value2") : QueryBuilders.matchAllQuery())
.get();
assertHitCount(response, 1);
assertSearchHits(response, "2");
+
+ QueryBuilder combined = QueryBuilders.boolQuery()
+ .should(QueryBuilders.termQuery("field2", "value2"))
+ .should(QueryBuilders.termQuery("field1", "value1"))
+ .minimumNumberShouldMatch(1);
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(randomBoolean() ? combined : QueryBuilders.matchAllQuery())
+ .get();
+ assertHitCount(response, 2);
+ assertSearchHits(response, "1", "2");
}
public void testGetApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1")
- .get();
- client().prepareIndex("test", "type1", "2").setSource("field2", "value2")
- .get();
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1").get();
+ client().prepareIndex("test", "type1", "2").setSource("field2", "value2").get();
+ client().prepareIndex("test", "type1", "3").setSource("field3", "value3").get();
+ // test documents users can see
Boolean realtime = randomFrom(true, false, null);
GetResponse response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
@@ -137,6 +155,7 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
.get();
assertThat(response.isExists(), is(true));
assertThat(response.getId(), equalTo("1"));
+
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.prepareGet("test", "type1", "2")
.setRealtime(realtime)
@@ -145,6 +164,23 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
assertThat(response.isExists(), is(true));
assertThat(response.getId(), equalTo("2"));
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareGet("test", "type1", "1")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getId(), equalTo("1"));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareGet("test", "type1", "2")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getId(), equalTo("2"));
+
+ // test documents user cannot see
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.prepareGet("test", "type1", "1")
.setRealtime(realtime)
@@ -157,17 +193,22 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
.setRefresh(true)
.get();
assertThat(response.isExists(), is(false));
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareGet("test", "type1", "3")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.isExists(), is(false));
}
public void testMGetApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1")
- .get();
- client().prepareIndex("test", "type1", "2").setSource("field2", "value2")
- .get();
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1").get();
+ client().prepareIndex("test", "type1", "2").setSource("field2", "value2").get();
+ client().prepareIndex("test", "type1", "3").setSource("field3", "value3").get();
Boolean realtime = randomFrom(true, false, null);
MultiGetResponse response = client()
@@ -191,6 +232,20 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
assertThat(response.getResponses()[0].getResponse().getId(), equalTo("2"));
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareMultiGet()
+ .add("test", "type1", "1")
+ .add("test", "type1", "2")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.getResponses()[0].isFailed(), is(false));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[0].getResponse().getId(), equalTo("1"));
+ assertThat(response.getResponses()[1].isFailed(), is(false));
+ assertThat(response.getResponses()[1].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[1].getResponse().getId(), equalTo("2"));
+
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.prepareMultiGet()
.add("test", "type1", "1")
@@ -208,12 +263,22 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
.get();
assertThat(response.getResponses()[0].isFailed(), is(false));
assertThat(response.getResponses()[0].getResponse().isExists(), is(false));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareMultiGet()
+ .add("test", "type1", "3")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.getResponses()[0].isFailed(), is(false));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(false));
}
public void testTVApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.addMapping("type1", "field1", "type=string,term_vector=with_positions_offsets_payloads",
- "field2", "type=string,term_vector=with_positions_offsets_payloads")
+ "field2", "type=string,term_vector=with_positions_offsets_payloads",
+ "field3", "type=string,term_vector=with_positions_offsets_payloads")
);
client().prepareIndex("test", "type1", "1").setSource("field1", "value1")
.setRefresh(true)
@@ -221,6 +286,9 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
client().prepareIndex("test", "type1", "2").setSource("field2", "value2")
.setRefresh(true)
.get();
+ client().prepareIndex("test", "type1", "3").setSource("field3", "value3")
+ .setRefresh(true)
+ .get();
Boolean realtime = randomFrom(true, false, null);
TermVectorsResponse response = client()
@@ -238,6 +306,20 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
assertThat(response.isExists(), is(true));
assertThat(response.getId(), is("2"));
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareTermVectors("test", "type1", "1")
+ .setRealtime(realtime)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getId(), is("1"));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareTermVectors("test", "type1", "2")
+ .setRealtime(realtime)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getId(), is("2"));
+
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.prepareTermVectors("test", "type1", "1")
.setRealtime(realtime)
@@ -249,12 +331,19 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
.setRealtime(realtime)
.get();
assertThat(response.isExists(), is(false));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareTermVectors("test", "type1", "3")
+ .setRealtime(realtime)
+ .get();
+ assertThat(response.isExists(), is(false));
}
public void testMTVApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.addMapping("type1", "field1", "type=string,term_vector=with_positions_offsets_payloads",
- "field2", "type=string,term_vector=with_positions_offsets_payloads")
+ "field2", "type=string,term_vector=with_positions_offsets_payloads",
+ "field3", "type=string,term_vector=with_positions_offsets_payloads")
);
client().prepareIndex("test", "type1", "1").setSource("field1", "value1")
.setRefresh(true)
@@ -262,6 +351,9 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
client().prepareIndex("test", "type1", "2").setSource("field2", "value2")
.setRefresh(true)
.get();
+ client().prepareIndex("test", "type1", "3").setSource("field3", "value3")
+ .setRefresh(true)
+ .get();
Boolean realtime = randomFrom(true, false, null);
MultiTermVectorsResponse response = client()
@@ -281,6 +373,17 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
assertThat(response.getResponses()[0].getResponse().getId(), is("2"));
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareMultiTermVectors()
+ .add(new TermVectorsRequest("test", "type1", "1").realtime(realtime))
+ .add(new TermVectorsRequest("test", "type1", "2").realtime(realtime))
+ .get();
+ assertThat(response.getResponses().length, equalTo(2));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[0].getResponse().getId(), is("1"));
+ assertThat(response.getResponses()[1].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[1].getResponse().getId(), is("2"));
+
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.prepareMultiTermVectors()
.add(new TermVectorsRequest("test", "type1", "1").realtime(realtime))
@@ -294,11 +397,18 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
.get();
assertThat(response.getResponses().length, equalTo(1));
assertThat(response.getResponses()[0].getResponse().isExists(), is(false));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareMultiTermVectors()
+ .add(new TermVectorsRequest("test", "type1", "3").realtime(realtime))
+ .get();
+ assertThat(response.getResponses().length, equalTo(1));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(false));
}
public void testGlobalAggregation() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
client().prepareIndex("test", "type1", "1").setSource("field1", "value1")
.setRefresh(true)
@@ -306,15 +416,18 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
client().prepareIndex("test", "type1", "2").setSource("field2", "value2")
.setRefresh(true)
.get();
+ client().prepareIndex("test", "type1", "3").setSource("field3", "value3")
+ .setRefresh(true)
+ .get();
SearchResponse response = client().prepareSearch("test")
.addAggregation(AggregationBuilders.global("global").subAggregation(AggregationBuilders.terms("field2").field("field2")))
.get();
- assertHitCount(response, 2);
- assertSearchHits(response, "1", "2");
+ assertHitCount(response, 3);
+ assertSearchHits(response, "1", "2", "3");
Global globalAgg = response.getAggregations().get("global");
- assertThat(globalAgg.getDocCount(), equalTo(2L));
+ 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));
@@ -330,6 +443,30 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
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));
}
public void testChildrenAggregation() throws Exception {
@@ -372,34 +509,49 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
assertThat(children.getDocCount(), equalTo(0L));
termsAgg = children.getAggregations().get("field3");
assertThat(termsAgg.getBuckets().size(), equalTo(0));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setTypes("type1")
+ .addAggregation(AggregationBuilders.children("children", "type2")
+ .subAggregation(AggregationBuilders.terms("field3").field("field3")))
+ .get();
+ assertHitCount(response, 1);
+ assertSearchHits(response, "1");
+
+ children = response.getAggregations().get("children");
+ assertThat(children.getDocCount(), equalTo(0L));
+ termsAgg = children.getAggregations().get("field3");
+ assertThat(termsAgg.getBuckets().size(), equalTo(0));
}
public void testParentChild() {
assertAcked(prepareCreate("test")
.addMapping("parent")
- .addMapping("child", "_parent", "type=parent", "field1", "type=string", "field2", "type=string"));
+ .addMapping("child", "_parent", "type=parent", "field1", "type=string", "field2", "type=string", "field3", "type=string"));
ensureGreen();
// index simple data
client().prepareIndex("test", "parent", "p1").setSource("field1", "value1").get();
client().prepareIndex("test", "child", "c1").setSource("field2", "value2").setParent("p1").get();
client().prepareIndex("test", "child", "c2").setSource("field2", "value2").setParent("p1").get();
+ client().prepareIndex("test", "child", "c3").setSource("field3", "value3").setParent("p1").get();
refresh();
SearchResponse searchResponse = client().prepareSearch("test")
.setQuery(hasChildQuery("child", matchAllQuery()))
.get();
assertHitCount(searchResponse, 1L);
- assertThat(searchResponse.getHits().totalHits(), equalTo(1L));
assertThat(searchResponse.getHits().getAt(0).id(), equalTo("p1"));
searchResponse = client().prepareSearch("test")
.setQuery(hasParentQuery("parent", matchAllQuery()))
.addSort("_id", SortOrder.ASC)
.get();
- assertHitCount(searchResponse, 2L);
+ assertHitCount(searchResponse, 3L);
assertThat(searchResponse.getHits().getAt(0).id(), equalTo("c1"));
assertThat(searchResponse.getHits().getAt(1).id(), equalTo("c2"));
+ assertThat(searchResponse.getHits().getAt(2).id(), equalTo("c3"));
// Both user1 and user2 can't see field1 and field2, no parent/child query should yield results:
searchResponse = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
@@ -425,11 +577,27 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
.setQuery(hasParentQuery("parent", matchAllQuery()))
.get();
assertHitCount(searchResponse, 0L);
+
+ // 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()))
+ .get();
+ assertHitCount(searchResponse, 1L);
+ assertThat(searchResponse.getHits().getAt(0).id(), equalTo("p1"));
+
+ searchResponse = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(hasParentQuery("parent", matchAllQuery()))
+ .get();
+ assertHitCount(searchResponse, 2L);
+ assertThat(searchResponse.getHits().getAt(0).id(), equalTo("c1"));
+ assertThat(searchResponse.getHits().getAt(1).id(), equalTo("c2"));
}
public void testPercolateApi() {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping(".percolator", "field1", "type=string", "field2", "type=string")
+ .addMapping(".percolator", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
client().prepareIndex("test", ".percolator", "1")
.setSource("{\"query\" : { \"match_all\" : {} }, \"field1\" : \"value1\"}")
@@ -446,6 +614,23 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
assertThat(response.getCount(), equalTo(1L));
assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
+ response = client()
+ .filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
+ .preparePercolate()
+ .setDocumentType("type")
+ .setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
+ .get();
+ assertThat(response.getCount(), equalTo(0L));
+
+ response = client()
+ .filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .preparePercolate()
+ .setDocumentType("type")
+ .setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
+ .get();
+ assertThat(response.getCount(), equalTo(1L));
+ assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
+
// Percolator with a query on a document that the current user can see. Percolator will have one query to evaluate, so there is a
// match:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
@@ -467,6 +652,15 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
.get();
assertThat(response.getCount(), equalTo(0L));
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .preparePercolate()
+ .setDocumentType("type")
+ .setPercolateQuery(termQuery("field1", "value1"))
+ .setPercolateDoc(new PercolateSourceBuilder.DocBuilder().setDoc("{}"))
+ .get();
+ assertThat(response.getCount(), equalTo(1L));
+ assertThat(response.getMatches()[0].getId().string(), equalTo("1"));
+
assertAcked(client().admin().indices().prepareClose("test"));
assertAcked(client().admin().indices().prepareOpen("test"));
ensureGreen("test");
@@ -484,12 +678,14 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
public void testRequestCache() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.setSettings(Settings.builder().put(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true))
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
client().prepareIndex("test", "type1", "1").setSource("field1", "value1")
.get();
client().prepareIndex("test", "type1", "2").setSource("field2", "value2")
.get();
+ client().prepareIndex("test", "type1", "3").setSource("field3", "value3")
+ .get();
refresh();
int max = scaledRandomIntBetween(4, 32);
@@ -512,6 +708,14 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase {
.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);
}
}
diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/FieldLevelSecurityTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/FieldLevelSecurityTests.java
index 6059b49eeb3..5ab9c61aaf5 100644
--- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/FieldLevelSecurityTests.java
+++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/FieldLevelSecurityTests.java
@@ -45,7 +45,7 @@ import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
-// The random usage of meta fields such as _timestamp add noice to the test, so disable random index templates:
+// The random usage of meta fields such as _timestamp add noise to the test, so disable random index templates:
@ESIntegTestCase.ClusterScope(randomDynamicTemplates = false)
public class FieldLevelSecurityTests extends ShieldIntegTestCase {
@@ -60,18 +60,20 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
"user3:" + USERS_PASSWD_HASHED + "\n" +
"user4:" + USERS_PASSWD_HASHED + "\n" +
"user5:" + USERS_PASSWD_HASHED + "\n" +
- "user6:" + USERS_PASSWD_HASHED + "\n";
+ "user6:" + USERS_PASSWD_HASHED + "\n" +
+ "user7:" + USERS_PASSWD_HASHED + "\n" +
+ "user8:" + USERS_PASSWD_HASHED + "\n";
}
@Override
protected String configUsersRoles() {
return super.configUsersRoles() +
- "role1:user1\n" +
- "role2:user2\n" +
- "role3:user3\n" +
- "role4:user4\n" +
- "role5:user5\n" +
- "role5:user6\n";
+ "role1:user1,user7,user8\n" +
+ "role2:user2,user7,user8\n" +
+ "role3:user3,user7\n" +
+ "role4:user4,user7\n" +
+ "role5:user5,user7\n" +
+ "role6:user6\n";
}
@Override
protected String configRoles() {
@@ -109,6 +111,7 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
"role6:\n" +
" cluster: all\n" +
" indices:\n" +
+ " '*':\n" +
" privileges: ALL\n" +
" fields: 'field*'\n";
}
@@ -123,9 +126,9 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
public void testQuery() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2", "field3", "value3")
.setRefresh(true)
.get();
@@ -160,6 +163,18 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.setQuery(matchQuery("field1", "value1"))
.get();
assertHitCount(response, 1);
+ // user7 has roles with field level security configured and without field level security
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field1", "value1"))
+ .get();
+ assertHitCount(response, 1);
+ // user8 has roles with field level security configured for field1 and field2
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field1", "value1"))
+ .get();
+ assertHitCount(response, 1);
// user1 has no access to field1, so the query should not match with the document:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
@@ -191,14 +206,70 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.setQuery(matchQuery("field2", "value2"))
.get();
assertHitCount(response, 1);
+ // user7 has role with field level security and without field level security
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field2", "value2"))
+ .get();
+ assertHitCount(response, 1);
+ // user8 has roles with field level security configured for field1 and field2
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field2", "value2"))
+ .get();
+ assertHitCount(response, 1);
+
+ // user1 has access to field3, so the query should not match with the document:
+ response = client()
+ .filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field3", "value3"))
+ .get();
+ assertHitCount(response, 0);
+ // user2 has no access to field3, so the query should not match with the document:
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field3", "value3"))
+ .get();
+ assertHitCount(response, 0);
+ // user3 has access to field1 and field2 but not field3, so the query should not match with the document:
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field3", "value3"))
+ .get();
+ assertHitCount(response, 0);
+ // user4 has access to no fields, so the query should not match with the document:
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user4", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field3", "value3"))
+ .get();
+ assertHitCount(response, 0);
+ // user5 has no field level security configured, so the query should match with the document:
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field3", "value3"))
+ .get();
+ assertHitCount(response, 1);
+ // user7 has roles with field level security and without field level security
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field3", "value3"))
+ .get();
+ assertHitCount(response, 1);
+ // user8 has roles with field level security configured for field1 and field2
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD)))
+ .prepareSearch("test")
+ .setQuery(matchQuery("field3", "value3"))
+ .get();
+ assertHitCount(response, 0);
}
public void testGetApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2", "field3", "value3")
.get();
Boolean realtime = randomFrom(true, false, null);
@@ -250,6 +321,42 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.setRefresh(true)
.get();
assertThat(response.isExists(), is(true));
+ assertThat(response.getSource().size(), equalTo(3));
+ assertThat(response.getSource().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getSource().get("field2").toString(), equalTo("value2"));
+ assertThat(response.getSource().get("field3").toString(), equalTo("value3"));
+
+ // user6 has access to field*
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD)))
+ .prepareGet("test", "type1", "1")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getSource().size(), equalTo(3));
+ assertThat(response.getSource().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getSource().get("field2").toString(), equalTo("value2"));
+ assertThat(response.getSource().get("field3").toString(), equalTo("value3"));
+
+ // user7 has roles with field level security and without field level security
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD)))
+ .prepareGet("test", "type1", "1")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getSource().size(), equalTo(3));
+ assertThat(response.getSource().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getSource().get("field2").toString(), equalTo("value2"));
+ assertThat(response.getSource().get("field3").toString(), equalTo("value3"));
+
+ // user8 has roles with field level security with access to field1 and field2
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD)))
+ .prepareGet("test", "type1", "1")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.isExists(), is(true));
assertThat(response.getSource().size(), equalTo(2));
assertThat(response.getSource().get("field1").toString(), equalTo("value1"));
assertThat(response.getSource().get("field2").toString(), equalTo("value2"));
@@ -257,10 +364,9 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
public void testMGetApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
- .get();
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2", "field3", "value3").get();
Boolean realtime = randomFrom(true, false, null);
// user1 is granted access to field1 only:
@@ -321,6 +427,48 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.get();
assertThat(response.getResponses()[0].isFailed(), is(false));
assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[0].getResponse().getSource().size(), equalTo(3));
+ assertThat(response.getResponses()[0].getResponse().getSource().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getResponses()[0].getResponse().getSource().get("field2").toString(), equalTo("value2"));
+ assertThat(response.getResponses()[0].getResponse().getSource().get("field3").toString(), equalTo("value3"));
+
+ // user6 has access to field*
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD)))
+ .prepareMultiGet()
+ .add("test", "type1", "1")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.getResponses()[0].isFailed(), is(false));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[0].getResponse().getSource().size(), equalTo(3));
+ assertThat(response.getResponses()[0].getResponse().getSource().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getResponses()[0].getResponse().getSource().get("field2").toString(), equalTo("value2"));
+ assertThat(response.getResponses()[0].getResponse().getSource().get("field3").toString(), equalTo("value3"));
+
+ // user7 has roles with field level security and without field level security
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD)))
+ .prepareMultiGet()
+ .add("test", "type1", "1")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.getResponses()[0].isFailed(), is(false));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[0].getResponse().getSource().size(), equalTo(3));
+ assertThat(response.getResponses()[0].getResponse().getSource().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getResponses()[0].getResponse().getSource().get("field2").toString(), equalTo("value2"));
+ assertThat(response.getResponses()[0].getResponse().getSource().get("field3").toString(), equalTo("value3"));
+
+ // user8 has roles with field level security with access to field1 and field2
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD)))
+ .prepareMultiGet()
+ .add("test", "type1", "1")
+ .setRealtime(realtime)
+ .setRefresh(true)
+ .get();
+ assertThat(response.getResponses()[0].isFailed(), is(false));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
assertThat(response.getResponses()[0].getResponse().getSource().size(), equalTo(2));
assertThat(response.getResponses()[0].getResponse().getSource().get("field1").toString(), equalTo("value1"));
assertThat(response.getResponses()[0].getResponse().getSource().get("field2").toString(), equalTo("value2"));
@@ -328,9 +476,9 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
public void testFieldStatsApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2", "field3", "value3")
.setRefresh(true)
.get();
@@ -338,7 +486,7 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
FieldStatsResponse response = client()
.filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user1", USERS_PASSWD)))
.prepareFieldStats()
- .setFields("field1", "field2")
+ .setFields("field1", "field2", "field3")
.get();
assertThat(response.getAllFieldStats().size(), equalTo(1));
assertThat(response.getAllFieldStats().get("field1").getDocCount(), equalTo(1L));
@@ -346,7 +494,7 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
// user2 is granted access to field2 only:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user2", USERS_PASSWD)))
.prepareFieldStats()
- .setFields("field1", "field2")
+ .setFields("field1", "field2", "field3")
.get();
assertThat(response.getAllFieldStats().size(), equalTo(1));
assertThat(response.getAllFieldStats().get("field2").getDocCount(), equalTo(1L));
@@ -354,7 +502,7 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
// user3 is granted access to field1 and field2:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user3", USERS_PASSWD)))
.prepareFieldStats()
- .setFields("field1", "field2")
+ .setFields("field1", "field2", "field3")
.get();
assertThat(response.getAllFieldStats().size(), equalTo(2));
assertThat(response.getAllFieldStats().get("field1").getDocCount(), equalTo(1L));
@@ -370,7 +518,37 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
// user5 has no field level security configured:
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD)))
.prepareFieldStats()
- .setFields("field1", "field2")
+ .setFields("field1", "field2", "field3")
+ .get();
+ assertThat(response.getAllFieldStats().size(), equalTo(3));
+ assertThat(response.getAllFieldStats().get("field1").getDocCount(), equalTo(1L));
+ assertThat(response.getAllFieldStats().get("field2").getDocCount(), equalTo(1L));
+ assertThat(response.getAllFieldStats().get("field3").getDocCount(), equalTo(1L));
+
+ // user6 has field level security configured for field*:
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD)))
+ .prepareFieldStats()
+ .setFields("field1", "field2", "field3")
+ .get();
+ assertThat(response.getAllFieldStats().size(), equalTo(3));
+ assertThat(response.getAllFieldStats().get("field1").getDocCount(), equalTo(1L));
+ assertThat(response.getAllFieldStats().get("field2").getDocCount(), equalTo(1L));
+ assertThat(response.getAllFieldStats().get("field3").getDocCount(), equalTo(1L));
+
+ // user7 has no field level security configured (roles with and without field level security):
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD)))
+ .prepareFieldStats()
+ .setFields("field1", "field2", "field3")
+ .get();
+ assertThat(response.getAllFieldStats().size(), equalTo(3));
+ assertThat(response.getAllFieldStats().get("field1").getDocCount(), equalTo(1L));
+ assertThat(response.getAllFieldStats().get("field2").getDocCount(), equalTo(1L));
+ assertThat(response.getAllFieldStats().get("field3").getDocCount(), equalTo(1L));
+
+ // user8 has field level security configured for field1 and field2 (multiple roles):
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD)))
+ .prepareFieldStats()
+ .setFields("field1", "field2", "field3")
.get();
assertThat(response.getAllFieldStats().size(), equalTo(2));
assertThat(response.getAllFieldStats().get("field1").getDocCount(), equalTo(1L));
@@ -380,9 +558,9 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
public void testQueryCache() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.setSettings(Settings.builder().put(IndexModule.INDEX_QUERY_CACHE_EVERYTHING_SETTING.getKey(), true))
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2", "field3", "value3")
.setRefresh(true)
.get();
@@ -394,18 +572,31 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.setQuery(constantScoreQuery(termQuery("field1", "value1")))
.get();
assertHitCount(response, 1);
+ assertThat(response.getHits().getAt(0).getSource().size(), is(1));
+ assertThat(response.getHits().getAt(0).getSource().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);
+ 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).getSource().size(), is(3));
+ assertThat(response.getHits().getAt(0).getSource().get("field1"), is("value1"));
+ assertThat(response.getHits().getAt(0).getSource().get("field2"), is("value2"));
+ assertThat(response.getHits().getAt(0).getSource().get("field3"), is("value3"));
}
}
public void testRequestCache() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.setSettings(Settings.builder().put(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true))
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
.setRefresh(true)
@@ -431,14 +622,25 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.get();
assertNoFailures(response);
assertHitCount(response, 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);
}
}
public void testFields() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string,store=true", "field2", "type=string,store=true")
+ .addMapping("type1", "field1", "type=string,store=true", "field2", "type=string,store=true",
+ "field3", "type=string,store=true")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2", "field3", "value3")
.setRefresh(true)
.get();
@@ -448,6 +650,7 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.prepareSearch("test")
.addField("field1")
.addField("field2")
+ .addField("field3")
.get();
assertThat(response.getHits().getAt(0).fields().size(), equalTo(1));
assertThat(response.getHits().getAt(0).fields().get("field1").getValue(), equalTo("value1"));
@@ -457,6 +660,7 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.prepareSearch("test")
.addField("field1")
.addField("field2")
+ .addField("field3")
.get();
assertThat(response.getHits().getAt(0).fields().size(), equalTo(1));
assertThat(response.getHits().getAt(0).fields().get("field2").getValue(), equalTo("value2"));
@@ -466,6 +670,7 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.prepareSearch("test")
.addField("field1")
.addField("field2")
+ .addField("field3")
.get();
assertThat(response.getHits().getAt(0).fields().size(), equalTo(2));
assertThat(response.getHits().getAt(0).fields().get("field1").getValue(), equalTo("value1"));
@@ -476,6 +681,7 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.prepareSearch("test")
.addField("field1")
.addField("field2")
+ .addField("field3")
.get();
assertThat(response.getHits().getAt(0).fields().size(), equalTo(0));
@@ -484,6 +690,43 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.prepareSearch("test")
.addField("field1")
.addField("field2")
+ .addField("field3")
+ .get();
+ assertThat(response.getHits().getAt(0).fields().size(), equalTo(3));
+ assertThat(response.getHits().getAt(0).fields().get("field1").getValue(), equalTo("value1"));
+ assertThat(response.getHits().getAt(0).fields().get("field2").getValue(), equalTo("value2"));
+ assertThat(response.getHits().getAt(0).fields().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")
+ .addField("field1")
+ .addField("field2")
+ .addField("field3")
+ .get();
+ assertThat(response.getHits().getAt(0).fields().size(), equalTo(3));
+ assertThat(response.getHits().getAt(0).fields().get("field1").getValue(), equalTo("value1"));
+ assertThat(response.getHits().getAt(0).fields().get("field2").getValue(), equalTo("value2"));
+ assertThat(response.getHits().getAt(0).fields().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")
+ .addField("field1")
+ .addField("field2")
+ .addField("field3")
+ .get();
+ assertThat(response.getHits().getAt(0).fields().size(), equalTo(3));
+ assertThat(response.getHits().getAt(0).fields().get("field1").getValue(), equalTo("value1"));
+ assertThat(response.getHits().getAt(0).fields().get("field2").getValue(), equalTo("value2"));
+ assertThat(response.getHits().getAt(0).fields().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")
+ .addField("field1")
+ .addField("field2")
+ .addField("field3")
.get();
assertThat(response.getHits().getAt(0).fields().size(), equalTo(2));
assertThat(response.getHits().getAt(0).fields().get("field1").getValue(), equalTo("value1"));
@@ -492,9 +735,9 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
public void testSource() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
- .addMapping("type1", "field1", "type=string", "field2", "type=string")
+ .addMapping("type1", "field1", "type=string", "field2", "type=string", "field3", "type=string")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2", "field3", "value3")
.setRefresh(true)
.get();
@@ -531,6 +774,33 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD)))
.prepareSearch("test")
.get();
+ assertThat(response.getHits().getAt(0).sourceAsMap().size(), equalTo(3));
+ assertThat(response.getHits().getAt(0).sourceAsMap().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getHits().getAt(0).sourceAsMap().get("field2").toString(), equalTo("value2"));
+ assertThat(response.getHits().getAt(0).sourceAsMap().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).sourceAsMap().size(), equalTo(3));
+ assertThat(response.getHits().getAt(0).sourceAsMap().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getHits().getAt(0).sourceAsMap().get("field2").toString(), equalTo("value2"));
+ assertThat(response.getHits().getAt(0).sourceAsMap().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).sourceAsMap().size(), equalTo(3));
+ assertThat(response.getHits().getAt(0).sourceAsMap().get("field1").toString(), equalTo("value1"));
+ assertThat(response.getHits().getAt(0).sourceAsMap().get("field2").toString(), equalTo("value2"));
+ assertThat(response.getHits().getAt(0).sourceAsMap().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).sourceAsMap().size(), equalTo(2));
assertThat(response.getHits().getAt(0).sourceAsMap().get("field1").toString(), equalTo("value1"));
assertThat(response.getHits().getAt(0).sourceAsMap().get("field2").toString(), equalTo("value2"));
@@ -616,9 +886,10 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
public void testTVApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.addMapping("type1", "field1", "type=string,term_vector=with_positions_offsets_payloads",
- "field2", "type=string,term_vector=with_positions_offsets_payloads")
+ "field2", "type=string,term_vector=with_positions_offsets_payloads",
+ "field3", "type=string,term_vector=with_positions_offsets_payloads")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2", "field3", "value3")
.setRefresh(true)
.get();
@@ -655,14 +926,54 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
.get();
assertThat(response.isExists(), is(true));
assertThat(response.getFields().size(), equalTo(0));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD)))
+ .prepareTermVectors("test", "type1", "1")
+ .setRealtime(realtime)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getFields().size(), equalTo(3));
+ assertThat(response.getFields().terms("field1").size(), equalTo(1L));
+ assertThat(response.getFields().terms("field2").size(), equalTo(1L));
+ assertThat(response.getFields().terms("field3").size(), equalTo(1L));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD)))
+ .prepareTermVectors("test", "type1", "1")
+ .setRealtime(realtime)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getFields().size(), equalTo(3));
+ assertThat(response.getFields().terms("field1").size(), equalTo(1L));
+ assertThat(response.getFields().terms("field2").size(), equalTo(1L));
+ assertThat(response.getFields().terms("field3").size(), equalTo(1L));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD)))
+ .prepareTermVectors("test", "type1", "1")
+ .setRealtime(realtime)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getFields().size(), equalTo(3));
+ assertThat(response.getFields().terms("field1").size(), equalTo(1L));
+ assertThat(response.getFields().terms("field2").size(), equalTo(1L));
+ assertThat(response.getFields().terms("field3").size(), equalTo(1L));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD)))
+ .prepareTermVectors("test", "type1", "1")
+ .setRealtime(realtime)
+ .get();
+ assertThat(response.isExists(), is(true));
+ assertThat(response.getFields().size(), equalTo(2));
+ assertThat(response.getFields().terms("field1").size(), equalTo(1L));
+ assertThat(response.getFields().terms("field2").size(), equalTo(1L));
}
public void testMTVApi() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test")
.addMapping("type1", "field1", "type=string,term_vector=with_positions_offsets_payloads",
- "field2", "type=string,term_vector=with_positions_offsets_payloads")
+ "field2", "type=string,term_vector=with_positions_offsets_payloads",
+ "field3", "type=string,term_vector=with_positions_offsets_payloads")
);
- client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2")
+ client().prepareIndex("test", "type1", "1").setSource("field1", "value1", "field2", "value2", "field3", "value3")
.setRefresh(true)
.get();
@@ -703,6 +1014,49 @@ public class FieldLevelSecurityTests extends ShieldIntegTestCase {
assertThat(response.getResponses().length, equalTo(1));
assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
assertThat(response.getResponses()[0].getResponse().getFields().size(), equalTo(0));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user5", USERS_PASSWD)))
+ .prepareMultiTermVectors()
+ .add(new TermVectorsRequest("test", "type1", "1").realtime(realtime))
+ .get();
+ assertThat(response.getResponses().length, equalTo(1));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[0].getResponse().getFields().size(), equalTo(3));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field1").size(), equalTo(1L));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field2").size(), equalTo(1L));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field3").size(), equalTo(1L));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user6", USERS_PASSWD)))
+ .prepareMultiTermVectors()
+ .add(new TermVectorsRequest("test", "type1", "1").realtime(realtime))
+ .get();
+ assertThat(response.getResponses().length, equalTo(1));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[0].getResponse().getFields().size(), equalTo(3));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field1").size(), equalTo(1L));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field2").size(), equalTo(1L));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field3").size(), equalTo(1L));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user7", USERS_PASSWD)))
+ .prepareMultiTermVectors()
+ .add(new TermVectorsRequest("test", "type1", "1").realtime(realtime))
+ .get();
+ assertThat(response.getResponses().length, equalTo(1));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[0].getResponse().getFields().size(), equalTo(3));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field1").size(), equalTo(1L));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field2").size(), equalTo(1L));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field3").size(), equalTo(1L));
+
+ response = client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("user8", USERS_PASSWD)))
+ .prepareMultiTermVectors()
+ .add(new TermVectorsRequest("test", "type1", "1").realtime(realtime))
+ .get();
+ assertThat(response.getResponses().length, equalTo(1));
+ assertThat(response.getResponses()[0].getResponse().isExists(), is(true));
+ assertThat(response.getResponses()[0].getResponse().getFields().size(), equalTo(2));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field1").size(), equalTo(1L));
+ assertThat(response.getResponses()[0].getResponse().getFields().terms("field2").size(), equalTo(1L));
}
public void testPercolateApi() {
diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/IndicesAccessControlTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/IndicesAccessControlTests.java
new file mode 100644
index 00000000000..35410ac80c5
--- /dev/null
+++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/accesscontrol/IndicesAccessControlTests.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+package org.elasticsearch.shield.authz.accesscontrol;
+
+import org.elasticsearch.common.bytes.BytesArray;
+import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.util.set.Sets;
+import org.elasticsearch.test.ESTestCase;
+
+import java.util.Collections;
+import org.elasticsearch.shield.authz.accesscontrol.IndicesAccessControl.IndexAccessControl;
+
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+
+/**
+ * Unit tests for {@link IndicesAccessControl}
+ */
+public class IndicesAccessControlTests extends ESTestCase {
+
+ public void testEmptyIndicesAccessControl() {
+ IndicesAccessControl indicesAccessControl = new IndicesAccessControl(true, Collections.emptyMap());
+ assertThat(indicesAccessControl.isGranted(), is(true));
+ assertThat(indicesAccessControl.getIndexPermissions(randomAsciiOfLengthBetween(3,20)), nullValue());
+ }
+
+ public void testMergeFields() {
+ IndexAccessControl indexAccessControl = new IndexAccessControl(true, Sets.newHashSet("a", "c"), null);
+ IndexAccessControl other = new IndexAccessControl(true, Sets.newHashSet("b"), null);
+
+ IndexAccessControl merge1 = indexAccessControl.merge(other);
+ assertThat(merge1.getFields(), containsInAnyOrder("a", "b", "c"));
+ assertThat(merge1.isGranted(), is(true));
+ assertThat(merge1.getQueries(), nullValue());
+
+ IndexAccessControl merge2 = other.merge(indexAccessControl);
+ assertThat(merge2.getFields(), containsInAnyOrder("a", "b", "c"));
+ assertThat(merge2.isGranted(), is(true));
+ assertThat(merge2.getQueries(), nullValue());
+ }
+
+ public void testMergeEmptyAndNullFields() {
+ IndexAccessControl indexAccessControl = new IndexAccessControl(true, Collections.emptySet(), null);
+ IndexAccessControl other = new IndexAccessControl(true, null, null);
+
+ IndexAccessControl merge1 = indexAccessControl.merge(other);
+ assertThat(merge1.getFields(), nullValue());
+ assertThat(merge1.isGranted(), is(true));
+ assertThat(merge1.getQueries(), nullValue());
+
+ IndexAccessControl merge2 = other.merge(indexAccessControl);
+ assertThat(merge2.getFields(), nullValue());
+ assertThat(merge2.isGranted(), is(true));
+ assertThat(merge2.getQueries(), nullValue());
+ }
+
+ public void testMergeNullFields() {
+ IndexAccessControl indexAccessControl = new IndexAccessControl(true, Sets.newHashSet("a", "b"), null);
+ IndexAccessControl other = new IndexAccessControl(true, null, null);
+
+ IndexAccessControl merge1 = indexAccessControl.merge(other);
+ assertThat(merge1.getFields(), nullValue());
+ assertThat(merge1.isGranted(), is(true));
+ assertThat(merge1.getQueries(), nullValue());
+
+ IndexAccessControl merge2 = other.merge(indexAccessControl);
+ assertThat(merge2.getFields(), nullValue());
+ assertThat(merge2.isGranted(), is(true));
+ assertThat(merge2.getQueries(), nullValue());
+ }
+
+ public void testMergeQueries() {
+ BytesReference query1 = new BytesArray(new byte[] { 0x1 });
+ BytesReference query2 = new BytesArray(new byte[] { 0x2 });
+ IndexAccessControl indexAccessControl = new IndexAccessControl(true, null, Collections.singleton(query1));
+ IndexAccessControl other = new IndexAccessControl(true, null, Collections.singleton(query2));
+
+ IndexAccessControl merge1 = indexAccessControl.merge(other);
+ assertThat(merge1.getFields(), nullValue());
+ assertThat(merge1.isGranted(), is(true));
+ assertThat(merge1.getQueries(), containsInAnyOrder(query1, query2));
+
+ IndexAccessControl merge2 = other.merge(indexAccessControl);
+ assertThat(merge2.getFields(), nullValue());
+ assertThat(merge2.isGranted(), is(true));
+ assertThat(merge1.getQueries(), containsInAnyOrder(query1, query2));
+ }
+
+ public void testMergeNullQuery() {
+ BytesReference query1 = new BytesArray(new byte[] { 0x1 });
+ IndexAccessControl indexAccessControl = new IndexAccessControl(true, null, Collections.singleton(query1));
+ IndexAccessControl other = new IndexAccessControl(true, null, null);
+
+ IndexAccessControl merge1 = indexAccessControl.merge(other);
+ assertThat(merge1.getFields(), nullValue());
+ assertThat(merge1.isGranted(), is(true));
+ assertThat(merge1.getQueries(), nullValue());
+
+ IndexAccessControl merge2 = other.merge(indexAccessControl);
+ assertThat(merge2.getFields(), nullValue());
+ assertThat(merge2.isGranted(), is(true));
+ assertThat(merge1.getQueries(), nullValue());
+ }
+}