Changed search and get privileges
- separated `get` privilege from `search`. This should make it simpler for users to only allow search (and not get) when working with filtered aliases - added multi search under the `search` privilege - added the multi get under the `get` privilege Original commit: elastic/x-pack-elasticsearch@6fafb08a2c
This commit is contained in:
parent
a25d603b93
commit
dd4a66bd6c
|
@ -12,6 +12,8 @@ import org.elasticsearch.ElasticsearchException;
|
|||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.action.admin.indices.create.CreateIndexAction;
|
||||
import org.elasticsearch.action.get.GetAction;
|
||||
import org.elasticsearch.action.get.MultiGetAction;
|
||||
import org.elasticsearch.action.search.MultiSearchAction;
|
||||
import org.elasticsearch.action.search.SearchAction;
|
||||
import org.elasticsearch.action.suggest.SuggestAction;
|
||||
import org.elasticsearch.common.Strings;
|
||||
|
@ -115,8 +117,8 @@ public abstract class Privilege<P extends Privilege<P>> {
|
|||
public static final Index DATA_ACCESS = new Index("data_access", "indices:data/*");
|
||||
public static final Index CRUD = new Index("crud", "indices:data/write/*", "indices:data/read/*");
|
||||
public static final Index READ = new Index("read", "indices:data/read/*");
|
||||
public static final Index SEARCH = new Index("search", SearchAction.NAME + "*", GetAction.NAME + "*", SuggestAction.NAME + "*");
|
||||
public static final Index GET = new Index("get", GetAction.NAME + "*");
|
||||
public static final Index SEARCH = new Index("search", SearchAction.NAME + "*", MultiSearchAction.NAME + "*", SuggestAction.NAME + "*");
|
||||
public static final Index GET = new Index("get", GetAction.NAME + "*", MultiGetAction.NAME + "*");
|
||||
public static final Index SUGGEST = new Index("suggest", SuggestAction.NAME + "*");
|
||||
public static final Index INDEX = new Index("index", "indices:data/write/index*", "indices:data/write/update");
|
||||
public static final Index DELETE = new Index("delete", "indices:data/write/delete*");
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
*/
|
||||
package org.elasticsearch.integration;
|
||||
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.action.get.MultiGetResponse;
|
||||
import org.elasticsearch.action.index.IndexResponse;
|
||||
import org.elasticsearch.action.search.MultiSearchResponse;
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.action.suggest.SuggestResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.search.suggest.SuggestBuilders;
|
||||
|
@ -16,6 +18,7 @@ import org.elasticsearch.shield.authz.AuthorizationException;
|
|||
import org.elasticsearch.test.ShieldIntegrationTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.elasticsearch.client.Requests.searchRequest;
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
||||
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
|
||||
|
@ -24,15 +27,11 @@ import static org.hamcrest.Matchers.equalTo;
|
|||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
@ClusterScope(scope = Scope.SUITE)
|
||||
public class SearchPermissionsTests extends ShieldIntegrationTest {
|
||||
public class SearchGetAndSuggestPermissionsTests extends ShieldIntegrationTest {
|
||||
|
||||
@Override
|
||||
protected String configRoles() {
|
||||
return super.configRoles() + "\n" +
|
||||
"\n" +
|
||||
"suggest_role:\n" +
|
||||
" indices:\n" +
|
||||
" 'a': suggest\n" +
|
||||
"\n" +
|
||||
"search_role:\n" +
|
||||
" indices:\n" +
|
||||
|
@ -40,23 +39,28 @@ public class SearchPermissionsTests extends ShieldIntegrationTest {
|
|||
"\n" +
|
||||
"get_role:\n" +
|
||||
" indices:\n" +
|
||||
" 'a': get\n";
|
||||
" 'a': get\n" +
|
||||
"\n" +
|
||||
"suggest_role:\n" +
|
||||
" indices:\n" +
|
||||
" 'a': suggest\n";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String configUsers() {
|
||||
return super.configUsers() +
|
||||
"suggest_user:{plain}passwd\n" +
|
||||
"search_user:{plain}passwd\n" +
|
||||
"get_user:{plain}passwd\n";
|
||||
"get_user:{plain}passwd\n" +
|
||||
"suggest_user:{plain}passwd\n";
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String configUsersRoles() {
|
||||
return super.configUsersRoles() +
|
||||
"suggest_role:suggest_user\n" +
|
||||
"search_role:search_user\n" +
|
||||
"get_role:get_user";
|
||||
"get_role:get_user\n" +
|
||||
"suggest_role:suggest_user\n";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +102,7 @@ public class SearchPermissionsTests extends ShieldIntegrationTest {
|
|||
}
|
||||
|
||||
/**
|
||||
* testing both "search" and "get" privileges can execute the get API
|
||||
* testing that "search" privilege cannot execute the get API
|
||||
*/
|
||||
@Test
|
||||
public void testGetAPI() throws Exception {
|
||||
|
@ -112,29 +116,75 @@ public class SearchPermissionsTests extends ShieldIntegrationTest {
|
|||
|
||||
Client client = internalCluster().transportClient();
|
||||
|
||||
GetResponse getResponse = client.prepareGet("a", "type", indexResponse.getId())
|
||||
try {
|
||||
client.prepareGet("a", "type", indexResponse.getId())
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("search_user", "passwd"))
|
||||
.get();
|
||||
fail("a user with only search privilege should not be authorized for a get request");
|
||||
} catch (AuthorizationException ae) {
|
||||
// expected
|
||||
logger.error("could not get document", ae);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* testing that "get" privilege can execute the mget API, and "search" privilege cannot execute mget
|
||||
*/
|
||||
@Test
|
||||
public void testMultiGetAPI() throws Exception {
|
||||
IndexResponse indexResponse = index("a", "type", jsonBuilder()
|
||||
.startObject()
|
||||
.field("name", "value")
|
||||
.endObject());
|
||||
assertThat(indexResponse.isCreated(), is(true));
|
||||
|
||||
refresh();
|
||||
|
||||
Client client = internalCluster().transportClient();
|
||||
|
||||
MultiGetResponse response = client.prepareMultiGet().add("a", "type", indexResponse.getId())
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("get_user", "passwd"))
|
||||
.get();
|
||||
assertNotNull(getResponse);
|
||||
assertThat(getResponse.getId(), equalTo(indexResponse.getId()));
|
||||
|
||||
getResponse = client.prepareGet("a", "type", indexResponse.getId())
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("search_user", "passwd"))
|
||||
.get();
|
||||
assertNotNull(getResponse);
|
||||
assertThat(getResponse.getId(), equalTo(indexResponse.getId()));
|
||||
assertNotNull(response);
|
||||
assertThat(response.getResponses().length, is(1));
|
||||
assertThat(response.getResponses()[0].getId(), equalTo(indexResponse.getId()));
|
||||
|
||||
try {
|
||||
client.prepareSearch("a")
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("get_user", "passwd"))
|
||||
client.prepareMultiGet().add("a", "type", indexResponse.getId())
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("search_user", "passwd"))
|
||||
.get();
|
||||
fail("a user with only a get privilege cannot execute search");
|
||||
} catch (AuthorizationException e) {
|
||||
logger.error("failed to search", e);
|
||||
fail("a user with only a search privilege should not be able to execute the mget API");
|
||||
} catch (AuthorizationException ae) {
|
||||
// expected
|
||||
logger.error("could not mget documents", ae);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* testing that "search" privilege can execute the msearch API
|
||||
*/
|
||||
@Test
|
||||
public void testMultiSearchAPI() throws Exception {
|
||||
IndexResponse indexResponse = index("a", "type", jsonBuilder()
|
||||
.startObject()
|
||||
.field("name", "value")
|
||||
.endObject());
|
||||
assertThat(indexResponse.isCreated(), is(true));
|
||||
|
||||
refresh();
|
||||
|
||||
Client client = internalCluster().transportClient();
|
||||
|
||||
MultiSearchResponse response = client.prepareMultiSearch().add(searchRequest("a").types("type"))
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("search_user", "passwd"))
|
||||
.get();
|
||||
assertNotNull(response);
|
||||
assertThat(response.getResponses().length, is(1));
|
||||
SearchResponse first = response.getResponses()[0].getResponse();
|
||||
assertNotNull(first);
|
||||
assertNoFailures(first);
|
||||
}
|
||||
|
||||
private static String userHeader(String username, String password) {
|
||||
return UsernamePasswordToken.basicAuthHeaderValue(username, SecuredStringTests.build(password));
|
||||
}
|
|
@ -42,11 +42,12 @@ public class PermissionTests extends ElasticsearchTestCase {
|
|||
assertThat(matcher1, is(matcher2));
|
||||
}
|
||||
|
||||
// "baz_*foo", "/fool.*bar/"
|
||||
private void testAllowedIndicesMatcher(Predicate<String> indicesMatcher) {
|
||||
assertThat(indicesMatcher.apply("test_123"), is(true));
|
||||
assertThat(indicesMatcher.apply("foobar"), is(true));
|
||||
assertThat(indicesMatcher.apply("fool"), is(true));
|
||||
assertThat(indicesMatcher.apply("foobar"), is(false));
|
||||
assertThat(indicesMatcher.apply("fool"), is(false));
|
||||
assertThat(indicesMatcher.apply("fool2bar"), is(true));
|
||||
assertThat(indicesMatcher.apply("baz_foo"), is(true));
|
||||
assertThat(indicesMatcher.apply("barbapapa"), is(false));
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@ package org.elasticsearch.shield.authz;
|
|||
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.action.get.GetAction;
|
||||
import org.elasticsearch.action.get.MultiGetAction;
|
||||
import org.elasticsearch.action.search.MultiSearchAction;
|
||||
import org.elasticsearch.action.search.SearchAction;
|
||||
import org.elasticsearch.action.suggest.SuggestAction;
|
||||
import org.elasticsearch.common.base.Predicate;
|
||||
|
@ -185,9 +187,23 @@ public class PrivilegeTests extends ElasticsearchTestCase {
|
|||
Predicate<String> predicate = Privilege.Index.SEARCH.predicate();
|
||||
assertThat(predicate.apply(SearchAction.NAME), is(true));
|
||||
assertThat(predicate.apply(SearchAction.NAME + "/whatever"), is(true));
|
||||
assertThat(predicate.apply(GetAction.NAME), is(true));
|
||||
assertThat(predicate.apply(GetAction.NAME + "/whatever"), is(true));
|
||||
assertThat(predicate.apply(MultiSearchAction.NAME), is(true));
|
||||
assertThat(predicate.apply(MultiSearchAction.NAME + "/whatever"), is(true));
|
||||
assertThat(predicate.apply(SuggestAction.NAME), is(true));
|
||||
assertThat(predicate.apply(SuggestAction.NAME + "/whatever"), is(true));
|
||||
|
||||
assertThat(predicate.apply(GetAction.NAME), is(false));
|
||||
assertThat(predicate.apply(GetAction.NAME + "/whatever"), is(false));
|
||||
assertThat(predicate.apply(MultiGetAction.NAME), is(false));
|
||||
assertThat(predicate.apply(MultiGetAction.NAME + "/whatever"), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPrivilege() throws Exception {
|
||||
Predicate<String> predicate = Privilege.Index.GET.predicate();
|
||||
assertThat(predicate.apply(GetAction.NAME), is(true));
|
||||
assertThat(predicate.apply(GetAction.NAME + "/whatever"), is(true));
|
||||
assertThat(predicate.apply(MultiGetAction.NAME), is(true));
|
||||
assertThat(predicate.apply(MultiGetAction.NAME + "/whatever"), is(true));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue