diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java index 876d990360da0..36e2b8bbc46da 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java @@ -7,6 +7,10 @@ import org.elasticsearch.Version; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsAction; +import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; +import org.elasticsearch.action.get.GetAction; +import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.cluster.metadata.IndexMetaData; @@ -22,18 +26,23 @@ import org.elasticsearch.license.TestUtils.UpdatableLicenseState; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.transport.TransportRequest; import org.elasticsearch.xpack.core.XPackSettings; +import org.elasticsearch.xpack.core.security.action.user.PutUserAction; import org.elasticsearch.xpack.core.security.authz.RoleDescriptor; import org.elasticsearch.xpack.core.security.authz.RoleDescriptor.IndicesPrivileges; import org.elasticsearch.xpack.core.security.authz.accesscontrol.IndicesAccessControl; import org.elasticsearch.xpack.core.security.authz.permission.FieldPermissionsCache; import org.elasticsearch.xpack.core.security.authz.permission.Role; +import org.elasticsearch.xpack.core.security.authz.privilege.ApplicationPrivilege; +import org.elasticsearch.xpack.core.security.authz.privilege.ApplicationPrivilegeDescriptor; import org.elasticsearch.xpack.core.security.authz.privilege.IndexPrivilege; import org.elasticsearch.xpack.core.security.authz.store.ReservedRolesStore; import org.elasticsearch.xpack.security.support.SecurityIndexManager; import java.io.IOException; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Map; @@ -42,6 +51,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiConsumer; import java.util.function.Function; +import java.util.function.Predicate; import static org.elasticsearch.mock.orig.Mockito.times; import static org.elasticsearch.mock.orig.Mockito.verifyNoMoreInteractions; @@ -347,6 +357,100 @@ public void testMergingRolesWithFls() { assertTrue(acls.get("test").getFieldPermissions().grantsAccessTo("L3.foo")); } + public void testMergingBasicRoles() { + RoleDescriptor role1 = new RoleDescriptor("r1", new String[]{"monitor"}, new IndicesPrivileges[]{ + IndicesPrivileges.builder() + .indices("abc-*", "xyz-*") + .privileges("read") + .build(), + IndicesPrivileges.builder() + .indices("ind-1-*") + .privileges("all") + .build(), + }, new RoleDescriptor.ApplicationResourcePrivileges[]{ + RoleDescriptor.ApplicationResourcePrivileges.builder() + .application("app1") + .resources("user/*") + .privileges("read", "write") + .build(), + RoleDescriptor.ApplicationResourcePrivileges.builder() + .application("app1") + .resources("settings/*") + .privileges("read") + .build() + }, + new String[]{"app-user-1"}, null, null); + + RoleDescriptor role2 = new RoleDescriptor("r2", new String[]{"manage"}, new IndicesPrivileges[]{ + IndicesPrivileges.builder() + .indices("abc-*", "ind-2-*") + .privileges("all") + .build() + }, new RoleDescriptor.ApplicationResourcePrivileges[]{ + RoleDescriptor.ApplicationResourcePrivileges.builder() + .application("app2a") + .resources("*") + .privileges("all") + .build(), + RoleDescriptor.ApplicationResourcePrivileges.builder() + .application("app2b") + .resources("*") + .privileges("read") + .build() + }, + new String[]{"app-user-2"}, null, null); + + FieldPermissionsCache cache = new FieldPermissionsCache(Settings.EMPTY); + PlainActionFuture future = new PlainActionFuture<>(); + final NativePrivilegeStore privilegeStore = mock(NativePrivilegeStore.class); + doAnswer(inv -> { + assertTrue(inv.getArguments().length == 3); + ActionListener> listener + = (ActionListener>) inv.getArguments()[2]; + Set set = new HashSet<>(); + Arrays.asList("app1", "app2a", "app2b").forEach( + app -> Arrays.asList("read", "write", "all").forEach( + perm -> set.add( + new ApplicationPrivilegeDescriptor(app, perm, Collections.emptySet(), Collections.emptyMap()) + ))); + listener.onResponse(set); + return null; + }).when(privilegeStore).getPrivileges(any(Collection.class), any(Collection.class), any(ActionListener.class)); + CompositeRolesStore.buildRoleFromDescriptors(Sets.newHashSet(role1, role2), cache, privilegeStore, future); + Role role = future.actionGet(); + + final TransportRequest request = mock(TransportRequest.class); + + assertThat(role.cluster().check(ClusterStateAction.NAME, request), equalTo(true)); + assertThat(role.cluster().check(ClusterUpdateSettingsAction.NAME, request), equalTo(true)); + assertThat(role.cluster().check(PutUserAction.NAME, request), equalTo(false)); + + final Predicate allowedRead = role.indices().allowedIndicesMatcher(GetAction.NAME); + assertThat(allowedRead.test("abc-123"), equalTo(true)); + assertThat(allowedRead.test("xyz-000"), equalTo(true)); + assertThat(allowedRead.test("ind-1-a"), equalTo(true)); + assertThat(allowedRead.test("ind-2-a"), equalTo(true)); + assertThat(allowedRead.test("foo"), equalTo(false)); + assertThat(allowedRead.test("abc"), equalTo(false)); + assertThat(allowedRead.test("xyz"), equalTo(false)); + assertThat(allowedRead.test("ind-3-a"), equalTo(false)); + + final Predicate allowedWrite = role.indices().allowedIndicesMatcher(IndexAction.NAME); + assertThat(allowedWrite.test("abc-123"), equalTo(true)); + assertThat(allowedWrite.test("xyz-000"), equalTo(false)); + assertThat(allowedWrite.test("ind-1-a"), equalTo(true)); + assertThat(allowedWrite.test("ind-2-a"), equalTo(true)); + assertThat(allowedWrite.test("foo"), equalTo(false)); + assertThat(allowedWrite.test("abc"), equalTo(false)); + assertThat(allowedWrite.test("xyz"), equalTo(false)); + assertThat(allowedWrite.test("ind-3-a"), equalTo(false)); + + role.application().grants(new ApplicationPrivilege("app1", "app1-read", "write"), "user/joe"); + role.application().grants(new ApplicationPrivilege("app1", "app1-read", "read"), "settings/hostname"); + role.application().grants(new ApplicationPrivilege("app2a", "app2a-all", "all"), "user/joe"); + role.application().grants(new ApplicationPrivilege("app2b", "app2b-read", "read"), "settings/hostname"); + } + public void testCustomRolesProviderFailures() throws Exception { final FileRolesStore fileRolesStore = mock(FileRolesStore.class); when(fileRolesStore.roleDescriptors(anySetOf(String.class))).thenReturn(Collections.emptySet());