mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-09 14:35:04 +00:00
Adds SUGGEST index privilege
The `suggest` action was also added to the `SEARCH` privilege as one can execute suggestions under the `_search` API as well. Closes elastic/elasticsearch#24 Original commit: elastic/x-pack-elasticsearch@672809e199
This commit is contained in:
parent
97f229f667
commit
a25d603b93
@ -13,6 +13,7 @@ import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.action.admin.indices.create.CreateIndexAction;
|
||||
import org.elasticsearch.action.get.GetAction;
|
||||
import org.elasticsearch.action.search.SearchAction;
|
||||
import org.elasticsearch.action.suggest.SuggestAction;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.base.Predicate;
|
||||
import org.elasticsearch.common.cache.CacheBuilder;
|
||||
@ -114,14 +115,15 @@ 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 + "*");
|
||||
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 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*");
|
||||
public static final Index WRITE = new Index("write", "indices:data/write/*");
|
||||
|
||||
private static final Index[] values = new Index[] {
|
||||
NONE, ALL, MANAGE, CREATE_INDEX, MANAGE_ALIASES, MONITOR, DATA_ACCESS, CRUD, READ, SEARCH, GET, INDEX, DELETE, WRITE
|
||||
NONE, ALL, MANAGE, CREATE_INDEX, MANAGE_ALIASES, MONITOR, DATA_ACCESS, CRUD, READ, SEARCH, GET, SUGGEST, INDEX, DELETE, WRITE
|
||||
};
|
||||
|
||||
public static final Predicate<String> ACTION_MATCHER = Privilege.Index.ALL.predicate();
|
||||
|
@ -8,7 +8,6 @@ package org.elasticsearch.shield.signature;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.common.base.Charsets;
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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.integration;
|
||||
|
||||
import org.elasticsearch.action.get.GetResponse;
|
||||
import org.elasticsearch.action.index.IndexResponse;
|
||||
import org.elasticsearch.action.suggest.SuggestResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.search.suggest.SuggestBuilders;
|
||||
import org.elasticsearch.shield.authc.support.SecuredStringTests;
|
||||
import org.elasticsearch.shield.authc.support.UsernamePasswordToken;
|
||||
import org.elasticsearch.shield.authz.AuthorizationException;
|
||||
import org.elasticsearch.test.ShieldIntegrationTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||
import static org.elasticsearch.test.ElasticsearchIntegrationTest.ClusterScope;
|
||||
import static org.elasticsearch.test.ElasticsearchIntegrationTest.Scope;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
@ClusterScope(scope = Scope.SUITE)
|
||||
public class SearchPermissionsTests 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" +
|
||||
" 'a': search\n" +
|
||||
"\n" +
|
||||
"get_role:\n" +
|
||||
" indices:\n" +
|
||||
" 'a': get\n";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String configUsers() {
|
||||
return super.configUsers() +
|
||||
"suggest_user:{plain}passwd\n" +
|
||||
"search_user:{plain}passwd\n" +
|
||||
"get_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";
|
||||
}
|
||||
|
||||
/**
|
||||
* testing both "search" and "suggest" privileges can execute the suggest API
|
||||
*/
|
||||
@Test
|
||||
public void testSuggestAPI() throws Exception {
|
||||
IndexResponse indexResponse = index("a", "type", jsonBuilder()
|
||||
.startObject()
|
||||
.field("name", "value")
|
||||
.endObject());
|
||||
assertThat(indexResponse.isCreated(), is(true));
|
||||
|
||||
refresh();
|
||||
|
||||
Client client = internalCluster().transportClient();
|
||||
|
||||
SuggestResponse suggestResponse = client.prepareSuggest("a")
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("suggest_user", "passwd"))
|
||||
.addSuggestion(SuggestBuilders.termSuggestion("name").field("name").text("val")).get();
|
||||
assertNoFailures(suggestResponse);
|
||||
assertThat(suggestResponse.getSuggest().size(), is(1));
|
||||
|
||||
suggestResponse = client.prepareSuggest("a")
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("search_user", "passwd"))
|
||||
.addSuggestion(SuggestBuilders.termSuggestion("name").field("name").text("val")).get();
|
||||
assertNoFailures(suggestResponse);
|
||||
assertThat(suggestResponse.getSuggest().size(), is(1));
|
||||
|
||||
try {
|
||||
client.prepareSearch("a")
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("suggest_user", "passwd"))
|
||||
.get();
|
||||
fail("a user with only a suggest privilege cannot execute search");
|
||||
} catch (AuthorizationException e) {
|
||||
logger.error("failed to search", e);
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* testing both "search" and "get" privileges can execute the get API
|
||||
*/
|
||||
@Test
|
||||
public void testGetAPI() throws Exception {
|
||||
IndexResponse indexResponse = index("a", "type", jsonBuilder()
|
||||
.startObject()
|
||||
.field("name", "value")
|
||||
.endObject());
|
||||
assertThat(indexResponse.isCreated(), is(true));
|
||||
|
||||
refresh();
|
||||
|
||||
Client client = internalCluster().transportClient();
|
||||
|
||||
GetResponse getResponse = client.prepareGet("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()));
|
||||
|
||||
try {
|
||||
client.prepareSearch("a")
|
||||
.putHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("get_user", "passwd"))
|
||||
.get();
|
||||
fail("a user with only a get privilege cannot execute search");
|
||||
} catch (AuthorizationException e) {
|
||||
logger.error("failed to search", e);
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
private static String userHeader(String username, String password) {
|
||||
return UsernamePasswordToken.basicAuthHeaderValue(username, SecuredStringTests.build(password));
|
||||
}
|
||||
}
|
@ -6,6 +6,9 @@
|
||||
package org.elasticsearch.shield.authz;
|
||||
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.action.get.GetAction;
|
||||
import org.elasticsearch.action.search.SearchAction;
|
||||
import org.elasticsearch.action.suggest.SuggestAction;
|
||||
import org.elasticsearch.common.base.Predicate;
|
||||
import org.elasticsearch.shield.support.AutomatonPredicate;
|
||||
import org.elasticsearch.shield.support.Automatons;
|
||||
@ -176,4 +179,15 @@ public class PrivilegeTests extends ElasticsearchTestCase {
|
||||
assertThat(predicate.apply("cluster:whatever"), is(false));
|
||||
assertThat(predicate.apply("whatever"), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchPrivilege() throws Exception {
|
||||
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(SuggestAction.NAME), is(true));
|
||||
assertThat(predicate.apply(SuggestAction.NAME + "/whatever"), is(true));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user