diff --git a/src/main/java/org/elasticsearch/shield/authz/Permission.java b/src/main/java/org/elasticsearch/shield/authz/Permission.java index f084f70f602..36a38583073 100644 --- a/src/main/java/org/elasticsearch/shield/authz/Permission.java +++ b/src/main/java/org/elasticsearch/shield/authz/Permission.java @@ -46,9 +46,6 @@ public interface Permission { static class Global implements Permission { - final static Predicate clusterActionMatcher = Privilege.Cluster.ALL.predicate(); - final static Predicate indicesActionMatcher = Privilege.Index.ALL.predicate(); - private final Cluster cluster; private final Indices indices; @@ -70,10 +67,10 @@ public interface Permission { } public boolean check(User user, String action, TransportRequest request, MetaData metaData) { - if (clusterActionMatcher.apply(action)) { + if (Privilege.Cluster.ACTION_MATCHER.apply(action)) { return cluster != null && cluster.check(user, action, request, metaData); } - if (indicesActionMatcher.apply(action)) { + if (Privilege.Index.ACTION_MATCHER.apply(action)) { return indices != null && indices.check(user, action, request, metaData); } return false; diff --git a/src/main/java/org/elasticsearch/shield/authz/Privilege.java b/src/main/java/org/elasticsearch/shield/authz/Privilege.java index 45d0d463eaf..d6da98e69c3 100644 --- a/src/main/java/org/elasticsearch/shield/authz/Privilege.java +++ b/src/main/java/org/elasticsearch/shield/authz/Privilege.java @@ -117,6 +117,8 @@ public abstract class Privilege

> { NONE, ALL, MANAGE, CREATE_INDEX, MONITOR, DATA_ACCESS, CRUD, READ, SEARCH, GET, INDEX, DELETE, WRITE, BENCHMARK }; + public static final Predicate ACTION_MATCHER = Privilege.Index.ALL.predicate(); + static Index[] values() { return values; } @@ -180,7 +182,7 @@ public abstract class Privilege

> { private static Index resolve(String name) { name = name.toLowerCase(Locale.ROOT); - if (name.startsWith("indices:")) { + if (ACTION_MATCHER.apply(name)) { return action(name); } for (Index index : values) { @@ -190,7 +192,7 @@ public abstract class Privilege

> { } throw new ElasticsearchIllegalArgumentException("Unknown index privilege [" + name + "]. A privilege must either " + "on of the predefined fixed indices privileges [" + Strings.arrayToCommaDelimitedString(values) + - "] or a pattern over one of the available index actions (the pattern must begin with \"indices:\" prefix)"); + "] or a pattern over one of the available index actions"); } } @@ -201,6 +203,8 @@ public abstract class Privilege

> { public static final Cluster ALL = new Cluster(Name.ALL, "cluster:*", "indices:admin/template/*"); public static final Cluster MONITOR = new Cluster("monitor", "cluster:monitor/*"); + final static Predicate ACTION_MATCHER = Privilege.Cluster.ALL.predicate(); + private static final Cluster[] values = new Cluster[] { NONE, ALL, MONITOR }; static Cluster[] values() { @@ -233,9 +237,7 @@ public abstract class Privilege

> { @Override protected Cluster create(Name name, Automaton automaton) { - if (name == Name.NONE) { - return NONE; - } + return new Cluster(name, automaton); } @@ -259,7 +261,7 @@ public abstract class Privilege

> { private static Cluster resolve(String name) { name = name.toLowerCase(Locale.ROOT); - if (name.startsWith("cluster:")) { + if (ACTION_MATCHER.apply(name)) { return action(name); } for (Cluster cluster : values) { @@ -269,7 +271,7 @@ public abstract class Privilege

> { } throw new ElasticsearchIllegalArgumentException("Unknown cluster privilege [" + name + "]. A privilege must either " + "on of the predefined fixed cluster privileges [" + Strings.arrayToCommaDelimitedString(values) + - "] or a pattern over one of the available cluster actions (the pattern must begin with \"cluster:\" prefix)"); + "] or a pattern over one of the available cluster actions"); } } diff --git a/src/test/java/org/elasticsearch/shield/authz/PrivilegeTests.java b/src/test/java/org/elasticsearch/shield/authz/PrivilegeTests.java index 339d9ba3b45..5c426177f3d 100644 --- a/src/test/java/org/elasticsearch/shield/authz/PrivilegeTests.java +++ b/src/test/java/org/elasticsearch/shield/authz/PrivilegeTests.java @@ -72,6 +72,25 @@ public class PrivilegeTests extends ElasticsearchTestCase { assertThat(cluster, is(cluster2)); } + @Test + public void testCluster_TemplateActions() throws Exception { + + Privilege.Name name = new Privilege.Name("indices:admin/template/delete"); + Privilege.Cluster cluster = Privilege.Cluster.get(name); + assertThat(cluster, notNullValue()); + assertThat(cluster.predicate().apply("indices:admin/template/delete"), is(true)); + + name = new Privilege.Name("indices:admin/template/get"); + cluster = Privilege.Cluster.get(name); + assertThat(cluster, notNullValue()); + assertThat(cluster.predicate().apply("indices:admin/template/get"), is(true)); + + name = new Privilege.Name("indices:admin/template/put"); + cluster = Privilege.Cluster.get(name); + assertThat(cluster, notNullValue()); + assertThat(cluster.predicate().apply("indices:admin/template/put"), is(true)); + } + @Test public void testCluster_InvalidNaem() throws Exception { thrown.expect(ElasticsearchIllegalArgumentException.class); diff --git a/src/test/java/org/elasticsearch/shield/authz/store/FileRolesStoreTests.java b/src/test/java/org/elasticsearch/shield/authz/store/FileRolesStoreTests.java index 920b4585e35..d6c7b14f7f1 100644 --- a/src/test/java/org/elasticsearch/shield/authz/store/FileRolesStoreTests.java +++ b/src/test/java/org/elasticsearch/shield/authz/store/FileRolesStoreTests.java @@ -7,6 +7,7 @@ package org.elasticsearch.shield.authz.store; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.base.Charsets; +import org.elasticsearch.common.base.Predicate; import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; @@ -94,6 +95,24 @@ public class FileRolesStoreTests extends ElasticsearchTestCase { assertThat(group.privilege().isAlias(Privilege.Index.union(Privilege.Index.READ, Privilege.Index.WRITE)), is(true)); } + /** + * This test is mainly to make sure we can read the default roles.yml config + */ + @Test + public void testDefaultRolesFile() throws Exception { + Path path = Paths.get(getClass().getResource("default_roles.yml").toURI()); + Map roles = FileRolesStore.parseFile(path, logger, mock(AuthorizationService.class)); + assertThat(roles, notNullValue()); + assertThat(roles.size(), is(6)); + + assertThat(roles, hasKey("admin")); + assertThat(roles, hasKey("power_user")); + assertThat(roles, hasKey("user")); + assertThat(roles, hasKey("kibana3")); + assertThat(roles, hasKey("kibana4")); + assertThat(roles, hasKey("logstash")); + } + @Test public void testAutoReload() throws Exception { ThreadPool threadPool = null; diff --git a/src/test/resources/org/elasticsearch/shield/authz/store/default_roles.yml b/src/test/resources/org/elasticsearch/shield/authz/store/default_roles.yml new file mode 100644 index 00000000000..59ede13072c --- /dev/null +++ b/src/test/resources/org/elasticsearch/shield/authz/store/default_roles.yml @@ -0,0 +1,36 @@ +admin: + cluster: all + indices: + '*': all + +# monitoring cluster privileges +# All operations on all indices +power_user: + cluster: monitor + indices: + '*': all + +# Only operations on indices +user: + indices: + '*': read + +# The required role for kibana 3 users +kibana3: + cluster: cluster:monitor/nodes/info + indices: + '*': indices:data/read/search, indices:data/read/get, indices:admin/get + 'kibana-int': indices:data/read/get, indices:data/read/search, indices:data/write/delete, indices:data/write/index, create_index + +# The required role for kibana 4 users +kibana4: + cluster: cluster:monitor/nodes/info + indices: + '*': indices:data/read/search, indices:data/read/get, indices:admin/get + '.kibana': indices:data/read/get, indices:data/read/search, indices:data/write/delete, indices:data/write/index, create_index + +# The required role for logstash users +logstash: + cluster: indices:admin/template/get, indices:admin/template/put + indices: + 'logstash-*': indices:data/write/bulk, indices:data/write/delete, indices:data/write/update, create_index \ No newline at end of file