|
@@ -64,6 +64,7 @@ import org.elasticsearch.cluster.metadata.Metadata;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.util.set.Sets;
|
|
|
import org.elasticsearch.test.ESTestCase;
|
|
|
+import org.elasticsearch.transport.TcpTransport;
|
|
|
import org.elasticsearch.transport.TransportRequest;
|
|
|
import org.elasticsearch.xpack.core.XPackPlugin;
|
|
|
import org.elasticsearch.xpack.core.action.XPackInfoAction;
|
|
@@ -180,6 +181,7 @@ import org.elasticsearch.xpack.core.security.authc.AuthenticationTestHelper;
|
|
|
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
|
|
|
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.RemoteIndicesPermission;
|
|
|
import org.elasticsearch.xpack.core.security.authz.permission.Role;
|
|
|
import org.elasticsearch.xpack.core.security.authz.privilege.ApplicationPrivilegeDescriptor;
|
|
|
import org.elasticsearch.xpack.core.security.authz.privilege.ApplicationPrivilegeTests;
|
|
@@ -213,6 +215,7 @@ import org.elasticsearch.xpack.core.watcher.transport.actions.service.WatcherSer
|
|
|
import org.elasticsearch.xpack.core.watcher.transport.actions.stats.WatcherStatsAction;
|
|
|
import org.elasticsearch.xpack.core.watcher.watch.Watch;
|
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.Collection;
|
|
|
import java.util.Collections;
|
|
@@ -222,6 +225,10 @@ import java.util.Set;
|
|
|
import java.util.SortedMap;
|
|
|
|
|
|
import static org.elasticsearch.xpack.core.security.test.TestRestrictedIndices.RESTRICTED_INDICES;
|
|
|
+import static org.hamcrest.Matchers.containsInAnyOrder;
|
|
|
+import static org.hamcrest.Matchers.emptyArray;
|
|
|
+import static org.hamcrest.Matchers.emptyIterable;
|
|
|
+import static org.hamcrest.Matchers.equalTo;
|
|
|
import static org.hamcrest.Matchers.hasEntry;
|
|
|
import static org.hamcrest.Matchers.is;
|
|
|
import static org.hamcrest.Matchers.not;
|
|
@@ -2963,6 +2970,74 @@ public class ReservedRolesStoreTests extends ESTestCase {
|
|
|
assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 20)), is(false));
|
|
|
}
|
|
|
|
|
|
+ public void testRemoteIndicesPrivilegesForSuperuserRole() {
|
|
|
+ final RoleDescriptor superuserRoleDescriptor = new ReservedRolesStore().roleDescriptor("superuser");
|
|
|
+ final Role superuserRole = Role.buildFromRoleDescriptor(
|
|
|
+ superuserRoleDescriptor,
|
|
|
+ new FieldPermissionsCache(Settings.EMPTY),
|
|
|
+ RESTRICTED_INDICES
|
|
|
+ );
|
|
|
+
|
|
|
+ if (TcpTransport.isUntrustedRemoteClusterEnabled()) {
|
|
|
+ assertThat(superuserRoleDescriptor.hasRemoteIndicesPrivileges(), is(true));
|
|
|
+ assertThat(
|
|
|
+ Arrays.stream(superuserRoleDescriptor.getRemoteIndicesPrivileges())
|
|
|
+ .map(RoleDescriptor.RemoteIndicesPrivileges::indicesPrivileges)
|
|
|
+ .toArray(RoleDescriptor.IndicesPrivileges[]::new),
|
|
|
+ equalTo(superuserRoleDescriptor.getIndicesPrivileges())
|
|
|
+ );
|
|
|
+ final List<RemoteIndicesPermission.RemoteIndicesGroup> remoteIndicesGroups = superuserRole.remoteIndices()
|
|
|
+ .remoteIndicesGroups();
|
|
|
+ assertThat(remoteIndicesGroups.size(), equalTo(1));
|
|
|
+ assertThat(remoteIndicesGroups.get(0).remoteClusterAliasMatcher().isTotal(), is(true));
|
|
|
+ } else {
|
|
|
+ assertThat(superuserRoleDescriptor.hasRemoteIndicesPrivileges(), is(false));
|
|
|
+ assertThat(superuserRoleDescriptor.getRemoteIndicesPrivileges(), emptyArray());
|
|
|
+ assertThat(superuserRole.remoteIndices(), is(RemoteIndicesPermission.NONE));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testRemoteIndicesPrivileges() {
|
|
|
+ final List<String> rolesWithRemoteIndicesPrivileges = new ArrayList<>();
|
|
|
+
|
|
|
+ for (RoleDescriptor roleDescriptor : new ReservedRolesStore().roleDescriptors()) {
|
|
|
+ if (roleDescriptor.getName().equals("superuser")) {
|
|
|
+ continue; // superuser is tested separately
|
|
|
+ }
|
|
|
+ final Role role = Role.buildFromRoleDescriptor(roleDescriptor, new FieldPermissionsCache(Settings.EMPTY), RESTRICTED_INDICES);
|
|
|
+
|
|
|
+ if (TcpTransport.isUntrustedRemoteClusterEnabled()) {
|
|
|
+ // The assumption here is that any read_cross_cluster indices privileges should be paired with
|
|
|
+ // a corresponding remote indices privileges
|
|
|
+ final var readCrossClusterIndicesPrivileges = Arrays.stream(roleDescriptor.getIndicesPrivileges())
|
|
|
+ .filter(ip -> Arrays.asList(ip.getPrivileges()).contains("read_cross_cluster"))
|
|
|
+ .toArray(RoleDescriptor.IndicesPrivileges[]::new);
|
|
|
+ if (readCrossClusterIndicesPrivileges.length == 0) {
|
|
|
+ assertThat(roleDescriptor.hasRemoteIndicesPrivileges(), is(false));
|
|
|
+ } else {
|
|
|
+ assertThat(roleDescriptor.hasRemoteIndicesPrivileges(), is(true));
|
|
|
+ assertThat(
|
|
|
+ Arrays.stream(roleDescriptor.getRemoteIndicesPrivileges())
|
|
|
+ .map(RoleDescriptor.RemoteIndicesPrivileges::indicesPrivileges)
|
|
|
+ .toList(),
|
|
|
+ containsInAnyOrder(readCrossClusterIndicesPrivileges)
|
|
|
+ );
|
|
|
+ rolesWithRemoteIndicesPrivileges.add(roleDescriptor.getName());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ assertThat(roleDescriptor.hasRemoteIndicesPrivileges(), is(false));
|
|
|
+ assertThat(roleDescriptor.getRemoteIndicesPrivileges(), emptyArray());
|
|
|
+ assertThat(role.remoteIndices(), is(RemoteIndicesPermission.NONE));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (TcpTransport.isUntrustedRemoteClusterEnabled()) {
|
|
|
+ assertThat(rolesWithRemoteIndicesPrivileges, containsInAnyOrder("kibana_system", "monitoring_user"));
|
|
|
+ } else {
|
|
|
+ assertThat(rolesWithRemoteIndicesPrivileges, emptyIterable());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private void assertAllIndicesAccessAllowed(Role role, String index) {
|
|
|
logger.info("index name [{}]", index);
|
|
|
assertThat(role.indices().allowedIndicesMatcher("indices:foo").test(mockIndexAbstraction(index)), is(true));
|