diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/ClusterPermission.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/ClusterPermission.java index 7c990bd735a41..00a272dcbff7b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/ClusterPermission.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/ClusterPermission.java @@ -5,30 +5,92 @@ */ package org.elasticsearch.xpack.core.security.authz.permission; +import org.elasticsearch.transport.TransportRequest; import org.elasticsearch.xpack.core.security.authz.privilege.ClusterPrivilege; +import java.util.Collection; +import java.util.Set; import java.util.function.Predicate; +import java.util.stream.Collectors; /** - * A permission that is based on privileges for cluster wide actions + * A permission that is based on privileges for cluster wide actions, with the optional ability to inspect the request object */ -public final class ClusterPermission { - - public static final ClusterPermission NONE = new ClusterPermission(ClusterPrivilege.NONE); - +public abstract class ClusterPermission { private final ClusterPrivilege privilege; - private final Predicate predicate; ClusterPermission(ClusterPrivilege privilege) { this.privilege = privilege; - this.predicate = privilege.predicate(); } public ClusterPrivilege privilege() { return privilege; } - public boolean check(String action) { - return predicate.test(action); + public abstract boolean check(String action, TransportRequest request); + + /** + * A permission that is based solely on cluster privileges and does not consider request state + */ + public static class SimpleClusterPermission extends ClusterPermission { + + public static final SimpleClusterPermission NONE = new SimpleClusterPermission(ClusterPrivilege.NONE); + + private final Predicate predicate; + + SimpleClusterPermission(ClusterPrivilege privilege) { + super(privilege); + this.predicate = privilege.predicate(); + } + + @Override + public boolean check(String action, TransportRequest request) { + return predicate.test(action); + } + } + + /** + * A permission that makes use of both cluster privileges and request inspection + */ + public static class ConditionalClusterPermission extends ClusterPermission { + private final Predicate actionPredicate; + private final Predicate requestPredicate; + + public ConditionalClusterPermission(ClusterPrivilege privilege, Predicate requestPredicate) { + super(privilege); + this.actionPredicate = privilege.predicate(); + this.requestPredicate = requestPredicate; + } + + @Override + public boolean check(String action, TransportRequest request) { + return actionPredicate.test(action) && requestPredicate.test(request); + } + } + + /** + * A permission that composes a number of other cluster permissions + */ + public static class CompositeClusterPermission extends ClusterPermission { + private final Collection children; + + public CompositeClusterPermission(Collection children) { + super(buildPrivilege(children)); + this.children = children; + } + + private static ClusterPrivilege buildPrivilege(Collection children) { + final Set names = children.stream() + .map(ClusterPermission::privilege) + .map(ClusterPrivilege::name) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + return ClusterPrivilege.get(names); + } + + @Override + public boolean check(String action, TransportRequest request) { + return children.stream().anyMatch(p -> p.check(action, request)); + } } } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/Role.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/Role.java index 12bc9048dce3b..5eef17bc0ef18 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/Role.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/permission/Role.java @@ -95,7 +95,7 @@ public IndicesAccessControl authorize(String action, Set requestedIndice public static class Builder { private final String[] names; - private ClusterPermission cluster = ClusterPermission.NONE; + private ClusterPermission cluster = ClusterPermission.SimpleClusterPermission.NONE; private RunAsPermission runAs = RunAsPermission.NONE; private List groups = new ArrayList<>(); private List>> applicationPrivs = new ArrayList<>(); @@ -107,7 +107,7 @@ private Builder(String[] names) { private Builder(RoleDescriptor rd, @Nullable FieldPermissionsCache fieldPermissionsCache) { this.names = new String[] { rd.getName() }; if (rd.getClusterPrivileges().length == 0) { - cluster = ClusterPermission.NONE; + cluster = ClusterPermission.SimpleClusterPermission.NONE; } else { this.cluster(ClusterPrivilege.get(Sets.newHashSet(rd.getClusterPrivileges()))); } @@ -125,7 +125,7 @@ private Builder(RoleDescriptor rd, @Nullable FieldPermissionsCache fieldPermissi } public Builder cluster(ClusterPrivilege privilege) { - cluster = new ClusterPermission(privilege); + cluster = new ClusterPermission.SimpleClusterPermission(privilege); return this; } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java index 8868fcd616030..79c29b6e31268 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStore.java @@ -27,7 +27,7 @@ public class ReservedRolesStore { new String[] { "all" }, new RoleDescriptor.IndicesPrivileges[] { RoleDescriptor.IndicesPrivileges.builder().indices("*").privileges("all").build()}, - new RoleDescriptor.ApplicationResourcePrivileges[]{ + new RoleDescriptor.ApplicationResourcePrivileges[] { RoleDescriptor.ApplicationResourcePrivileges.builder().application("*").privileges("*").resources("*").build() }, new String[] { "*" }, diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java index 697f30ae797e3..8bf9626f74b45 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/store/ReservedRolesStoreTests.java @@ -35,6 +35,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.transport.TransportRequest; import org.elasticsearch.xpack.core.ml.MlMetaIndex; import org.elasticsearch.xpack.core.ml.action.CloseJobAction; import org.elasticsearch.xpack.core.ml.action.DeleteDatafeedAction; @@ -111,6 +112,7 @@ import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.is; +import static org.mockito.Mockito.mock; /** * Unit tests for the {@link ReservedRolesStore} @@ -142,21 +144,23 @@ public void testIsReserved() { } public void testIngestAdminRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("ingest_admin"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role ingestAdminRole = Role.builder(roleDescriptor, null).build(); - assertThat(ingestAdminRole.cluster().check(PutIndexTemplateAction.NAME), is(true)); - assertThat(ingestAdminRole.cluster().check(GetIndexTemplatesAction.NAME), is(true)); - assertThat(ingestAdminRole.cluster().check(DeleteIndexTemplateAction.NAME), is(true)); - assertThat(ingestAdminRole.cluster().check(PutPipelineAction.NAME), is(true)); - assertThat(ingestAdminRole.cluster().check(GetPipelineAction.NAME), is(true)); - assertThat(ingestAdminRole.cluster().check(DeletePipelineAction.NAME), is(true)); + assertThat(ingestAdminRole.cluster().check(PutIndexTemplateAction.NAME, request), is(true)); + assertThat(ingestAdminRole.cluster().check(GetIndexTemplatesAction.NAME, request), is(true)); + assertThat(ingestAdminRole.cluster().check(DeleteIndexTemplateAction.NAME, request), is(true)); + assertThat(ingestAdminRole.cluster().check(PutPipelineAction.NAME, request), is(true)); + assertThat(ingestAdminRole.cluster().check(GetPipelineAction.NAME, request), is(true)); + assertThat(ingestAdminRole.cluster().check(DeletePipelineAction.NAME, request), is(true)); - assertThat(ingestAdminRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(ingestAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(ingestAdminRole.cluster().check(MonitoringBulkAction.NAME), is(false)); + assertThat(ingestAdminRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(ingestAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(ingestAdminRole.cluster().check(MonitoringBulkAction.NAME, request), is(false)); assertThat(ingestAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test("foo"), is(false)); assertThat(ingestAdminRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)), @@ -166,31 +170,33 @@ public void testIngestAdminRole() { } public void testKibanaSystemRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("kibana_system"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role kibanaRole = Role.builder(roleDescriptor, null).build(); - assertThat(kibanaRole.cluster().check(ClusterHealthAction.NAME), is(true)); - assertThat(kibanaRole.cluster().check(ClusterStateAction.NAME), is(true)); - assertThat(kibanaRole.cluster().check(ClusterStatsAction.NAME), is(true)); - assertThat(kibanaRole.cluster().check(PutIndexTemplateAction.NAME), is(true)); - assertThat(kibanaRole.cluster().check(GetIndexTemplatesAction.NAME), is(true)); - assertThat(kibanaRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(kibanaRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(kibanaRole.cluster().check(MonitoringBulkAction.NAME), is(true)); + assertThat(kibanaRole.cluster().check(ClusterHealthAction.NAME, request), is(true)); + assertThat(kibanaRole.cluster().check(ClusterStateAction.NAME, request), is(true)); + assertThat(kibanaRole.cluster().check(ClusterStatsAction.NAME, request), is(true)); + assertThat(kibanaRole.cluster().check(PutIndexTemplateAction.NAME, request), is(true)); + assertThat(kibanaRole.cluster().check(GetIndexTemplatesAction.NAME, request), is(true)); + assertThat(kibanaRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(kibanaRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(kibanaRole.cluster().check(MonitoringBulkAction.NAME, request), is(true)); // SAML - assertThat(kibanaRole.cluster().check(SamlPrepareAuthenticationAction.NAME), is(true)); - assertThat(kibanaRole.cluster().check(SamlAuthenticateAction.NAME), is(true)); - assertThat(kibanaRole.cluster().check(InvalidateTokenAction.NAME), is(true)); - assertThat(kibanaRole.cluster().check(CreateTokenAction.NAME), is(false)); + assertThat(kibanaRole.cluster().check(SamlPrepareAuthenticationAction.NAME, request), is(true)); + assertThat(kibanaRole.cluster().check(SamlAuthenticateAction.NAME, request), is(true)); + assertThat(kibanaRole.cluster().check(InvalidateTokenAction.NAME, request), is(true)); + assertThat(kibanaRole.cluster().check(CreateTokenAction.NAME, request), is(false)); // Security - assertThat(kibanaRole.cluster().check(DeletePrivilegesAction.NAME), is(false)); - assertThat(kibanaRole.cluster().check(GetPrivilegesAction.NAME), is(true)); - assertThat(kibanaRole.cluster().check(PutPrivilegesAction.NAME), is(true)); - + assertThat(kibanaRole.cluster().check(DeletePrivilegesAction.NAME, request), is(false)); + assertThat(kibanaRole.cluster().check(GetPrivilegesAction.NAME, request), is(true)); + assertThat(kibanaRole.cluster().check(PutPrivilegesAction.NAME, request), is(true)); + // Everything else assertThat(kibanaRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false)); @@ -246,18 +252,20 @@ public void testKibanaSystemRole() { } public void testKibanaUserRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("kibana_user"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role kibanaUserRole = Role.builder(roleDescriptor, null).build(); - assertThat(kibanaUserRole.cluster().check(ClusterHealthAction.NAME), is(false)); - assertThat(kibanaUserRole.cluster().check(ClusterStateAction.NAME), is(false)); - assertThat(kibanaUserRole.cluster().check(ClusterStatsAction.NAME), is(false)); - assertThat(kibanaUserRole.cluster().check(PutIndexTemplateAction.NAME), is(false)); - assertThat(kibanaUserRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(kibanaUserRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(kibanaUserRole.cluster().check(MonitoringBulkAction.NAME), is(false)); + assertThat(kibanaUserRole.cluster().check(ClusterHealthAction.NAME, request), is(false)); + assertThat(kibanaUserRole.cluster().check(ClusterStateAction.NAME, request), is(false)); + assertThat(kibanaUserRole.cluster().check(ClusterStatsAction.NAME, request), is(false)); + assertThat(kibanaUserRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false)); + assertThat(kibanaUserRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(kibanaUserRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(kibanaUserRole.cluster().check(MonitoringBulkAction.NAME, request), is(false)); assertThat(kibanaUserRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false)); @@ -282,19 +290,21 @@ public void testKibanaUserRole() { } public void testMonitoringUserRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("monitoring_user"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role monitoringUserRole = Role.builder(roleDescriptor, null).build(); - assertThat(monitoringUserRole.cluster().check(MainAction.NAME), is(true)); - assertThat(monitoringUserRole.cluster().check(ClusterHealthAction.NAME), is(false)); - assertThat(monitoringUserRole.cluster().check(ClusterStateAction.NAME), is(false)); - assertThat(monitoringUserRole.cluster().check(ClusterStatsAction.NAME), is(false)); - assertThat(monitoringUserRole.cluster().check(PutIndexTemplateAction.NAME), is(false)); - assertThat(monitoringUserRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(monitoringUserRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(monitoringUserRole.cluster().check(MonitoringBulkAction.NAME), is(false)); + assertThat(monitoringUserRole.cluster().check(MainAction.NAME, request), is(true)); + assertThat(monitoringUserRole.cluster().check(ClusterHealthAction.NAME, request), is(false)); + assertThat(monitoringUserRole.cluster().check(ClusterStateAction.NAME, request), is(false)); + assertThat(monitoringUserRole.cluster().check(ClusterStatsAction.NAME, request), is(false)); + assertThat(monitoringUserRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false)); + assertThat(monitoringUserRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(monitoringUserRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(monitoringUserRole.cluster().check(MonitoringBulkAction.NAME, request), is(false)); assertThat(monitoringUserRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false)); @@ -321,27 +331,29 @@ public void testMonitoringUserRole() { } public void testRemoteMonitoringAgentRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("remote_monitoring_agent"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role remoteMonitoringAgentRole = Role.builder(roleDescriptor, null).build(); - assertThat(remoteMonitoringAgentRole.cluster().check(ClusterHealthAction.NAME), is(true)); - assertThat(remoteMonitoringAgentRole.cluster().check(ClusterStateAction.NAME), is(true)); - assertThat(remoteMonitoringAgentRole.cluster().check(ClusterStatsAction.NAME), is(true)); - assertThat(remoteMonitoringAgentRole.cluster().check(PutIndexTemplateAction.NAME), is(true)); - assertThat(remoteMonitoringAgentRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(remoteMonitoringAgentRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(remoteMonitoringAgentRole.cluster().check(MonitoringBulkAction.NAME), is(false)); - assertThat(remoteMonitoringAgentRole.cluster().check(GetWatchAction.NAME), is(true)); - assertThat(remoteMonitoringAgentRole.cluster().check(PutWatchAction.NAME), is(true)); - assertThat(remoteMonitoringAgentRole.cluster().check(DeleteWatchAction.NAME), is(true)); - assertThat(remoteMonitoringAgentRole.cluster().check(ExecuteWatchAction.NAME), is(false)); - assertThat(remoteMonitoringAgentRole.cluster().check(AckWatchAction.NAME), is(false)); - assertThat(remoteMonitoringAgentRole.cluster().check(ActivateWatchAction.NAME), is(false)); - assertThat(remoteMonitoringAgentRole.cluster().check(WatcherServiceAction.NAME), is(false)); + assertThat(remoteMonitoringAgentRole.cluster().check(ClusterHealthAction.NAME, request), is(true)); + assertThat(remoteMonitoringAgentRole.cluster().check(ClusterStateAction.NAME, request), is(true)); + assertThat(remoteMonitoringAgentRole.cluster().check(ClusterStatsAction.NAME, request), is(true)); + assertThat(remoteMonitoringAgentRole.cluster().check(PutIndexTemplateAction.NAME, request), is(true)); + assertThat(remoteMonitoringAgentRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(remoteMonitoringAgentRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(remoteMonitoringAgentRole.cluster().check(MonitoringBulkAction.NAME, request), is(false)); + assertThat(remoteMonitoringAgentRole.cluster().check(GetWatchAction.NAME, request), is(true)); + assertThat(remoteMonitoringAgentRole.cluster().check(PutWatchAction.NAME, request), is(true)); + assertThat(remoteMonitoringAgentRole.cluster().check(DeleteWatchAction.NAME, request), is(true)); + assertThat(remoteMonitoringAgentRole.cluster().check(ExecuteWatchAction.NAME, request), is(false)); + assertThat(remoteMonitoringAgentRole.cluster().check(AckWatchAction.NAME, request), is(false)); + assertThat(remoteMonitoringAgentRole.cluster().check(ActivateWatchAction.NAME, request), is(false)); + assertThat(remoteMonitoringAgentRole.cluster().check(WatcherServiceAction.NAME, request), is(false)); // we get this from the cluster:monitor privilege - assertThat(remoteMonitoringAgentRole.cluster().check(WatcherStatsAction.NAME), is(true)); + assertThat(remoteMonitoringAgentRole.cluster().check(WatcherStatsAction.NAME, request), is(true)); assertThat(remoteMonitoringAgentRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false)); @@ -365,18 +377,20 @@ public void testRemoteMonitoringAgentRole() { } public void testReportingUserRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("reporting_user"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role reportingUserRole = Role.builder(roleDescriptor, null).build(); - assertThat(reportingUserRole.cluster().check(ClusterHealthAction.NAME), is(false)); - assertThat(reportingUserRole.cluster().check(ClusterStateAction.NAME), is(false)); - assertThat(reportingUserRole.cluster().check(ClusterStatsAction.NAME), is(false)); - assertThat(reportingUserRole.cluster().check(PutIndexTemplateAction.NAME), is(false)); - assertThat(reportingUserRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(reportingUserRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(reportingUserRole.cluster().check(MonitoringBulkAction.NAME), is(false)); + assertThat(reportingUserRole.cluster().check(ClusterHealthAction.NAME, request), is(false)); + assertThat(reportingUserRole.cluster().check(ClusterStateAction.NAME, request), is(false)); + assertThat(reportingUserRole.cluster().check(ClusterStatsAction.NAME, request), is(false)); + assertThat(reportingUserRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false)); + assertThat(reportingUserRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(reportingUserRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(reportingUserRole.cluster().check(MonitoringBulkAction.NAME, request), is(false)); assertThat(reportingUserRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false)); @@ -401,18 +415,20 @@ public void testReportingUserRole() { } public void testKibanaDashboardOnlyUserRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("kibana_dashboard_only_user"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role dashboardsOnlyUserRole = Role.builder(roleDescriptor, null).build(); - assertThat(dashboardsOnlyUserRole.cluster().check(ClusterHealthAction.NAME), is(false)); - assertThat(dashboardsOnlyUserRole.cluster().check(ClusterStateAction.NAME), is(false)); - assertThat(dashboardsOnlyUserRole.cluster().check(ClusterStatsAction.NAME), is(false)); - assertThat(dashboardsOnlyUserRole.cluster().check(PutIndexTemplateAction.NAME), is(false)); - assertThat(dashboardsOnlyUserRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(dashboardsOnlyUserRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(dashboardsOnlyUserRole.cluster().check(MonitoringBulkAction.NAME), is(false)); + assertThat(dashboardsOnlyUserRole.cluster().check(ClusterHealthAction.NAME, request), is(false)); + assertThat(dashboardsOnlyUserRole.cluster().check(ClusterStateAction.NAME, request), is(false)); + assertThat(dashboardsOnlyUserRole.cluster().check(ClusterStatsAction.NAME, request), is(false)); + assertThat(dashboardsOnlyUserRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false)); + assertThat(dashboardsOnlyUserRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(dashboardsOnlyUserRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(dashboardsOnlyUserRole.cluster().check(MonitoringBulkAction.NAME, request), is(false)); assertThat(dashboardsOnlyUserRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false)); @@ -431,17 +447,19 @@ public void testKibanaDashboardOnlyUserRole() { } public void testSuperuserRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("superuser"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role superuserRole = Role.builder(roleDescriptor, null).build(); - assertThat(superuserRole.cluster().check(ClusterHealthAction.NAME), is(true)); - assertThat(superuserRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(true)); - assertThat(superuserRole.cluster().check(PutUserAction.NAME), is(true)); - assertThat(superuserRole.cluster().check(PutRoleAction.NAME), is(true)); - assertThat(superuserRole.cluster().check(PutIndexTemplateAction.NAME), is(true)); - assertThat(superuserRole.cluster().check("internal:admin/foo"), is(false)); + assertThat(superuserRole.cluster().check(ClusterHealthAction.NAME, request), is(true)); + assertThat(superuserRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(true)); + assertThat(superuserRole.cluster().check(PutUserAction.NAME, request), is(true)); + assertThat(superuserRole.cluster().check(PutRoleAction.NAME, request), is(true)); + assertThat(superuserRole.cluster().check(PutIndexTemplateAction.NAME, request), is(true)); + assertThat(superuserRole.cluster().check("internal:admin/foo", request), is(false)); final Settings indexSettings = Settings.builder().put("index.version.created", Version.CURRENT).build(); final MetaData metaData = new MetaData.Builder() @@ -480,18 +498,20 @@ public void testSuperuserRole() { } public void testLogstashSystemRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("logstash_system"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role logstashSystemRole = Role.builder(roleDescriptor, null).build(); - assertThat(logstashSystemRole.cluster().check(ClusterHealthAction.NAME), is(true)); - assertThat(logstashSystemRole.cluster().check(ClusterStateAction.NAME), is(true)); - assertThat(logstashSystemRole.cluster().check(ClusterStatsAction.NAME), is(true)); - assertThat(logstashSystemRole.cluster().check(PutIndexTemplateAction.NAME), is(false)); - assertThat(logstashSystemRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(logstashSystemRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(logstashSystemRole.cluster().check(MonitoringBulkAction.NAME), is(true)); + assertThat(logstashSystemRole.cluster().check(ClusterHealthAction.NAME, request), is(true)); + assertThat(logstashSystemRole.cluster().check(ClusterStateAction.NAME, request), is(true)); + assertThat(logstashSystemRole.cluster().check(ClusterStatsAction.NAME, request), is(true)); + assertThat(logstashSystemRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false)); + assertThat(logstashSystemRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(logstashSystemRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(logstashSystemRole.cluster().check(MonitoringBulkAction.NAME, request), is(true)); assertThat(logstashSystemRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); @@ -502,18 +522,21 @@ public void testLogstashSystemRole() { } public void testBeatsAdminRole() { + final TransportRequest request = mock(TransportRequest.class); + final RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("beats_admin"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); + final Role beatsAdminRole = Role.builder(roleDescriptor, null).build(); - assertThat(beatsAdminRole.cluster().check(ClusterHealthAction.NAME), is(false)); - assertThat(beatsAdminRole.cluster().check(ClusterStateAction.NAME), is(false)); - assertThat(beatsAdminRole.cluster().check(ClusterStatsAction.NAME), is(false)); - assertThat(beatsAdminRole.cluster().check(PutIndexTemplateAction.NAME), is(false)); - assertThat(beatsAdminRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(beatsAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(beatsAdminRole.cluster().check(MonitoringBulkAction.NAME), is(false)); + assertThat(beatsAdminRole.cluster().check(ClusterHealthAction.NAME, request), is(false)); + assertThat(beatsAdminRole.cluster().check(ClusterStateAction.NAME, request), is(false)); + assertThat(beatsAdminRole.cluster().check(ClusterStatsAction.NAME, request), is(false)); + assertThat(beatsAdminRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false)); + assertThat(beatsAdminRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(beatsAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(beatsAdminRole.cluster().check(MonitoringBulkAction.NAME, request), is(false)); assertThat(beatsAdminRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); @@ -535,18 +558,20 @@ public void testBeatsAdminRole() { } public void testBeatsSystemRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor(BeatsSystemUser.ROLE_NAME); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role logstashSystemRole = Role.builder(roleDescriptor, null).build(); - assertThat(logstashSystemRole.cluster().check(ClusterHealthAction.NAME), is(true)); - assertThat(logstashSystemRole.cluster().check(ClusterStateAction.NAME), is(true)); - assertThat(logstashSystemRole.cluster().check(ClusterStatsAction.NAME), is(true)); - assertThat(logstashSystemRole.cluster().check(PutIndexTemplateAction.NAME), is(false)); - assertThat(logstashSystemRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(logstashSystemRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); - assertThat(logstashSystemRole.cluster().check(MonitoringBulkAction.NAME), is(true)); + assertThat(logstashSystemRole.cluster().check(ClusterHealthAction.NAME, request), is(true)); + assertThat(logstashSystemRole.cluster().check(ClusterStateAction.NAME, request), is(true)); + assertThat(logstashSystemRole.cluster().check(ClusterStatsAction.NAME, request), is(true)); + assertThat(logstashSystemRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false)); + assertThat(logstashSystemRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(logstashSystemRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); + assertThat(logstashSystemRole.cluster().check(MonitoringBulkAction.NAME, request), is(true)); assertThat(logstashSystemRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); @@ -557,46 +582,48 @@ public void testBeatsSystemRole() { } public void testMachineLearningAdminRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("machine_learning_admin"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role role = Role.builder(roleDescriptor, null).build(); - assertThat(role.cluster().check(CloseJobAction.NAME), is(true)); - assertThat(role.cluster().check(DeleteDatafeedAction.NAME), is(true)); - assertThat(role.cluster().check(DeleteExpiredDataAction.NAME), is(true)); - assertThat(role.cluster().check(DeleteFilterAction.NAME), is(true)); - assertThat(role.cluster().check(DeleteJobAction.NAME), is(true)); - assertThat(role.cluster().check(DeleteModelSnapshotAction.NAME), is(true)); - assertThat(role.cluster().check(FinalizeJobExecutionAction.NAME), is(false)); // internal use only - assertThat(role.cluster().check(FlushJobAction.NAME), is(true)); - assertThat(role.cluster().check(GetBucketsAction.NAME), is(true)); - assertThat(role.cluster().check(GetCategoriesAction.NAME), is(true)); - assertThat(role.cluster().check(GetDatafeedsAction.NAME), is(true)); - assertThat(role.cluster().check(GetDatafeedsStatsAction.NAME), is(true)); - assertThat(role.cluster().check(GetFiltersAction.NAME), is(true)); - assertThat(role.cluster().check(GetInfluencersAction.NAME), is(true)); - assertThat(role.cluster().check(GetJobsAction.NAME), is(true)); - assertThat(role.cluster().check(GetJobsStatsAction.NAME), is(true)); - assertThat(role.cluster().check(GetModelSnapshotsAction.NAME), is(true)); - assertThat(role.cluster().check(GetRecordsAction.NAME), is(true)); - assertThat(role.cluster().check(IsolateDatafeedAction.NAME), is(false)); // internal use only - assertThat(role.cluster().check(KillProcessAction.NAME), is(false)); // internal use only - assertThat(role.cluster().check(OpenJobAction.NAME), is(true)); - assertThat(role.cluster().check(PostDataAction.NAME), is(true)); - assertThat(role.cluster().check(PreviewDatafeedAction.NAME), is(true)); - assertThat(role.cluster().check(PutDatafeedAction.NAME), is(true)); - assertThat(role.cluster().check(PutFilterAction.NAME), is(true)); - assertThat(role.cluster().check(PutJobAction.NAME), is(true)); - assertThat(role.cluster().check(RevertModelSnapshotAction.NAME), is(true)); - assertThat(role.cluster().check(StartDatafeedAction.NAME), is(true)); - assertThat(role.cluster().check(StopDatafeedAction.NAME), is(true)); - assertThat(role.cluster().check(UpdateDatafeedAction.NAME), is(true)); - assertThat(role.cluster().check(UpdateJobAction.NAME), is(true)); - assertThat(role.cluster().check(UpdateModelSnapshotAction.NAME), is(true)); - assertThat(role.cluster().check(UpdateProcessAction.NAME), is(false)); // internal use only - assertThat(role.cluster().check(ValidateDetectorAction.NAME), is(true)); - assertThat(role.cluster().check(ValidateJobConfigAction.NAME), is(true)); + assertThat(role.cluster().check(CloseJobAction.NAME, request), is(true)); + assertThat(role.cluster().check(DeleteDatafeedAction.NAME, request), is(true)); + assertThat(role.cluster().check(DeleteExpiredDataAction.NAME, request), is(true)); + assertThat(role.cluster().check(DeleteFilterAction.NAME, request), is(true)); + assertThat(role.cluster().check(DeleteJobAction.NAME, request), is(true)); + assertThat(role.cluster().check(DeleteModelSnapshotAction.NAME, request), is(true)); + assertThat(role.cluster().check(FinalizeJobExecutionAction.NAME, request), is(false)); // internal use only + assertThat(role.cluster().check(FlushJobAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetBucketsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetCategoriesAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetDatafeedsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetDatafeedsStatsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetFiltersAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetInfluencersAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetJobsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetJobsStatsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetModelSnapshotsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetRecordsAction.NAME, request), is(true)); + assertThat(role.cluster().check(IsolateDatafeedAction.NAME, request), is(false)); // internal use only + assertThat(role.cluster().check(KillProcessAction.NAME, request), is(false)); // internal use only + assertThat(role.cluster().check(OpenJobAction.NAME, request), is(true)); + assertThat(role.cluster().check(PostDataAction.NAME, request), is(true)); + assertThat(role.cluster().check(PreviewDatafeedAction.NAME, request), is(true)); + assertThat(role.cluster().check(PutDatafeedAction.NAME, request), is(true)); + assertThat(role.cluster().check(PutFilterAction.NAME, request), is(true)); + assertThat(role.cluster().check(PutJobAction.NAME, request), is(true)); + assertThat(role.cluster().check(RevertModelSnapshotAction.NAME, request), is(true)); + assertThat(role.cluster().check(StartDatafeedAction.NAME, request), is(true)); + assertThat(role.cluster().check(StopDatafeedAction.NAME, request), is(true)); + assertThat(role.cluster().check(UpdateDatafeedAction.NAME, request), is(true)); + assertThat(role.cluster().check(UpdateJobAction.NAME, request), is(true)); + assertThat(role.cluster().check(UpdateModelSnapshotAction.NAME, request), is(true)); + assertThat(role.cluster().check(UpdateProcessAction.NAME, request), is(false)); // internal use only + assertThat(role.cluster().check(ValidateDetectorAction.NAME, request), is(true)); + assertThat(role.cluster().check(ValidateJobConfigAction.NAME, request), is(true)); assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); assertNoAccessAllowed(role, "foo"); @@ -607,46 +634,48 @@ public void testMachineLearningAdminRole() { } public void testMachineLearningUserRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("machine_learning_user"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role role = Role.builder(roleDescriptor, null).build(); - assertThat(role.cluster().check(CloseJobAction.NAME), is(false)); - assertThat(role.cluster().check(DeleteDatafeedAction.NAME), is(false)); - assertThat(role.cluster().check(DeleteExpiredDataAction.NAME), is(false)); - assertThat(role.cluster().check(DeleteFilterAction.NAME), is(false)); - assertThat(role.cluster().check(DeleteJobAction.NAME), is(false)); - assertThat(role.cluster().check(DeleteModelSnapshotAction.NAME), is(false)); - assertThat(role.cluster().check(FinalizeJobExecutionAction.NAME), is(false)); - assertThat(role.cluster().check(FlushJobAction.NAME), is(false)); - assertThat(role.cluster().check(GetBucketsAction.NAME), is(true)); - assertThat(role.cluster().check(GetCategoriesAction.NAME), is(true)); - assertThat(role.cluster().check(GetDatafeedsAction.NAME), is(true)); - assertThat(role.cluster().check(GetDatafeedsStatsAction.NAME), is(true)); - assertThat(role.cluster().check(GetFiltersAction.NAME), is(false)); - assertThat(role.cluster().check(GetInfluencersAction.NAME), is(true)); - assertThat(role.cluster().check(GetJobsAction.NAME), is(true)); - assertThat(role.cluster().check(GetJobsStatsAction.NAME), is(true)); - assertThat(role.cluster().check(GetModelSnapshotsAction.NAME), is(true)); - assertThat(role.cluster().check(GetRecordsAction.NAME), is(true)); - assertThat(role.cluster().check(IsolateDatafeedAction.NAME), is(false)); - assertThat(role.cluster().check(KillProcessAction.NAME), is(false)); - assertThat(role.cluster().check(OpenJobAction.NAME), is(false)); - assertThat(role.cluster().check(PostDataAction.NAME), is(false)); - assertThat(role.cluster().check(PreviewDatafeedAction.NAME), is(false)); - assertThat(role.cluster().check(PutDatafeedAction.NAME), is(false)); - assertThat(role.cluster().check(PutFilterAction.NAME), is(false)); - assertThat(role.cluster().check(PutJobAction.NAME), is(false)); - assertThat(role.cluster().check(RevertModelSnapshotAction.NAME), is(false)); - assertThat(role.cluster().check(StartDatafeedAction.NAME), is(false)); - assertThat(role.cluster().check(StopDatafeedAction.NAME), is(false)); - assertThat(role.cluster().check(UpdateDatafeedAction.NAME), is(false)); - assertThat(role.cluster().check(UpdateJobAction.NAME), is(false)); - assertThat(role.cluster().check(UpdateModelSnapshotAction.NAME), is(false)); - assertThat(role.cluster().check(UpdateProcessAction.NAME), is(false)); - assertThat(role.cluster().check(ValidateDetectorAction.NAME), is(false)); - assertThat(role.cluster().check(ValidateJobConfigAction.NAME), is(false)); + assertThat(role.cluster().check(CloseJobAction.NAME, request), is(false)); + assertThat(role.cluster().check(DeleteDatafeedAction.NAME, request), is(false)); + assertThat(role.cluster().check(DeleteExpiredDataAction.NAME, request), is(false)); + assertThat(role.cluster().check(DeleteFilterAction.NAME, request), is(false)); + assertThat(role.cluster().check(DeleteJobAction.NAME, request), is(false)); + assertThat(role.cluster().check(DeleteModelSnapshotAction.NAME, request), is(false)); + assertThat(role.cluster().check(FinalizeJobExecutionAction.NAME, request), is(false)); + assertThat(role.cluster().check(FlushJobAction.NAME, request), is(false)); + assertThat(role.cluster().check(GetBucketsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetCategoriesAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetDatafeedsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetDatafeedsStatsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetFiltersAction.NAME, request), is(false)); + assertThat(role.cluster().check(GetInfluencersAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetJobsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetJobsStatsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetModelSnapshotsAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetRecordsAction.NAME, request), is(true)); + assertThat(role.cluster().check(IsolateDatafeedAction.NAME, request), is(false)); + assertThat(role.cluster().check(KillProcessAction.NAME, request), is(false)); + assertThat(role.cluster().check(OpenJobAction.NAME, request), is(false)); + assertThat(role.cluster().check(PostDataAction.NAME, request), is(false)); + assertThat(role.cluster().check(PreviewDatafeedAction.NAME, request), is(false)); + assertThat(role.cluster().check(PutDatafeedAction.NAME, request), is(false)); + assertThat(role.cluster().check(PutFilterAction.NAME, request), is(false)); + assertThat(role.cluster().check(PutJobAction.NAME, request), is(false)); + assertThat(role.cluster().check(RevertModelSnapshotAction.NAME, request), is(false)); + assertThat(role.cluster().check(StartDatafeedAction.NAME, request), is(false)); + assertThat(role.cluster().check(StopDatafeedAction.NAME, request), is(false)); + assertThat(role.cluster().check(UpdateDatafeedAction.NAME, request), is(false)); + assertThat(role.cluster().check(UpdateJobAction.NAME, request), is(false)); + assertThat(role.cluster().check(UpdateModelSnapshotAction.NAME, request), is(false)); + assertThat(role.cluster().check(UpdateProcessAction.NAME, request), is(false)); + assertThat(role.cluster().check(ValidateDetectorAction.NAME, request), is(false)); + assertThat(role.cluster().check(ValidateJobConfigAction.NAME, request), is(false)); assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); assertNoAccessAllowed(role, "foo"); @@ -657,19 +686,21 @@ public void testMachineLearningUserRole() { } public void testWatcherAdminRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("watcher_admin"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role role = Role.builder(roleDescriptor, null).build(); - assertThat(role.cluster().check(PutWatchAction.NAME), is(true)); - assertThat(role.cluster().check(GetWatchAction.NAME), is(true)); - assertThat(role.cluster().check(DeleteWatchAction.NAME), is(true)); - assertThat(role.cluster().check(ExecuteWatchAction.NAME), is(true)); - assertThat(role.cluster().check(AckWatchAction.NAME), is(true)); - assertThat(role.cluster().check(ActivateWatchAction.NAME), is(true)); - assertThat(role.cluster().check(WatcherServiceAction.NAME), is(true)); - assertThat(role.cluster().check(WatcherStatsAction.NAME), is(true)); + assertThat(role.cluster().check(PutWatchAction.NAME, request), is(true)); + assertThat(role.cluster().check(GetWatchAction.NAME, request), is(true)); + assertThat(role.cluster().check(DeleteWatchAction.NAME, request), is(true)); + assertThat(role.cluster().check(ExecuteWatchAction.NAME, request), is(true)); + assertThat(role.cluster().check(AckWatchAction.NAME, request), is(true)); + assertThat(role.cluster().check(ActivateWatchAction.NAME, request), is(true)); + assertThat(role.cluster().check(WatcherServiceAction.NAME, request), is(true)); + assertThat(role.cluster().check(WatcherStatsAction.NAME, request), is(true)); assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test("foo"), is(false)); @@ -682,19 +713,21 @@ public void testWatcherAdminRole() { } public void testWatcherUserRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("watcher_user"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role role = Role.builder(roleDescriptor, null).build(); - assertThat(role.cluster().check(PutWatchAction.NAME), is(false)); - assertThat(role.cluster().check(GetWatchAction.NAME), is(true)); - assertThat(role.cluster().check(DeleteWatchAction.NAME), is(false)); - assertThat(role.cluster().check(ExecuteWatchAction.NAME), is(false)); - assertThat(role.cluster().check(AckWatchAction.NAME), is(false)); - assertThat(role.cluster().check(ActivateWatchAction.NAME), is(false)); - assertThat(role.cluster().check(WatcherServiceAction.NAME), is(false)); - assertThat(role.cluster().check(WatcherStatsAction.NAME), is(true)); + assertThat(role.cluster().check(PutWatchAction.NAME, request), is(false)); + assertThat(role.cluster().check(GetWatchAction.NAME, request), is(true)); + assertThat(role.cluster().check(DeleteWatchAction.NAME, request), is(false)); + assertThat(role.cluster().check(ExecuteWatchAction.NAME, request), is(false)); + assertThat(role.cluster().check(AckWatchAction.NAME, request), is(false)); + assertThat(role.cluster().check(ActivateWatchAction.NAME, request), is(false)); + assertThat(role.cluster().check(WatcherServiceAction.NAME, request), is(false)); + assertThat(role.cluster().check(WatcherStatsAction.NAME, request), is(true)); assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); assertThat(role.indices().allowedIndicesMatcher(IndexAction.NAME).test("foo"), is(false)); @@ -732,15 +765,17 @@ private void assertNoAccessAllowed(Role role, String index) { } public void testLogstashAdminRole() { + final TransportRequest request = mock(TransportRequest.class); + RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("logstash_admin"); assertNotNull(roleDescriptor); assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true)); Role logstashAdminRole = Role.builder(roleDescriptor, null).build(); - assertThat(logstashAdminRole.cluster().check(ClusterHealthAction.NAME), is(false)); - assertThat(logstashAdminRole.cluster().check(PutIndexTemplateAction.NAME), is(false)); - assertThat(logstashAdminRole.cluster().check(ClusterRerouteAction.NAME), is(false)); - assertThat(logstashAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME), is(false)); + assertThat(logstashAdminRole.cluster().check(ClusterHealthAction.NAME, request), is(false)); + assertThat(logstashAdminRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false)); + assertThat(logstashAdminRole.cluster().check(ClusterRerouteAction.NAME, request), is(false)); + assertThat(logstashAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false)); assertThat(logstashAdminRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false)); diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java index 09de32643ed93..642bc167f7d4a 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java @@ -178,8 +178,8 @@ public void authorize(Authentication authentication, String action, TransportReq // first, we'll check if the action is a cluster action. If it is, we'll only check it against the cluster permissions if (ClusterPrivilege.ACTION_MATCHER.test(action)) { - ClusterPermission cluster = permission.cluster(); - if (cluster.check(action) || checkSameUserPermissions(action, request, authentication)) { + final ClusterPermission cluster = permission.cluster(); + if (cluster.check(action, request) || checkSameUserPermissions(action, request, authentication) ) { putTransientIfNonExisting(AuthorizationServiceField.INDICES_PERMISSIONS_KEY, IndicesAccessControl.ALLOW_ALL); auditTrail.accessGranted(authentication, action, request, permission.names()); return; diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealmIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealmIntegTests.java index 2b5f81cac0175..b7cd23745b932 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealmIntegTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/esnative/NativeRealmIntegTests.java @@ -22,6 +22,7 @@ import org.elasticsearch.test.NativeRealmIntegTestCase; import org.elasticsearch.test.SecuritySettingsSource; import org.elasticsearch.test.SecuritySettingsSourceField; +import org.elasticsearch.transport.TransportRequest; import org.elasticsearch.xpack.core.XPackFeatureSet; import org.elasticsearch.xpack.core.action.XPackUsageRequestBuilder; import org.elasticsearch.xpack.core.action.XPackUsageResponse; @@ -66,6 +67,7 @@ import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.mockito.Mockito.mock; /** * Tests for the NativeUsersStore and NativeRolesStore @@ -358,10 +360,11 @@ public void testCreateAndUpdateRole() { assertThat(e.status(), is(RestStatus.FORBIDDEN)); } } else { + final TransportRequest request = mock(TransportRequest.class); GetRolesResponse getRolesResponse = c.prepareGetRoles().names("test_role").get(); assertTrue("test_role does not exist!", getRolesResponse.hasRoles()); assertTrue("any cluster permission should be authorized", - Role.builder(getRolesResponse.roles()[0], null).build().cluster().check("cluster:admin/foo")); + Role.builder(getRolesResponse.roles()[0], null).build().cluster().check("cluster:admin/foo", request)); c.preparePutRole("test_role") .cluster("none") @@ -372,7 +375,7 @@ public void testCreateAndUpdateRole() { assertTrue("test_role does not exist!", getRolesResponse.hasRoles()); assertFalse("no cluster permission should be authorized", - Role.builder(getRolesResponse.roles()[0], null).build().cluster().check("cluster:admin/bar")); + Role.builder(getRolesResponse.roles()[0], null).build().cluster().check("cluster:admin/bar", request)); } } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/FileRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/FileRolesStoreTests.java index 14be1e260db36..1e2428e77791b 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/FileRolesStoreTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/FileRolesStoreTests.java @@ -16,6 +16,7 @@ import org.elasticsearch.test.ESTestCase; import org.elasticsearch.threadpool.TestThreadPool; import org.elasticsearch.threadpool.ThreadPool; +import org.elasticsearch.transport.TransportRequest; import org.elasticsearch.watcher.ResourceWatcherService; import org.elasticsearch.xpack.core.XPackSettings; import org.elasticsearch.xpack.core.security.audit.logfile.CapturingLogger; @@ -123,7 +124,7 @@ public void testParseFile() throws Exception { assertThat(role, notNullValue()); assertThat(role.names(), equalTo(new String[] { "role3" })); assertThat(role.cluster(), notNullValue()); - assertThat(role.cluster(), is(ClusterPermission.NONE)); + assertThat(role.cluster(), is(ClusterPermission.SimpleClusterPermission.NONE)); assertThat(role.indices(), notNullValue()); assertThat(role.indices().groups(), notNullValue()); assertThat(role.indices().groups().length, is(1)); @@ -147,7 +148,7 @@ public void testParseFile() throws Exception { assertThat(role, notNullValue()); assertThat(role.names(), equalTo(new String[] { "role_run_as" })); assertThat(role.cluster(), notNullValue()); - assertThat(role.cluster(), is(ClusterPermission.NONE)); + assertThat(role.cluster(), is(ClusterPermission.SimpleClusterPermission.NONE)); assertThat(role.indices(), is(IndicesPermission.NONE)); assertThat(role.runAs(), notNullValue()); assertThat(role.runAs().check("user1"), is(true)); @@ -160,7 +161,7 @@ public void testParseFile() throws Exception { assertThat(role, notNullValue()); assertThat(role.names(), equalTo(new String[] { "role_run_as1" })); assertThat(role.cluster(), notNullValue()); - assertThat(role.cluster(), is(ClusterPermission.NONE)); + assertThat(role.cluster(), is(ClusterPermission.SimpleClusterPermission.NONE)); assertThat(role.indices(), is(IndicesPermission.NONE)); assertThat(role.runAs(), notNullValue()); assertThat(role.runAs().check("user1"), is(true)); @@ -173,7 +174,7 @@ public void testParseFile() throws Exception { assertThat(role, notNullValue()); assertThat(role.names(), equalTo(new String[] { "role_fields" })); assertThat(role.cluster(), notNullValue()); - assertThat(role.cluster(), is(ClusterPermission.NONE)); + assertThat(role.cluster(), is(ClusterPermission.SimpleClusterPermission.NONE)); assertThat(role.runAs(), is(RunAsPermission.NONE)); assertThat(role.indices(), notNullValue()); assertThat(role.indices().groups(), notNullValue()); @@ -195,7 +196,7 @@ public void testParseFile() throws Exception { assertThat(role, notNullValue()); assertThat(role.names(), equalTo(new String[] { "role_query" })); assertThat(role.cluster(), notNullValue()); - assertThat(role.cluster(), is(ClusterPermission.NONE)); + assertThat(role.cluster(), is(ClusterPermission.SimpleClusterPermission.NONE)); assertThat(role.runAs(), is(RunAsPermission.NONE)); assertThat(role.indices(), notNullValue()); assertThat(role.indices().groups(), notNullValue()); @@ -216,7 +217,7 @@ public void testParseFile() throws Exception { assertThat(role, notNullValue()); assertThat(role.names(), equalTo(new String[] { "role_query_fields" })); assertThat(role.cluster(), notNullValue()); - assertThat(role.cluster(), is(ClusterPermission.NONE)); + assertThat(role.cluster(), is(ClusterPermission.SimpleClusterPermission.NONE)); assertThat(role.runAs(), is(RunAsPermission.NONE)); assertThat(role.indices(), notNullValue()); assertThat(role.indices().groups(), notNullValue()); @@ -341,14 +342,15 @@ public void testAutoReload() throws Exception { fail("Waited too long for the updated file to be picked up"); } + final TransportRequest request = mock(TransportRequest.class); descriptors = store.roleDescriptors(Collections.singleton("role5")); assertThat(descriptors, notNullValue()); assertEquals(1, descriptors.size()); Role role = Role.builder(descriptors.iterator().next(), null).build(); assertThat(role, notNullValue()); assertThat(role.names(), equalTo(new String[] { "role5" })); - assertThat(role.cluster().check("cluster:monitor/foo/bar"), is(true)); - assertThat(role.cluster().check("cluster:admin/foo/bar"), is(false)); + assertThat(role.cluster().check("cluster:monitor/foo/bar", request), is(true)); + assertThat(role.cluster().check("cluster:admin/foo/bar", request), is(false)); } finally { if (watcherService != null) {