From a22539aca02620ec01faf50ff50d2246ff90d857 Mon Sep 17 00:00:00 2001 From: jaymode Date: Tue, 8 Mar 2016 14:20:54 -0500 Subject: [PATCH] shield: add support for new privilege naming This commit adds support for the privilege naming defined in elastic/elasticsearch#1342 and removes the support for the privileges that were deprecated in 2.3. This change also includes updates to the documentation to account for the new roles format. Original commit: elastic/x-pack-elasticsearch@98e9afd40990e3f6fa9796e627417c82e8d162b3 --- .../messy/tests/ShieldCachePermissionIT.java | 3 +- .../qa/shield-reindex-tests/roles.yml | 14 +- .../x-pack/shield/config/xpack/roles.yml | 92 ++------ .../authz/privilege/ClusterPrivilege.java | 44 +++- .../authz/privilege/IndexPrivilege.java | 80 ++++--- .../shield/support/Automatons.java | 2 + .../DocumentLevelSecurityRandomTests.java | 3 +- .../DocumentLevelSecurityTests.java | 6 +- .../FieldLevelSecurityRandomTests.java | 6 +- .../SearchGetAndSuggestPermissionsTests.java | 199 ------------------ .../shield/authz/IndexAliasesTests.java | 22 +- .../InternalAuthorizationServiceTests.java | 2 +- .../authz/permission/PermissionTests.java | 3 +- .../authz/privilege/PrivilegeTests.java | 28 --- .../authz/store/FileRolesStoreTests.java | 9 +- .../test/ShieldSettingsSource.java | 3 +- .../shield/authz/store/default_roles.yml | 92 ++------ .../shield/authz/store/roles.yml | 3 +- 18 files changed, 167 insertions(+), 444 deletions(-) delete mode 100644 elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/SearchGetAndSuggestPermissionsTests.java diff --git a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/ShieldCachePermissionIT.java b/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/ShieldCachePermissionIT.java index 4e5c2ab6f35..ba3471e61c5 100644 --- a/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/ShieldCachePermissionIT.java +++ b/elasticsearch/qa/messy-test-xpack-with-mustache/src/test/java/org/elasticsearch/messy/tests/ShieldCachePermissionIT.java @@ -53,7 +53,8 @@ public class ShieldCachePermissionIT extends ShieldIntegTestCase { return super.configRoles() + "\nread_one_idx:\n" + " indices:\n" - + " 'data': READ\n"; + + " 'data':\n" + + " - read\n"; } @Override diff --git a/elasticsearch/qa/shield-reindex-tests/roles.yml b/elasticsearch/qa/shield-reindex-tests/roles.yml index 2aaec4b9b6a..059156cd5a6 100644 --- a/elasticsearch/qa/shield-reindex-tests/roles.yml +++ b/elasticsearch/qa/shield-reindex-tests/roles.yml @@ -13,13 +13,13 @@ minimal: indices: - names: source privileges: - - search + - read - write - create_index - indices:admin/refresh - names: dest privileges: - - search + - read - write - create_index - indices:admin/refresh @@ -28,7 +28,7 @@ minimal: readonly: indices: - names: '*' - privileges: [ search ] + privileges: [ read ] # Write operations on destination index, none on source index dest_only: @@ -41,7 +41,7 @@ can_not_see_hidden_docs: indices: - names: source privileges: - - search + - read - write - create_index - indices:admin/refresh @@ -52,7 +52,7 @@ can_not_see_hidden_docs: hidden: true - names: dest privileges: - - search + - read - write - create_index - indices:admin/refresh @@ -62,7 +62,7 @@ can_not_see_hidden_fields: indices: - names: source privileges: - - search + - read - write - create_index - indices:admin/refresh @@ -71,7 +71,7 @@ can_not_see_hidden_fields: - bar - names: dest privileges: - - search + - read - write - create_index - indices:admin/refresh diff --git a/elasticsearch/x-pack/shield/config/xpack/roles.yml b/elasticsearch/x-pack/shield/config/xpack/roles.yml index b43fc06ea7b..1c36fd5ab07 100644 --- a/elasticsearch/x-pack/shield/config/xpack/roles.yml +++ b/elasticsearch/x-pack/shield/config/xpack/roles.yml @@ -26,101 +26,51 @@ user: # Defines the required permissions for transport clients transport_client: cluster: - - cluster:monitor/nodes/liveness - #uncomment the following for sniffing - #- cluster:monitor/state - -# The required permissions for kibana 4 users. -kibana4: - cluster: - - cluster:monitor/nodes/info - - cluster:monitor/health - indices: - - names: '*' - privileges: - - indices:admin/mappings/fields/get - - indices:admin/validate/query - - indices:data/read/search - - indices:data/read/msearch - - indices:data/read/field_stats - - indices:admin/get - - names: '.kibana' - privileges: - - indices:admin/exists - - indices:admin/mapping/put - - indices:admin/mappings/fields/get - - indices:admin/refresh - - indices:admin/validate/query - - indices:data/read/get - - indices:data/read/mget - - indices:data/read/search - - indices:data/write/delete - - indices:data/write/index - - indices:data/write/update + - transport_client # The required permissions for the kibana 4 server kibana4_server: cluster: - - cluster:monitor/nodes/info - - cluster:monitor/health + - monitor indices: - names: '.kibana' privileges: - - indices:admin/create - - indices:admin/exists - - indices:admin/mapping/put - - indices:admin/mappings/fields/get - - indices:admin/refresh - - indices:admin/validate/query - - indices:data/read/get - - indices:data/read/mget - - indices:data/read/search - - indices:data/write/delete - - indices:data/write/index - - indices:data/write/update + - all # The required role for logstash users logstash: cluster: - - indices:admin/template/get - - indices:admin/template/put + - manage_index_templates indices: - names: 'logstash-*' privileges: - - indices:data/write/bulk - - indices:data/write/delete - - indices:data/write/update - - indices:data/read/search - - indices:data/read/scroll + - write + - read - create_index -# Monitoring user role. Assign to monitoring users. +# Marvel user role. Assign to marvel users. monitoring_user: indices: - - names: '.monitoring-*' - privileges: - - read + - names: + - '.marvel-es-*' + - '.monitoring-*' + privileges: [ "read" ] - names: '.kibana' privileges: - - indices:admin/exists - - indices:admin/mappings/fields/get - - indices:admin/validate/query - - indices:data/read/get - - indices:data/read/mget - - indices:data/read/search + - view_index_metadata + - read -# Monitoring remote agent role. Assign to the agent user on the remote monitoring cluster -# to which the monitoring agent will export all its data +# Marvel remote agent role. Assign to the agent user on the remote marvel cluster +# to which the marvel agent will export all its data remote_monitoring_agent: - cluster: - - indices:admin/template/put - - indices:admin/template/get + cluster: [ "manage_index_templates" ] indices: - - names: '.monitoring-*' - privileges: - - all + - names: + - '.marvel-es-*' + - '.monitoring-*' + privileges: [ "all" ] # Allows all operations required to manage ingest pipelines ingest_admin: cluster: - - manage_pipeline \ No newline at end of file + - manage_pipeline diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/privilege/ClusterPrivilege.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/privilege/ClusterPrivilege.java index 82ae689c414..9dc00dae90b 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/privilege/ClusterPrivilege.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/authz/privilege/ClusterPrivilege.java @@ -6,8 +6,10 @@ package org.elasticsearch.shield.authz.privilege; import dk.brics.automaton.Automaton; -import dk.brics.automaton.BasicAutomata; import org.elasticsearch.common.Strings; +import org.elasticsearch.shield.action.realm.ClearRealmCacheAction; +import org.elasticsearch.shield.action.role.ClearRolesCacheAction; +import org.elasticsearch.shield.support.Automatons; import java.util.Locale; import java.util.Set; @@ -15,16 +17,35 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; import java.util.function.Predicate; +import static org.elasticsearch.shield.support.Automatons.minusAndDeterminize; +import static org.elasticsearch.shield.support.Automatons.patterns; + /** * */ public class ClusterPrivilege extends AbstractAutomatonPrivilege { - public static final ClusterPrivilege NONE = new ClusterPrivilege(Name.NONE, BasicAutomata.makeEmpty()); - public static final ClusterPrivilege ALL = new ClusterPrivilege(Name.ALL, "cluster:*", "indices:admin/template/*"); - public static final ClusterPrivilege MONITOR = new ClusterPrivilege("monitor", "cluster:monitor/*"); - public static final ClusterPrivilege MANAGE_SHIELD = new ClusterPrivilege("manage_shield", "cluster:admin/shield/*"); - public static final ClusterPrivilege MANAGE_PIPELINE = new ClusterPrivilege("manage_pipeline", "cluster:admin/ingest/pipeline/*"); + // shared automatons + private static final Automaton MANAGE_USER_AUTOMATON = patterns("cluster:admin/shield/user/*", ClearRolesCacheAction.NAME); + private static final Automaton MANAGE_ROLE_AUTOMATON = patterns("cluster:admin/shield/role/*", ClearRealmCacheAction.NAME); + private static final Automaton MANAGE_SECURITY_AUTOMATON = patterns("cluster:admin/shield/*"); + private static final Automaton MONITOR_AUTOMATON = patterns("cluster:monitor/*"); + private static final Automaton ALL_CLUSTER_AUTOMATON = patterns("cluster:*", "indices:admin/template/*"); + private static final Automaton MANAGE_AUTOMATON = minusAndDeterminize(ALL_CLUSTER_AUTOMATON, MANAGE_SECURITY_AUTOMATON); + private static final Automaton TRANSPORT_CLIENT_AUTOMATON = patterns("cluster:monitor/nodes/liveness", "cluster:monitor/state"); + private static final Automaton MANAGE_IDX_TEMPLATE_AUTOMATON = patterns("indices:admin/template/*"); + + public static final ClusterPrivilege NONE = new ClusterPrivilege(Name.NONE, Automatons.EMPTY); + public static final ClusterPrivilege ALL = new ClusterPrivilege(Name.ALL, ALL_CLUSTER_AUTOMATON); + public static final ClusterPrivilege MONITOR = new ClusterPrivilege("monitor", MONITOR_AUTOMATON); + public static final ClusterPrivilege MANAGE = new ClusterPrivilege("manage", MANAGE_AUTOMATON); + public static final ClusterPrivilege MANAGE_IDX_TEMPLATES = + new ClusterPrivilege("manage_index_templates", MANAGE_IDX_TEMPLATE_AUTOMATON); + public static final ClusterPrivilege TRANSPORT_CLIENT = new ClusterPrivilege("transport_client", TRANSPORT_CLIENT_AUTOMATON); + public static final ClusterPrivilege MANAGE_USERS = new ClusterPrivilege("manage_users", MANAGE_USER_AUTOMATON); + public static final ClusterPrivilege MANAGE_ROLES = new ClusterPrivilege("manage_roles", MANAGE_ROLE_AUTOMATON); + public static final ClusterPrivilege MANAGE_SECURITY = new ClusterPrivilege("manage_security", MANAGE_SECURITY_AUTOMATON); + public static final ClusterPrivilege MANAGE_PIPELINE = new ClusterPrivilege("manage_pipeline", "cluster:admin/ingest/pipeline/*"); public final static Predicate ACTION_MATCHER = ClusterPrivilege.ALL.predicate(); @@ -34,7 +55,12 @@ public class ClusterPrivilege extends AbstractAutomatonPrivilege { - public static final IndexPrivilege NONE = new IndexPrivilege(Name.NONE, BasicAutomata.makeEmpty()); - public static final IndexPrivilege ALL = new IndexPrivilege(Name.ALL, "indices:*"); - public static final IndexPrivilege MANAGE = new IndexPrivilege("manage", "indices:monitor/*", "indices:admin/*"); - public static final IndexPrivilege CREATE_INDEX = new IndexPrivilege("create_index", CreateIndexAction.NAME); - public static final IndexPrivilege MANAGE_ALIASES = new IndexPrivilege("manage_aliases", "indices:admin/aliases*"); - public static final IndexPrivilege MONITOR = new IndexPrivilege("monitor", "indices:monitor/*"); - public static final IndexPrivilege DATA_ACCESS = new IndexPrivilege("data_access", "indices:data/*", "indices:admin/mapping/put"); - public static final IndexPrivilege CRUD = - new IndexPrivilege("crud", "indices:data/write/*", "indices:data/read/*", "indices:admin/mapping/put"); - public static final IndexPrivilege READ = new IndexPrivilege("read", "indices:data/read/*"); - public static final IndexPrivilege SEARCH = - new IndexPrivilege("search", SearchAction.NAME + "*", MultiSearchAction.NAME + "*", SuggestAction.NAME + "*"); - public static final IndexPrivilege GET = new IndexPrivilege("get", GetAction.NAME + "*", MultiGetAction.NAME + "*"); - public static final IndexPrivilege SUGGEST = new IndexPrivilege("suggest", SuggestAction.NAME + "*"); - public static final IndexPrivilege INDEX = - new IndexPrivilege("index", "indices:data/write/index*", "indices:data/write/update*", "indices:admin/mapping/put"); - public static final IndexPrivilege DELETE = new IndexPrivilege("delete", "indices:data/write/delete*"); - public static final IndexPrivilege WRITE = new IndexPrivilege("write", "indices:data/write/*", "indices:admin/mapping/put"); + private static final Automaton ALL_AUTOMATON = patterns("indices:*"); + private static final Automaton READ_AUTOMATON = patterns("indices:data/read/*"); + private static final Automaton CREATE_AUTOMATON = patterns("indices:data/write/index*", PutMappingAction.NAME); + private static final Automaton INDEX_AUTOMATON = + patterns("indices:data/write/index*", "indices:data/write/update*", PutMappingAction.NAME); + private static final Automaton DELETE_AUTOMATON = patterns("indices:data/write/delete*"); + private static final Automaton WRITE_AUTOMATON = patterns("indices:data/write/*", PutMappingAction.NAME); + private static final Automaton MONITOR_AUTOMATON = patterns("indices:monitor/*"); + private static final Automaton MANAGE_AUTOMATON = unionAndDeterminize(MONITOR_AUTOMATON, patterns("indices:admin/*")); + private static final Automaton CREATE_INDEX_AUTOMATON = patterns(CreateIndexAction.NAME); + private static final Automaton DELETE_INDEX_AUTOMATON = patterns(DeleteIndexAction.NAME); + private static final Automaton VIEW_METADATA_AUTOMATON = patterns(GetAliasesAction.NAME, AliasesExistAction.NAME, + GetIndexAction.NAME, IndicesExistsAction.NAME, GetFieldMappingsAction.NAME, GetMappingsAction.NAME, + ClusterSearchShardsAction.NAME, TypesExistsAction.NAME, ValidateQueryAction.NAME, GetSettingsAction.NAME); + + public static final IndexPrivilege NONE = new IndexPrivilege(Name.NONE, Automatons.EMPTY); + public static final IndexPrivilege ALL = new IndexPrivilege(Name.ALL, ALL_AUTOMATON); + public static final IndexPrivilege READ = new IndexPrivilege("read", READ_AUTOMATON); + public static final IndexPrivilege CREATE = new IndexPrivilege("create", CREATE_AUTOMATON); + public static final IndexPrivilege INDEX = new IndexPrivilege("index", INDEX_AUTOMATON); + public static final IndexPrivilege DELETE = new IndexPrivilege("delete", DELETE_AUTOMATON); + public static final IndexPrivilege WRITE = new IndexPrivilege("write", WRITE_AUTOMATON); + public static final IndexPrivilege MONITOR = new IndexPrivilege("monitor", MONITOR_AUTOMATON); + public static final IndexPrivilege MANAGE = new IndexPrivilege("manage", MANAGE_AUTOMATON); + public static final IndexPrivilege DELETE_INDEX = new IndexPrivilege("delete_index", DELETE_INDEX_AUTOMATON); + public static final IndexPrivilege CREATE_INDEX = new IndexPrivilege("create_index", CREATE_INDEX_AUTOMATON); + public static final IndexPrivilege VIEW_METADATA = new IndexPrivilege("view_index_metadata", VIEW_METADATA_AUTOMATON); private static final Set values = new CopyOnWriteArraySet<>(); @@ -52,17 +71,14 @@ public class IndexPrivilege extends AbstractAutomatonPrivilege { values.add(ALL); values.add(MANAGE); values.add(CREATE_INDEX); - values.add(MANAGE_ALIASES); values.add(MONITOR); - values.add(DATA_ACCESS); - values.add(CRUD); values.add(READ); - values.add(SEARCH); - values.add(GET); - values.add(SUGGEST); values.add(INDEX); values.add(DELETE); values.add(WRITE); + values.add(CREATE); + values.add(DELETE_INDEX); + values.add(VIEW_METADATA); } public static final Predicate ACTION_MATCHER = ALL.predicate(); @@ -78,8 +94,8 @@ public class IndexPrivilege extends AbstractAutomatonPrivilege { super(name, patterns); } - private IndexPrivilege(Name name, String... patterns) { - super(name, patterns); + private IndexPrivilege(String name, Automaton automaton) { + super(new Name(name), automaton); } private IndexPrivilege(Name name, Automaton automaton) { diff --git a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/support/Automatons.java b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/support/Automatons.java index 03ae9e41011..48280b2c599 100644 --- a/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/support/Automatons.java +++ b/elasticsearch/x-pack/shield/src/main/java/org/elasticsearch/shield/support/Automatons.java @@ -24,6 +24,8 @@ import static dk.brics.automaton.MinimizationOperations.minimize; */ public final class Automatons { + public static final Automaton EMPTY = BasicAutomata.makeEmpty(); + static final char WILDCARD_STRING = '*'; // String equality with support for wildcards static final char WILDCARD_CHAR = '?'; // Char equality with support for wildcards static final char WILDCARD_ESCAPE = '\\'; // Escape character diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentLevelSecurityRandomTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentLevelSecurityRandomTests.java index 3a82a5f8706..633c3d9c77c 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentLevelSecurityRandomTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/DocumentLevelSecurityRandomTests.java @@ -63,7 +63,8 @@ public class DocumentLevelSecurityRandomTests extends ShieldIntegTestCase { builder.append(" cluster: [ all ]\n"); builder.append(" indices:\n"); builder.append(" - names: '*'\n"); - builder.append(" privileges: [ ALL ]\n"); + builder.append(" privileges:\n"); + builder.append(" - all\n"); builder.append(" query: \n"); builder.append(" term: \n"); builder.append(" field1: value").append(i).append('\n'); 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 0ab2f3e34ae..48678fc9e63 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 @@ -73,10 +73,12 @@ public class DocumentLevelSecurityTests extends ShieldIntegTestCase { protected String configRoles() { return super.configRoles() + "\nrole1:\n" + - " cluster: [ all ]\n" + + " cluster:\n" + + " - all\n" + " indices:\n" + " - names: '*'\n" + - " privileges: [ ALL ]\n" + + " privileges:\n" + + " - all\n" + " query: \n" + " term: \n" + " field1: value1\n" + diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/FieldLevelSecurityRandomTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/FieldLevelSecurityRandomTests.java index 46cb49b1db9..f4c48692e6b 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/FieldLevelSecurityRandomTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/FieldLevelSecurityRandomTests.java @@ -86,10 +86,12 @@ public class FieldLevelSecurityRandomTests extends ShieldIntegTestCase { " privileges: [ ALL ]\n" + " fields:\n" +roleFields.toString() + "role2:\n" + - " cluster: [ all ]\n" + + " cluster:\n" + + " - all\n" + " indices:\n" + " - names: test\n" + - " privileges: [ ALL ]\n" + + " privileges:\n" + + " - all\n" + " fields:\n" + " - field1\n" + "role3:\n" + diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/SearchGetAndSuggestPermissionsTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/SearchGetAndSuggestPermissionsTests.java deleted file mode 100644 index c4208907190..00000000000 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/integration/SearchGetAndSuggestPermissionsTests.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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.ElasticsearchSecurityException; -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; -import org.elasticsearch.shield.authc.support.Hasher; -import org.elasticsearch.shield.authc.support.SecuredString; -import org.elasticsearch.shield.authc.support.SecuredStringTests; -import org.elasticsearch.shield.authc.support.UsernamePasswordToken; -import org.elasticsearch.test.ShieldIntegTestCase; - -import java.util.Map; - -import static java.util.Collections.singletonMap; -import static org.elasticsearch.client.Requests.searchRequest; -import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; -import static org.elasticsearch.test.ShieldTestsUtils.assertAuthorizationException; -import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; - -public class SearchGetAndSuggestPermissionsTests extends ShieldIntegTestCase { - protected static final String USERS_PASSWD_HASHED = new String(Hasher.BCRYPT.hash(new SecuredString("passwd".toCharArray()))); - - @Override - protected String configRoles() { - return super.configRoles() + "\n" + - "\n" + - "search_role:\n" + - " indices:\n" + - " - names: 'a'\n" + - " privileges: [ search ]\n" + - "\n" + - "get_role:\n" + - " indices:\n" + - " - names: 'a'\n" + - " privileges: [ get ]\n" + - "\n" + - "suggest_role:\n" + - " indices:\n" + - " - names: 'a'\n" + - " privileges: [ suggest ]\n"; - } - - @Override - protected String configUsers() { - return super.configUsers() + - "search_user:" + USERS_PASSWD_HASHED + "\n" + - "get_user:" + USERS_PASSWD_HASHED + "\n" + - "suggest_user:" + USERS_PASSWD_HASHED + "\n"; - - } - - @Override - protected String configUsersRoles() { - return super.configUsersRoles() + - "search_role:search_user\n" + - "get_role:get_user\n" + - "suggest_role:suggest_user\n"; - } - - /** - * testing both "search" and "suggest" privileges can execute the suggest API - */ - 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(); - - Map headers = singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("suggest_user", "passwd")); - SuggestResponse suggestResponse = client.filterWithHeader(headers) - .prepareSuggest("a") - .addSuggestion(randomAsciiOfLengthBetween(3,7), SuggestBuilders.termSuggestion("name").text("val")).get(); - assertNoFailures(suggestResponse); - assertThat(suggestResponse.getSuggest().size(), is(1)); - - suggestResponse = client - .filterWithHeader(singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("search_user", "passwd"))) - .prepareSuggest("a") - .addSuggestion(randomAsciiOfLengthBetween(3, 7), SuggestBuilders.termSuggestion("name").text("val")).get(); - assertNoFailures(suggestResponse); - assertThat(suggestResponse.getSuggest().size(), is(1)); - - try { - client.filterWithHeader(singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("suggest_user", "passwd"))) - .prepareSearch("a") - .get(); - fail("a user with only a suggest privilege cannot execute search"); - } catch (ElasticsearchSecurityException e) { - logger.error("failed to search", e); - // expected - } - } - - /** - * testing that "search" privilege cannot execute the get API - */ - 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(); - - try { - client.filterWithHeader(singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("search_user", "passwd"))) - .prepareGet("a", "type", indexResponse.getId()) - .get(); - fail("a user with only search privilege should not be authorized for a get request"); - } catch (ElasticsearchSecurityException e) { - // expected - assertAuthorizationException(e); - logger.error("could not get document", e); - } - } - - /** - * testing that "get" privilege can execute the mget API, and "search" privilege cannot execute mget - */ - 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 - .filterWithHeader(singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("get_user", "passwd"))) - .prepareMultiGet().add("a", "type", indexResponse.getId()) - .get(); - assertNotNull(response); - assertThat(response.getResponses().length, is(1)); - assertThat(response.getResponses()[0].getId(), equalTo(indexResponse.getId())); - - try { - client.filterWithHeader(singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("search_user", "passwd"))) - .prepareMultiGet().add("a", "type", indexResponse.getId()) - .get(); - fail("a user with only a search privilege should not be able to execute the mget API"); - } catch (ElasticsearchSecurityException e) { - // expected - assertAuthorizationException(e); - logger.error("could not mget documents", e); - } - } - - /** - * testing that "search" privilege can execute the msearch API - */ - 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 - .filterWithHeader(singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, userHeader("search_user", "passwd"))) - .prepareMultiSearch().add(searchRequest("a").types("type")) - .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)); - } -} diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/IndexAliasesTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/IndexAliasesTests.java index 43374091036..14564560d53 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/IndexAliasesTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/IndexAliasesTests.java @@ -60,30 +60,30 @@ public class IndexAliasesTests extends ShieldIntegTestCase { " indices:\n" + " - names: '*'\n" + " privileges: [ create_index ]\n" + - //role that has create index and managa aliases on test_*, not enough to manage aliases outside of test_* namespace + //role that has create index and manage_aliases on test_*, not enough to manage_aliases aliases outside of test_* namespace "create_test_aliases_test:\n" + " indices:\n" + " - names: 'test_*'\n" + - " privileges: [ create_index, manage_aliases ]\n" + - //role that has create index on test_* and manage aliases on alias_*, can't create aliases pointing to test_* though + " privileges: [ create_index, 'indices:admin/aliases*' ]\n" + + //role that has create index on test_* and manage_aliases on alias_*, can't create aliases pointing to test_* though "create_test_aliases_alias:\n" + " indices:\n" + " - names: 'test_*'\n" + " privileges: [ create_index ]\n" + " - names: 'alias_*'\n" + - " privileges: [ manage_aliases ]\n" + + " privileges: [ 'indices:admin/aliases*' ]\n" + //role that has create index on test_* and manage_aliases on both alias_* and test_* "create_test_aliases_test_alias:\n" + " indices:\n" + " - names: 'test_*'\n" + " privileges: [ create_index ]\n" + " - names: [ 'alias_*', 'test_*' ]\n" + - " privileges: [ manage_aliases ]\n" + + " privileges: [ 'indices:admin/aliases*' ]\n" + //role that has manage_aliases only on both test_* and alias_* "aliases_only:\n" + " indices:\n" + " - names: [ 'alias_*', 'test_*']\n" + - " privileges: [ manage_aliases ]\n"; + " privileges: [ 'indices:admin/aliases*' ]\n"; } @Before @@ -368,7 +368,7 @@ public class IndexAliasesTests extends ShieldIntegTestCase { assertAcked(client.admin().indices().prepareCreate("test_1")); try { - //fails: user doesn't have manage aliases on test_1 + //fails: user doesn't have manage_aliases aliases on test_1 client.admin().indices().prepareAliases().addAlias("test_1", "test_alias").get(); fail("add alias should have failed due to missing manage_aliases privileges on test_alias and test_1"); } catch(ElasticsearchSecurityException e) { @@ -377,7 +377,7 @@ public class IndexAliasesTests extends ShieldIntegTestCase { } try { - //fails: user doesn't have manage aliases on test_1 + //fails: user doesn't have manage_aliases aliases on test_1 client.admin().indices().prepareAliases().addAlias("test_1", "alias_1").get(); fail("add alias should have failed due to missing manage_aliases privileges on test_1"); } catch(ElasticsearchSecurityException e) { @@ -386,7 +386,7 @@ public class IndexAliasesTests extends ShieldIntegTestCase { } try { - //fails: user doesn't have manage aliases on test_*, no matching indices to replace wildcards + //fails: user doesn't have manage_aliases aliases on test_*, no matching indices to replace wildcards client.admin().indices().prepareAliases().addAlias("test_*", "alias_1").get(); fail("add alias should have failed due to missing manage_aliases privileges on test_1"); } catch(IndexNotFoundException e) { @@ -465,7 +465,7 @@ public class IndexAliasesTests extends ShieldIntegTestCase { assertAcked(client.admin().indices().prepareCreate("test_1")); try { - //fails: user doesn't have manage aliases on test_1, nor test_alias + //fails: user doesn't have manage_aliases aliases on test_1, nor test_alias client.admin().indices().prepareGetAliases().setAliases("test_alias").setIndices("test_1").get(); fail("get alias should have failed due to missing manage_aliases privileges on test_alias and test_1"); } catch(ElasticsearchSecurityException e) { @@ -474,7 +474,7 @@ public class IndexAliasesTests extends ShieldIntegTestCase { } try { - //fails: user doesn't have manage aliases on test_*, no matching indices to replace wildcards + //fails: user doesn't have manage_aliases aliases on test_*, no matching indices to replace wildcards client.admin().indices().prepareGetAliases().setIndices("test_*").setAliases("test_alias").get(); fail("get alias should have failed due to missing manage_aliases privileges on test_*"); } catch(IndexNotFoundException e) { diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/InternalAuthorizationServiceTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/InternalAuthorizationServiceTests.java index 3e11e9dd00e..4863d157686 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/InternalAuthorizationServiceTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/InternalAuthorizationServiceTests.java @@ -302,7 +302,7 @@ public class InternalAuthorizationServiceTests extends ESTestCase { User user = new User("test user", "a_star", "b"); ClusterState state = mock(ClusterState.class); when(rolesStore.role("a_star")).thenReturn(Role.builder("a_star").add(IndexPrivilege.ALL, "a*").build()); - when(rolesStore.role("b")).thenReturn(Role.builder("a_star").add(IndexPrivilege.SEARCH, "b").build()); + when(rolesStore.role("b")).thenReturn(Role.builder("a_star").add(IndexPrivilege.READ, "b").build()); when(clusterService.state()).thenReturn(state); Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build(); when(state.metaData()).thenReturn(MetaData.builder() diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/PermissionTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/PermissionTests.java index 255b8f78644..b3ae5bb80df 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/PermissionTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/permission/PermissionTests.java @@ -18,7 +18,6 @@ import java.util.function.Predicate; import static org.elasticsearch.shield.authz.privilege.IndexPrivilege.MONITOR; import static org.elasticsearch.shield.authz.privilege.IndexPrivilege.READ; -import static org.elasticsearch.shield.authz.privilege.IndexPrivilege.SEARCH; import static org.elasticsearch.shield.authz.privilege.IndexPrivilege.union; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -33,7 +32,7 @@ public class PermissionTests extends ESTestCase { @Before public void init() { Role.Builder builder = Role.builder("test"); - builder.add(union(SEARCH, MONITOR), "test_*", "/foo.*/"); + builder.add(union(MONITOR), "test_*", "/foo.*/"); builder.add(union(READ), "baz_*foo", "/fool.*bar/"); builder.add(union(MONITOR), "/bar.*/"); permission = builder.build(); diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/privilege/PrivilegeTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/privilege/PrivilegeTests.java index 5be16799a12..11fb580ea5b 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/privilege/PrivilegeTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/privilege/PrivilegeTests.java @@ -5,15 +5,10 @@ */ package org.elasticsearch.shield.authz.privilege; -import org.elasticsearch.action.get.GetAction; -import org.elasticsearch.action.get.MultiGetAction; import org.elasticsearch.action.ingest.DeletePipelineAction; import org.elasticsearch.action.ingest.GetPipelineAction; import org.elasticsearch.action.ingest.PutPipelineAction; import org.elasticsearch.action.ingest.SimulatePipelineAction; -import org.elasticsearch.action.search.MultiSearchAction; -import org.elasticsearch.action.search.SearchAction; -import org.elasticsearch.action.suggest.SuggestAction; import org.elasticsearch.shield.support.AutomatonPredicate; import org.elasticsearch.shield.support.Automatons; import org.elasticsearch.test.ESTestCase; @@ -262,27 +257,4 @@ public class PrivilegeTests extends ESTestCase { assertThat(predicate.test("indices:admin/mapping/put"), is(false)); assertThat(predicate.test("indices:admin/mapping/whatever"), is(false)); } - - public void testSearchPrivilege() throws Exception { - Predicate predicate = IndexPrivilege.SEARCH.predicate(); - assertThat(predicate.test(SearchAction.NAME), is(true)); - assertThat(predicate.test(SearchAction.NAME + "/whatever"), is(true)); - assertThat(predicate.test(MultiSearchAction.NAME), is(true)); - assertThat(predicate.test(MultiSearchAction.NAME + "/whatever"), is(true)); - assertThat(predicate.test(SuggestAction.NAME), is(true)); - assertThat(predicate.test(SuggestAction.NAME + "/whatever"), is(true)); - - assertThat(predicate.test(GetAction.NAME), is(false)); - assertThat(predicate.test(GetAction.NAME + "/whatever"), is(false)); - assertThat(predicate.test(MultiGetAction.NAME), is(false)); - assertThat(predicate.test(MultiGetAction.NAME + "/whatever"), is(false)); - } - - public void testGetPrivilege() throws Exception { - Predicate predicate = IndexPrivilege.GET.predicate(); - assertThat(predicate.test(GetAction.NAME), is(true)); - assertThat(predicate.test(GetAction.NAME + "/whatever"), is(true)); - assertThat(predicate.test(MultiGetAction.NAME), is(true)); - assertThat(predicate.test(MultiGetAction.NAME + "/whatever"), is(true)); - } } diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/store/FileRolesStoreTests.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/store/FileRolesStoreTests.java index 9aac116b137..ff724398c63 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/store/FileRolesStoreTests.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/shield/authz/store/FileRolesStoreTests.java @@ -82,7 +82,8 @@ public class FileRolesStoreTests extends ESTestCase { assertThat(group.indices().length, is(1)); assertThat(group.indices()[0], equalTo("idx3")); assertThat(group.privilege(), notNullValue()); - assertThat(group.privilege(), is(IndexPrivilege.CRUD)); + assertThat(group.privilege().implies(IndexPrivilege.READ), is(true)); + assertThat(group.privilege().implies(IndexPrivilege.WRITE),is(true)); role = roles.get("role1.ab"); assertThat(role, notNullValue()); @@ -228,21 +229,21 @@ public class FileRolesStoreTests extends ESTestCase { * This test is mainly to make sure we can read the default roles.yml config */ public void testDefaultRolesFile() throws Exception { + // TODO we should add the config dir to the resources so we don't copy this stuff around... Path path = getDataPath("default_roles.yml"); Map roles = FileRolesStore.parseFile(path, logger, Settings.EMPTY); assertThat(roles, notNullValue()); - assertThat(roles.size(), is(10)); + assertThat(roles.size(), is(9)); assertThat(roles, hasKey("admin")); assertThat(roles, hasKey("power_user")); assertThat(roles, hasKey("user")); - assertThat(roles, hasKey("kibana4")); + assertThat(roles, hasKey("transport_client")); assertThat(roles, hasKey("kibana4_server")); assertThat(roles, hasKey("logstash")); assertThat(roles, hasKey("monitoring_user")); assertThat(roles, hasKey("remote_monitoring_agent")); assertThat(roles, hasKey("ingest_admin")); - assertThat(roles, hasKey("transport_client")); } public void testAutoReload() throws Exception { diff --git a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/ShieldSettingsSource.java b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/ShieldSettingsSource.java index ceca8a36646..356faf4a430 100644 --- a/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/ShieldSettingsSource.java +++ b/elasticsearch/x-pack/shield/src/test/java/org/elasticsearch/test/ShieldSettingsSource.java @@ -71,8 +71,7 @@ public class ShieldSettingsSource extends ClusterDiscoveryConfiguration.UnicastZ " privileges: [ ALL ]\n" + DEFAULT_TRANSPORT_CLIENT_ROLE + ":\n" + " cluster:\n" + - " - cluster:monitor/nodes/info\n" + - " - cluster:monitor/state"; + " - transport_client"; private final Path parentFolder; private final String subfolderPrefix; diff --git a/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/shield/authz/store/default_roles.yml b/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/shield/authz/store/default_roles.yml index 3413231018a..1c36fd5ab07 100644 --- a/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/shield/authz/store/default_roles.yml +++ b/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/shield/authz/store/default_roles.yml @@ -26,101 +26,51 @@ user: # Defines the required permissions for transport clients transport_client: cluster: - - cluster:monitor/nodes/liveness - #uncomment the following for sniffing - #- cluster:monitor/state - -# The required permissions for kibana 4 users. -kibana4: - cluster: - - cluster:monitor/nodes/info - - cluster:monitor/health - indices: - - names: '*' - privileges: - - indices:admin/mappings/fields/get - - indices:admin/validate/query - - indices:data/read/search - - indices:data/read/msearch - - indices:data/read/field_stats - - indices:admin/get - - names: '.kibana' - privileges: - - indices:admin/exists - - indices:admin/mapping/put - - indices:admin/mappings/fields/get - - indices:admin/refresh - - indices:admin/validate/query - - indices:data/read/get - - indices:data/read/mget - - indices:data/read/search - - indices:data/write/delete - - indices:data/write/index - - indices:data/write/update + - transport_client # The required permissions for the kibana 4 server kibana4_server: cluster: - - cluster:monitor/nodes/info - - cluster:monitor/health + - monitor indices: - names: '.kibana' privileges: - - indices:admin/create - - indices:admin/exists - - indices:admin/mapping/put - - indices:admin/mappings/fields/get - - indices:admin/refresh - - indices:admin/validate/query - - indices:data/read/get - - indices:data/read/mget - - indices:data/read/search - - indices:data/write/delete - - indices:data/write/index - - indices:data/write/update + - all # The required role for logstash users logstash: cluster: - - indices:admin/template/get - - indices:admin/template/put + - manage_index_templates indices: - names: 'logstash-*' privileges: - - indices:data/write/bulk - - indices:data/write/delete - - indices:data/write/update - - indices:data/read/search - - indices:data/read/scroll + - write + - read - create_index -# Monitoring user role. Assign to monitoring users. +# Marvel user role. Assign to marvel users. monitoring_user: indices: - - names: '.monitoring-*' - privileges: - - read + - names: + - '.marvel-es-*' + - '.monitoring-*' + privileges: [ "read" ] - names: '.kibana' privileges: - - indices:admin/exists - - indices:admin/mappings/fields/get - - indices:admin/validate/query - - indices:data/read/get - - indices:data/read/mget - - indices:data/read/search + - view_index_metadata + - read -# Monitoring remote agent role. Assign to the agent user on the remote monitoring cluster -# to which the monitoring agent will export all its data +# Marvel remote agent role. Assign to the agent user on the remote marvel cluster +# to which the marvel agent will export all its data remote_monitoring_agent: - cluster: - - indices:admin/template/put - - indices:admin/template/get + cluster: [ "manage_index_templates" ] indices: - - names: '.monitoring-*' - privileges: - - all + - names: + - '.marvel-es-*' + - '.monitoring-*' + privileges: [ "all" ] # Allows all operations required to manage ingest pipelines ingest_admin: cluster: - - manage_pipeline \ No newline at end of file + - manage_pipeline diff --git a/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/shield/authz/store/roles.yml b/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/shield/authz/store/roles.yml index 766d56487aa..47eda4b6dae 100644 --- a/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/shield/authz/store/roles.yml +++ b/elasticsearch/x-pack/shield/src/test/resources/org/elasticsearch/shield/authz/store/roles.yml @@ -9,7 +9,8 @@ role1: - READ - names: idx3 privileges: - - CRUD + - READ + - WRITE role1.ab: cluster: