Create snapshot role (#35820)

This commit introduces the `create_snapshot` cluster privilege and
the `snapshot_user` role.
This role is to be used by "cronable" tools that call the snapshot API
periodically without recurring to the `manage` cluster privilege. The
`create_snapshot` cluster privilege is much more limited compared to
the `manage` privilege.

The `snapshot_user` role grants the privileges to view the metadata of
all indices (including restricted ones, i.e. .security). It obviously grants the
create snapshot privilege but the repository has to be created using another
role. In addition, it grants the privileges to (only) GET repositories and
snapshots, but not create and delete them.

The role does not allow to create repositories. This distinction is important
because snapshotting equates to the `read` index privilege if the user has
control of the snapshot destination, but this is not the case in this instance,
because the role does not grant control over repository configuration.
This commit is contained in:
Albert Zaharovits 2019-01-27 23:07:32 +02:00 committed by GitHub
parent f24dce1122
commit 66ddd8d2f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 229 additions and 8 deletions

View File

@ -638,8 +638,8 @@ public class SecurityDocumentationIT extends ESRestHighLevelClientTestCase {
List<Role> roles = response.getRoles();
assertNotNull(response);
// 23 system roles plus the three we created
assertThat(roles.size(), equalTo(26));
// 24 system roles plus the three we created
assertThat(roles.size(), equalTo(27));
}
{

View File

@ -6,6 +6,10 @@
package org.elasticsearch.xpack.core.security.authz.privilege;
import org.apache.lucene.util.automaton.Automaton;
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesAction;
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotAction;
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsAction;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusAction;
import org.elasticsearch.action.admin.cluster.state.ClusterStateAction;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.MapBuilder;
@ -48,6 +52,8 @@ public final class ClusterPrivilege extends Privilege {
private static final Automaton MANAGE_ROLLUP_AUTOMATON = patterns("cluster:admin/xpack/rollup/*", "cluster:monitor/xpack/rollup/*");
private static final Automaton MANAGE_CCR_AUTOMATON =
patterns("cluster:admin/xpack/ccr/*", ClusterStateAction.NAME, HasPrivilegesAction.NAME);
private static final Automaton CREATE_SNAPSHOT_AUTOMATON = patterns(CreateSnapshotAction.NAME, SnapshotsStatusAction.NAME + "*",
GetSnapshotsAction.NAME, SnapshotsStatusAction.NAME, GetRepositoriesAction.NAME);
private static final Automaton READ_CCR_AUTOMATON = patterns(ClusterStateAction.NAME, HasPrivilegesAction.NAME);
private static final Automaton MANAGE_ILM_AUTOMATON = patterns("cluster:admin/ilm/*");
private static final Automaton READ_ILM_AUTOMATON = patterns(GetLifecycleAction.NAME, GetStatusAction.NAME);
@ -73,6 +79,7 @@ public final class ClusterPrivilege extends Privilege {
public static final ClusterPrivilege MANAGE_PIPELINE = new ClusterPrivilege("manage_pipeline", "cluster:admin/ingest/pipeline/*");
public static final ClusterPrivilege MANAGE_CCR = new ClusterPrivilege("manage_ccr", MANAGE_CCR_AUTOMATON);
public static final ClusterPrivilege READ_CCR = new ClusterPrivilege("read_ccr", READ_CCR_AUTOMATON);
public static final ClusterPrivilege CREATE_SNAPSHOT = new ClusterPrivilege("create_snapshot", CREATE_SNAPSHOT_AUTOMATON);
public static final ClusterPrivilege MANAGE_ILM = new ClusterPrivilege("manage_ilm", MANAGE_ILM_AUTOMATON);
public static final ClusterPrivilege READ_ILM = new ClusterPrivilege("read_ilm", READ_ILM_AUTOMATON);
@ -98,6 +105,7 @@ public final class ClusterPrivilege extends Privilege {
.put("manage_rollup", MANAGE_ROLLUP)
.put("manage_ccr", MANAGE_CCR)
.put("read_ccr", READ_CCR)
.put("create_snapshot", CREATE_SNAPSHOT)
.put("manage_ilm", MANAGE_ILM)
.put("read_ilm", READ_ILM)
.immutableMap();

View File

@ -64,8 +64,8 @@ public final class IndexPrivilege extends Privilege {
CloseIndexAction.NAME + "*");
private static final Automaton MANAGE_ILM_AUTOMATON = patterns("indices:admin/ilm/*");
public static final IndexPrivilege NONE = new IndexPrivilege("none", Automatons.EMPTY);
public static final IndexPrivilege ALL = new IndexPrivilege("all", ALL_AUTOMATON);
public static final IndexPrivilege NONE = new IndexPrivilege("none", Automatons.EMPTY);
public static final IndexPrivilege ALL = new IndexPrivilege("all", ALL_AUTOMATON);
public static final IndexPrivilege READ = new IndexPrivilege("read", READ_AUTOMATON);
public static final IndexPrivilege READ_CROSS_CLUSTER = new IndexPrivilege("read_cross_cluster", READ_CROSS_CLUSTER_AUTOMATON);
public static final IndexPrivilege CREATE = new IndexPrivilege("create", CREATE_AUTOMATON);

View File

@ -6,6 +6,7 @@
package org.elasticsearch.xpack.core.security.authz.store;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesAction;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.xpack.core.monitoring.action.MonitoringBulkAction;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
@ -179,6 +180,12 @@ public class ReservedRolesStore implements BiConsumer<Set<String>, ActionListene
RoleDescriptor.IndicesPrivileges.builder()
.indices(".code-*").privileges("read").build()
}, null, MetadataUtils.DEFAULT_RESERVED_METADATA))
.put("snapshot_user", new RoleDescriptor("snapshot_user", new String[] { "create_snapshot", GetRepositoriesAction.NAME },
new RoleDescriptor.IndicesPrivileges[] { RoleDescriptor.IndicesPrivileges.builder()
.indices("*")
.privileges("view_index_metadata")
.allowRestrictedIndices(true)
.build() }, null, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, null))
.immutableMap();
}

View File

@ -7,8 +7,13 @@ package org.elasticsearch.xpack.core.security.authz.store;
import org.elasticsearch.Version;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthAction;
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesAction;
import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryAction;
import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteAction;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsAction;
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotAction;
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsAction;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusAction;
import org.elasticsearch.action.admin.cluster.state.ClusterStateAction;
import org.elasticsearch.action.admin.cluster.stats.ClusterStatsAction;
import org.elasticsearch.action.admin.indices.create.CreateIndexAction;
@ -173,9 +178,54 @@ public class ReservedRolesStoreTests extends ESTestCase {
assertThat(ReservedRolesStore.isReserved(APMSystemUser.ROLE_NAME), is(true));
assertThat(ReservedRolesStore.isReserved(RemoteMonitoringUser.COLLECTION_ROLE_NAME), is(true));
assertThat(ReservedRolesStore.isReserved(RemoteMonitoringUser.INDEXING_ROLE_NAME), is(true));
assertThat(ReservedRolesStore.isReserved("snapshot_user"), is(true));
assertThat(ReservedRolesStore.isReserved("code_admin"), is(true));
assertThat(ReservedRolesStore.isReserved("code_user"), is(true));
}
public void testSnapshotUserRole() {
final TransportRequest request = mock(TransportRequest.class);
RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("snapshot_user");
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
Role snapshotUserRole = Role.builder(roleDescriptor, null).build();
assertThat(snapshotUserRole.cluster().check(GetRepositoriesAction.NAME, request), is(true));
assertThat(snapshotUserRole.cluster().check(CreateSnapshotAction.NAME, request), is(true));
assertThat(snapshotUserRole.cluster().check(SnapshotsStatusAction.NAME, request), is(true));
assertThat(snapshotUserRole.cluster().check(GetSnapshotsAction.NAME, request), is(true));
assertThat(snapshotUserRole.cluster().check(PutRepositoryAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(GetIndexTemplatesAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(DeleteIndexTemplateAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(PutPipelineAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(GetPipelineAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(DeletePipelineAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(ClusterRerouteAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(MonitoringBulkAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(GetWatchAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(PutWatchAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(DeleteWatchAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(ExecuteWatchAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(AckWatchAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(ActivateWatchAction.NAME, request), is(false));
assertThat(snapshotUserRole.cluster().check(WatcherServiceAction.NAME, request), is(false));
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(randomAlphaOfLengthBetween(8, 24)), is(false));
assertThat(snapshotUserRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)), is(false));
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetAction.NAME).test(randomAlphaOfLengthBetween(8, 24)), is(false));
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetAction.NAME).test(randomAlphaOfLengthBetween(8, 24)), is(false));
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME)
.test(randomAlphaOfLengthBetween(8, 24)), is(true));
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME)
.test(RestrictedIndicesNames.INTERNAL_SECURITY_INDEX), is(true));
assertThat(snapshotUserRole.indices().allowedIndicesMatcher(GetIndexAction.NAME)
.test(RestrictedIndicesNames.SECURITY_INDEX_NAME), is(true));
assertNoAccessAllowed(snapshotUserRole, RestrictedIndicesNames.NAMES_SET);
}
public void testIngestAdminRole() {

View File

@ -32,12 +32,15 @@ public class ClusterPrivilegeTests extends AbstractPrivilegeTestCase {
"role_c:\n" +
" indices:\n" +
" - names: 'someindex'\n" +
" privileges: [ all ]\n";
" privileges: [ all ]\n" +
"role_d:\n" +
" cluster: [ create_snapshot ]\n";
private static final String USERS_ROLES =
"role_a:user_a\n" +
"role_b:user_b\n" +
"role_c:user_c\n";
"role_c:user_c\n" +
"role_d:user_d\n";
private static Path repositoryLocation;
@ -75,8 +78,8 @@ public class ClusterPrivilegeTests extends AbstractPrivilegeTestCase {
return super.configUsers() +
"user_a:" + usersPasswdHashed + "\n" +
"user_b:" + usersPasswdHashed + "\n" +
"user_c:" + usersPasswdHashed + "\n";
"user_c:" + usersPasswdHashed + "\n" +
"user_d:" + usersPasswdHashed + "\n";
}
@Override
@ -122,6 +125,18 @@ public class ClusterPrivilegeTests extends AbstractPrivilegeTestCase {
assertAccessIsDenied("user_c", "GET", "/_nodes/infos");
assertAccessIsDenied("user_c", "POST", "/_cluster/reroute");
assertAccessIsDenied("user_c", "PUT", "/_cluster/settings", "{ \"transient\" : { \"search.default_search_timeout\": \"1m\" } }");
// user_d can view repos and create and view snapshots on existings repos, everything else is DENIED
assertAccessIsDenied("user_d", "GET", "/_cluster/state");
assertAccessIsDenied("user_d", "GET", "/_cluster/health");
assertAccessIsDenied("user_d", "GET", "/_cluster/settings");
assertAccessIsDenied("user_d", "GET", "/_cluster/stats");
assertAccessIsDenied("user_d", "GET", "/_cluster/pending_tasks");
assertAccessIsDenied("user_d", "GET", "/_nodes/stats");
assertAccessIsDenied("user_d", "GET", "/_nodes/hot_threads");
assertAccessIsDenied("user_d", "GET", "/_nodes/infos");
assertAccessIsDenied("user_d", "POST", "/_cluster/reroute");
assertAccessIsDenied("user_d", "PUT", "/_cluster/settings", "{ \"transient\" : { \"search.default_search_timeout\": \"1m\" } }");
}
public void testThatSnapshotAndRestore() throws Exception {
@ -129,6 +144,7 @@ public class ClusterPrivilegeTests extends AbstractPrivilegeTestCase {
repositoryLocation.toString()).endObject().endObject());
assertAccessIsDenied("user_b", "PUT", "/_snapshot/my-repo", repoJson);
assertAccessIsDenied("user_c", "PUT", "/_snapshot/my-repo", repoJson);
assertAccessIsDenied("user_d", "PUT", "/_snapshot/my-repo", repoJson);
assertAccessIsAllowed("user_a", "PUT", "/_snapshot/my-repo", repoJson);
Request createBar = new Request("PUT", "/someindex/bar/1");
@ -136,6 +152,7 @@ public class ClusterPrivilegeTests extends AbstractPrivilegeTestCase {
createBar.addParameter("refresh", "true");
assertAccessIsDenied("user_a", createBar);
assertAccessIsDenied("user_b", createBar);
assertAccessIsDenied("user_d", createBar);
assertAccessIsAllowed("user_c", createBar);
assertAccessIsDenied("user_b", "PUT", "/_snapshot/my-repo/my-snapshot", "{ \"indices\": \"someindex\" }");
@ -145,30 +162,38 @@ public class ClusterPrivilegeTests extends AbstractPrivilegeTestCase {
assertAccessIsDenied("user_b", "GET", "/_snapshot/my-repo/my-snapshot/_status");
assertAccessIsDenied("user_c", "GET", "/_snapshot/my-repo/my-snapshot/_status");
assertAccessIsAllowed("user_a", "GET", "/_snapshot/my-repo/my-snapshot/_status");
assertAccessIsAllowed("user_d", "GET", "/_snapshot/my-repo/my-snapshot/_status");
// This snapshot needs to be finished in order to be restored
waitForSnapshotToFinish("my-repo", "my-snapshot");
// user_d can create snapshots, but not concurrently
assertAccessIsAllowed("user_d", "PUT", "/_snapshot/my-repo/my-snapshot-d", "{ \"indices\": \"someindex\" }");
assertAccessIsDenied("user_a", "DELETE", "/someindex");
assertAccessIsDenied("user_b", "DELETE", "/someindex");
assertAccessIsDenied("user_d", "DELETE", "/someindex");
assertAccessIsAllowed("user_c", "DELETE", "/someindex");
Request restoreSnapshotRequest = new Request("POST", "/_snapshot/my-repo/my-snapshot/_restore");
restoreSnapshotRequest.addParameter("wait_for_completion", "true");
assertAccessIsDenied("user_b", restoreSnapshotRequest);
assertAccessIsDenied("user_c", restoreSnapshotRequest);
assertAccessIsDenied("user_d", restoreSnapshotRequest);
assertAccessIsAllowed("user_a", restoreSnapshotRequest);
assertAccessIsDenied("user_a", "GET", "/someindex/bar/1");
assertAccessIsDenied("user_b", "GET", "/someindex/bar/1");
assertAccessIsDenied("user_d", "GET", "/someindex/bar/1");
assertAccessIsAllowed("user_c", "GET", "/someindex/bar/1");
assertAccessIsDenied("user_b", "DELETE", "/_snapshot/my-repo/my-snapshot");
assertAccessIsDenied("user_c", "DELETE", "/_snapshot/my-repo/my-snapshot");
assertAccessIsDenied("user_d", "DELETE", "/_snapshot/my-repo/my-snapshot");
assertAccessIsAllowed("user_a", "DELETE", "/_snapshot/my-repo/my-snapshot");
assertAccessIsDenied("user_b", "DELETE", "/_snapshot/my-repo");
assertAccessIsDenied("user_c", "DELETE", "/_snapshot/my-repo");
assertAccessIsDenied("user_d", "DELETE", "/_snapshot/my-repo");
assertAccessIsAllowed("user_a", "DELETE", "/_snapshot/my-repo");
}

View File

@ -0,0 +1,131 @@
/*
* 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.xpack.security.authz;
import org.elasticsearch.action.admin.cluster.repositories.get.GetRepositoriesResponse;
import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.snapshots.SnapshotState;
import org.elasticsearch.test.NativeRealmIntegTestCase;
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
import org.junit.Before;
import java.util.Arrays;
import java.util.Collections;
import java.util.Locale;
import static org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames.INTERNAL_SECURITY_INDEX;
import static org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames.SECURITY_INDEX_NAME;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationException;
public class SnapshotUserRoleIntegTests extends NativeRealmIntegTestCase {
private Client client;
private String ordinaryIndex;
@Before
public void setupClusterBeforeSnapshot() {
logger.info("--> creating repository");
assertAcked(client().admin().cluster().preparePutRepository("repo")
.setType("fs")
.setSettings(Settings.builder().put("location", randomRepoPath())));
logger.info("--> creating ordinary index");
final int shards = between(1, 10);
ordinaryIndex = randomAlphaOfLength(4).toLowerCase(Locale.ROOT);
assertAcked(prepareCreate(ordinaryIndex, 0, Settings.builder().put("number_of_shards", shards).put("number_of_replicas", 0)));
ensureGreen();
logger.info("--> creating snapshot_user user");
final String user = "snapshot_user";
final char[] password = new char[] {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'};
final String snapshotUserToken = basicAuthHeaderValue(user, new SecureString(password));
client = client().filterWithHeader(Collections.singletonMap("Authorization", snapshotUserToken));
securityClient().preparePutUser(user, password, Hasher.BCRYPT, "snapshot_user").get();
ensureGreen(INTERNAL_SECURITY_INDEX);
}
public void testSnapshotUserRoleCanSnapshotAndSeeAllIndices() {
// view repositories
final GetRepositoriesResponse getRepositoriesResponse = client.admin().cluster().prepareGetRepositories(randomFrom("*", "_all"))
.get();
assertThat(getRepositoriesResponse.repositories().size(), is(1));
assertThat(getRepositoriesResponse.repositories().get(0).name(), is("repo"));
// view all indices, including restricted ones
final GetIndexResponse getIndexResponse = client.admin().indices().prepareGetIndex().setIndices(randomFrom("_all", "*")).get();
assertThat(Arrays.asList(getIndexResponse.indices()), containsInAnyOrder(INTERNAL_SECURITY_INDEX, ordinaryIndex));
// create snapshot that includes restricted indices
final CreateSnapshotResponse snapshotResponse = client.admin().cluster().prepareCreateSnapshot("repo", "snap")
.setIndices(randomFrom("_all", "*")).setWaitForCompletion(true).get();
assertThat(snapshotResponse.getSnapshotInfo().state(), is(SnapshotState.SUCCESS));
assertThat(snapshotResponse.getSnapshotInfo().indices(), containsInAnyOrder(INTERNAL_SECURITY_INDEX, ordinaryIndex));
// view snapshots for repo
final GetSnapshotsResponse getSnapshotResponse = client.admin().cluster().prepareGetSnapshots("repo").get();
assertThat(getSnapshotResponse.getSnapshots().size(), is(1));
assertThat(getSnapshotResponse.getSnapshots().get(0).snapshotId().getName(), is("snap"));
assertThat(getSnapshotResponse.getSnapshots().get(0).indices(), containsInAnyOrder(INTERNAL_SECURITY_INDEX, ordinaryIndex));
}
public void testSnapshotUserRoleIsReserved() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> securityClient().preparePutRole("snapshot_user").get());
assertThat(e.getMessage(), containsString("role [snapshot_user] is reserved and cannot be modified"));
e = expectThrows(IllegalArgumentException.class,
() -> securityClient().prepareDeleteRole("snapshot_user").get());
assertThat(e.getMessage(), containsString("role [snapshot_user] is reserved and cannot be deleted"));
}
public void testSnapshotUserRoleUnathorizedForDestructiveActions() {
// try search all
assertThrowsAuthorizationException(() -> client.prepareSearch(randomFrom("_all", "*")).get(), "indices:data/read/search",
"snapshot_user");
// try create index
assertThrowsAuthorizationException(() -> client.admin().indices().prepareCreate(ordinaryIndex + "2").get(), "indices:admin/create",
"snapshot_user");
// try create another repo
assertThrowsAuthorizationException(
() -> client.admin().cluster().preparePutRepository("some_other_repo").setType("fs")
.setSettings(Settings.builder().put("location", randomRepoPath())).get(),
"cluster:admin/repository/put", "snapshot_user");
// try delete repo
assertThrowsAuthorizationException(() -> client.admin().cluster().prepareDeleteRepository("repo").get(),
"cluster:admin/repository/delete", "snapshot_user");
// try fumble with snapshots
assertThrowsAuthorizationException(
() -> client.admin().cluster().prepareRestoreSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(),
"cluster:admin/snapshot/restore", "snapshot_user");
assertThrowsAuthorizationException(
() -> client.admin().cluster().prepareDeleteSnapshot("repo", randomAlphaOfLength(4).toLowerCase(Locale.ROOT)).get(),
"cluster:admin/snapshot/delete", "snapshot_user");
// try destructive/revealing actions on all indices
for (final String indexToTest : Arrays.asList(INTERNAL_SECURITY_INDEX, SECURITY_INDEX_NAME, ordinaryIndex)) {
assertThrowsAuthorizationException(() -> client.prepareSearch(indexToTest).get(), "indices:data/read/search", "snapshot_user");
assertThrowsAuthorizationException(() -> client.prepareGet(indexToTest, "doc", "1").get(), "indices:data/read/get",
"snapshot_user");
assertThrowsAuthorizationException(() -> client.prepareIndex(indexToTest, "doc").setSource("term", "val").get(),
"indices:data/write/index", "snapshot_user");
assertThrowsAuthorizationException(() -> client.prepareUpdate(indexToTest, "doc", "1").setDoc("term", "val").get(),
"indices:data/write/update", "snapshot_user");
assertThrowsAuthorizationException(() -> client.prepareDelete(indexToTest, "doc", "1").get(), "indices:data/write/delete",
"snapshot_user");
assertThrowsAuthorizationException(() -> client.admin().indices().prepareDelete(indexToTest).get(), "indices:admin/delete",
"snapshot_user");
}
}
}