[TEST] consolidate different assertAuthorizationException methods in one place

Original commit: elastic/x-pack-elasticsearch@27de6db7e0
This commit is contained in:
javanna 2016-10-06 16:29:32 +02:00 committed by Luca Cavanna
parent 3dbea2f4c2
commit 06b5d42741
9 changed files with 349 additions and 577 deletions

View File

@ -5,24 +5,25 @@
*/
package org.elasticsearch.integration;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesAction;
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateAction;
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.xpack.security.authc.support.Hasher;
import org.elasticsearch.xpack.security.authc.support.SecuredString;
import org.elasticsearch.xpack.security.authc.support.SecuredStringTests;
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
import org.elasticsearch.test.SecurityIntegTestCase;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationException;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.hamcrest.Matchers.hasSize;
/**
@ -103,29 +104,14 @@ public class PermissionPrecedenceTests extends SecurityIntegTestCase {
// now lets try with "user"
try {
Map<String, String> auth = Collections.singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, basicAuthHeaderValue("user",
transportClientPassword()));
client.filterWithHeader(auth)
.admin().indices().preparePutTemplate("template1")
.setTemplate("test_*")
.get();
fail("expected an authorization exception as template APIs should require cluster ALL permission");
} catch (ElasticsearchSecurityException e) {
// expected
assertAuthorizationException(e);
}
Map<String, String> auth = Collections.singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, basicAuthHeaderValue("user",
transportClientPassword()));
assertThrowsAuthorizationException(client.filterWithHeader(auth).admin().indices().preparePutTemplate("template1")
.setTemplate("test_*")::get, PutIndexTemplateAction.NAME, "user");
try {
Map<String, String> headers = Collections.singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, basicAuthHeaderValue("user",
SecuredStringTests.build("test123")));
client.filterWithHeader(headers)
.admin().indices().prepareGetTemplates("template1")
.get();
fail("expected an authorization exception as template APIs should require cluster ALL permission");
} catch (ElasticsearchSecurityException e) {
// expected
assertAuthorizationException(e);
}
Map<String, String> headers = Collections.singletonMap(UsernamePasswordToken.BASIC_AUTH_HEADER, basicAuthHeaderValue("user",
SecuredStringTests.build("test123")));
assertThrowsAuthorizationException(client.filterWithHeader(headers).admin().indices().prepareGetTemplates("template1")::get,
GetIndexTemplatesAction.NAME, "user");
}
}

View File

@ -5,23 +5,19 @@
*/
package org.elasticsearch.integration;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.xpack.security.crypto.CryptoService;
import java.util.Locale;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationException;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
public class ScrollIdSigningTests extends SecurityIntegTestCase {
public void testSearchAndClearScroll() throws Exception {
@ -66,14 +62,10 @@ public class ScrollIdSigningTests extends SecurityIntegTestCase {
String scrollId = response.getScrollId();
String tamperedScrollId = randomBoolean() ? scrollId.substring(randomIntBetween(1, 10)) :
scrollId + randomAsciiOfLength(randomIntBetween(3, 10));
try {
client().prepareSearchScroll(tamperedScrollId).setScroll(TimeValue.timeValueMinutes(2)).get();
fail("Expected an authorization exception to be thrown when scroll id is tampered");
} catch (Exception e) {
ElasticsearchSecurityException ese = (ElasticsearchSecurityException) ExceptionsHelper.unwrap(e,
ElasticsearchSecurityException.class);
assertThat(ese, notNullValue());
assertAuthorizationException(ese);
assertThrowsAuthorizationException(client().prepareSearchScroll(tamperedScrollId).setScroll(TimeValue.timeValueMinutes(2))::get,
equalTo("invalid request. tampered signed text"));
} finally {
clearScroll(scrollId);
}
@ -92,14 +84,10 @@ public class ScrollIdSigningTests extends SecurityIntegTestCase {
String scrollId = response.getScrollId();
String tamperedScrollId = randomBoolean() ? scrollId.substring(randomIntBetween(1, 10)) :
scrollId + randomAsciiOfLength(randomIntBetween(3, 10));
try {
client().prepareClearScroll().addScrollId(tamperedScrollId).get();
fail("Expected an authorization exception to be thrown when scroll id is tampered");
} catch (Exception e) {
ElasticsearchSecurityException ese = (ElasticsearchSecurityException) ExceptionsHelper.unwrap(e,
ElasticsearchSecurityException.class);
assertThat(ese, notNullValue());
assertAuthorizationException(ese);
assertThrowsAuthorizationException(client().prepareClearScroll().addScrollId(tamperedScrollId)::get,
equalTo("invalid request. tampered signed text"));
} finally {
clearScroll(scrollId);
}

View File

@ -6,8 +6,6 @@
package org.elasticsearch.test;
import org.elasticsearch.AbstractOldXPackIndicesBackwardsCompatibilityTestCase;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.ActionRequestBuilder;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;
@ -43,7 +41,6 @@ import java.util.stream.Collectors;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoTimeout;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsCollectionContaining.hasItem;
@ -362,11 +359,10 @@ public abstract class SecurityIntegTestCase extends ESIntegTestCase {
assertThat(clusterHealthResponse.getStatus(), is(ClusterHealthStatus.GREEN));
}
protected static void assertThrowsAuthorizationException(ActionRequestBuilder actionRequestBuilder) {
ElasticsearchSecurityException e = expectThrows(ElasticsearchSecurityException.class, actionRequestBuilder::get);
SecurityTestsUtils.assertAuthorizationException(e, containsString("is unauthorized for user ["));
}
/**
* Creates the indices provided as argument, randomly associating them with aliases, indexes one dummy document per index
* and refreshes the new indices
*/
protected void createIndicesWithRandomAliases(String... indices) {
if (randomBoolean()) {
//no aliases
@ -388,7 +384,7 @@ public abstract class SecurityIntegTestCase extends ESIntegTestCase {
for (String index : indices) {
client().prepareIndex(index, "type").setSource("field", "value").get();
}
refresh();
refresh(indices);
}
@Override

View File

@ -5,11 +5,16 @@
*/
package org.elasticsearch.test;
import org.apache.lucene.util.LuceneTestCase;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.rest.RestStatus;
import org.hamcrest.Matcher;
import static org.apache.lucene.util.LuceneTestCase.expectThrows;
import static org.elasticsearch.xpack.security.test.SecurityAssertions.assertContainsWWWAuthenticateHeader;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.either;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
@ -31,13 +36,38 @@ public class SecurityTestsUtils {
assertThat(e.getMessage(), messageMatcher);
}
public static void assertAuthorizationException(ElasticsearchSecurityException e) {
assertThat(e.status(), is(RestStatus.FORBIDDEN));
public static void assertThrowsAuthorizationException(LuceneTestCase.ThrowingRunnable throwingRunnable, String action, String user) {
assertThrowsAuthorizationException(throwingRunnable,
containsString("[" + action + "] is unauthorized for user [" + user + "]"));
}
public static void assertAuthorizationException(ElasticsearchSecurityException e, Matcher<String> messageMatcher) {
assertAuthorizationException(e);
assertThat(e.getMessage(), messageMatcher);
public static void assertThrowsAuthorizationExceptionRunAs(LuceneTestCase.ThrowingRunnable throwingRunnable,
String action, String user, String runAs) {
assertThrowsAuthorizationException(throwingRunnable,
containsString("[" + action + "] is unauthorized for user [" + user + "] run as [" + runAs + "]"));
}
public static void assertThrowsAuthorizationExceptionDefaultUsers(LuceneTestCase.ThrowingRunnable throwingRunnable, String action) {
ElasticsearchSecurityException exception = expectThrows(ElasticsearchSecurityException.class, throwingRunnable);
assertAuthorizationExceptionDefaultUsers(exception, action);
}
public static void assertAuthorizationExceptionDefaultUsers(Throwable throwable, String action) {
assertAuthorizationException(throwable, either(containsString("[" + action + "] is unauthorized for user ["
+ SecuritySettingsSource.DEFAULT_USER_NAME + "]")).or(containsString("[" + action + "] is unauthorized for user ["
+ SecuritySettingsSource.DEFAULT_TRANSPORT_CLIENT_USER_NAME + "]")));
}
public static void assertThrowsAuthorizationException(LuceneTestCase.ThrowingRunnable throwingRunnable,
Matcher<String> messageMatcher) {
ElasticsearchSecurityException securityException = expectThrows(ElasticsearchSecurityException.class, throwingRunnable);
assertAuthorizationException(securityException, messageMatcher);
}
private static void assertAuthorizationException(Throwable throwable, Matcher<String> messageMatcher) {
assertThat(throwable, instanceOf(ElasticsearchSecurityException.class));
ElasticsearchSecurityException securityException = (ElasticsearchSecurityException) throwable;
assertThat(securityException.status(), is(RestStatus.FORBIDDEN));
assertThat(throwable.getMessage(), messageMatcher);
}
}

View File

@ -5,17 +5,16 @@
*/
package org.elasticsearch.xpack.security.authz;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.admin.indices.analyze.AnalyzeAction;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.xpack.security.authc.support.Hasher;
import org.elasticsearch.xpack.security.authc.support.SecuredString;
import org.elasticsearch.test.SecurityIntegTestCase;
import java.util.Collections;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationException;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationException;
import static org.hamcrest.CoreMatchers.containsString;
public class AnalyzeTests extends SecurityIntegTestCase {
protected static final String USERS_PASSWD_HASHED = new String(Hasher.BCRYPT.hash(new SecuredString("test123".toCharArray())));
@ -59,34 +58,28 @@ public class AnalyzeTests extends SecurityIntegTestCase {
client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("analyze_indices", passwd)))
.admin().indices().prepareAnalyze("this is my text").setIndex("test_1").setAnalyzer("standard").get();
try {
//fails: user doesn't have permissions for analyze on index non_authorized
client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("analyze_indices", passwd)))
.admin().indices().prepareAnalyze("this is my text").setIndex("non_authorized").setAnalyzer("standard").get();
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:admin/analyze] is unauthorized for user [analyze_indices]"));
}
//fails: user doesn't have permissions for analyze on index non_authorized
assertThrowsAuthorizationException(client().filterWithHeader(
Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("analyze_indices", passwd)))
.admin().indices().prepareAnalyze("this is my text").setIndex("non_authorized").setAnalyzer("standard")::get,
AnalyzeAction.NAME, "analyze_indices");
try {
//fails: user doesn't have permissions for cluster level analyze
client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("analyze_indices", passwd)))
.admin().indices().prepareAnalyze("this is my text").setAnalyzer("standard").get();
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [cluster:admin/analyze] is unauthorized for user [analyze_indices]"));
}
//fails: user doesn't have permissions for cluster level analyze
assertThrowsAuthorizationException(client().filterWithHeader(
Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("analyze_indices", passwd)))
.admin().indices().prepareAnalyze("this is my text").setAnalyzer("standard")::get,
"cluster:admin/analyze", "analyze_indices");
}
public void testAnalyzeWithoutIndices() {
//this test tries to execute different analyze api variants from a user that has analyze privileges only at cluster level
SecuredString passwd = new SecuredString("test123".toCharArray());
try {
//fails: user doesn't have permissions for analyze on index test_1
client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("analyze_cluster", passwd)))
.admin().indices().prepareAnalyze("this is my text").setIndex("test_1").setAnalyzer("standard").get();
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:admin/analyze] is unauthorized for user [analyze_cluster]"));
}
//fails: user doesn't have permissions for analyze on index test_1
assertThrowsAuthorizationException(client().filterWithHeader(
Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("analyze_cluster", passwd)))
.admin().indices().prepareAnalyze("this is my text").setIndex("test_1").setAnalyzer("standard")::get,
AnalyzeAction.NAME, "analyze_cluster");
client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("analyze_cluster", passwd)))
.admin().indices().prepareAnalyze("this is my text").setAnalyzer("standard").get();

View File

@ -68,7 +68,6 @@ import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
@ -97,7 +96,8 @@ import java.util.Collections;
import java.util.List;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthenticationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationExceptionRunAs;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
@ -144,67 +144,49 @@ public class AuthorizationServiceTests extends ESTestCase {
public void testIndicesActionsAreNotAuthorized() {
TransportRequest request = mock(TransportRequest.class);
try {
authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "indices:", request);
fail("action beginning with indices should have failed");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:] is unauthorized for user [" + SystemUser.INSTANCE.principal() + "]"));
verify(auditTrail).accessDenied(SystemUser.INSTANCE, "indices:", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "indices:", request),
"indices:", SystemUser.INSTANCE.principal());
verify(auditTrail).accessDenied(SystemUser.INSTANCE, "indices:", request);
verifyNoMoreInteractions(auditTrail);
}
public void testClusterAdminActionsAreNotAuthorized() {
TransportRequest request = mock(TransportRequest.class);
try {
authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/whatever", request);
fail("action beginning with cluster:admin/whatever should have failed");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [cluster:admin/whatever] is unauthorized for user [" + SystemUser.INSTANCE.principal() + "]"));
verify(auditTrail).accessDenied(SystemUser.INSTANCE, "cluster:admin/whatever", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/whatever", request),
"cluster:admin/whatever", SystemUser.INSTANCE.principal());
verify(auditTrail).accessDenied(SystemUser.INSTANCE, "cluster:admin/whatever", request);
verifyNoMoreInteractions(auditTrail);
}
public void testClusterAdminSnapshotStatusActionIsNotAuthorized() {
TransportRequest request = mock(TransportRequest.class);
try {
authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/snapshot/status", request);
fail("action beginning with cluster:admin/snapshot/status should have failed");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [cluster:admin/snapshot/status] is unauthorized for user [" +
SystemUser.INSTANCE.principal() + "]"));
verify(auditTrail).accessDenied(SystemUser.INSTANCE, "cluster:admin/snapshot/status", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(SystemUser.INSTANCE), "cluster:admin/snapshot/status", request),
"cluster:admin/snapshot/status", SystemUser.INSTANCE.principal());
verify(auditTrail).accessDenied(SystemUser.INSTANCE, "cluster:admin/snapshot/status", request);
verifyNoMoreInteractions(auditTrail);
}
public void testNoRolesCausesDenial() {
TransportRequest request = new SearchRequest();
User user = new User("test user");
try {
authorizationService.authorize(createAuthentication(user), "indices:a", request);
fail("user without roles should be denied");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(user), "indices:a", request),
"indices:a", "test user");
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
public void testUnknownRoleCausesDenial() {
TransportRequest request = new SearchRequest();
User user = new User("test user", "non-existent-role");
try {
authorizationService.authorize(createAuthentication(user), "indices:a", request);
fail("user with unknown role only should have been denied");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(user), "indices:a", request),
"indices:a", "test user");
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
public void testThatNonIndicesAndNonClusterActionIsDenied() {
@ -212,14 +194,11 @@ public class AuthorizationServiceTests extends ESTestCase {
User user = new User("test user", "a_all");
when(rolesStore.role("a_all")).thenReturn(Role.builder("a_role").add(IndexPrivilege.ALL, "a").build());
try {
authorizationService.authorize(createAuthentication(user), "whatever", request);
fail("non indices and non cluster requests should be denied");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [whatever] is unauthorized for user [test user]"));
verify(auditTrail).accessDenied(user, "whatever", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(user), "whatever", request),
"whatever", "test user");
verify(auditTrail).accessDenied(user, "whatever", request);
verifyNoMoreInteractions(auditTrail);
}
public void testThatRoleWithNoIndicesIsDenied() {
@ -227,14 +206,11 @@ public class AuthorizationServiceTests extends ESTestCase {
User user = new User("test user", "no_indices");
when(rolesStore.role("no_indices")).thenReturn(Role.builder("no_indices").cluster(ClusterPrivilege.action("")).build());
try {
authorizationService.authorize(createAuthentication(user), "indices:a", request);
fail("user only has cluster roles so indices requests should fail");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(user), "indices:a", request),
"indices:a", "test user");
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
public void testSearchAgainstEmptyCluster() {
@ -248,14 +224,12 @@ public class AuthorizationServiceTests extends ESTestCase {
//ignore_unavailable set to false, user is not authorized for this index nor does it exist
SearchRequest searchRequest = new SearchRequest("does_not_exist")
.indicesOptions(IndicesOptions.fromOptions(false, true, true, false));
try {
authorizationService.authorize(createAuthentication(user), SearchAction.NAME, searchRequest);
fail("indices request for b should be denied since there is no such index");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [" + SearchAction.NAME + "] is unauthorized for user [test user]"));
verify(auditTrail).accessDenied(user, SearchAction.NAME, searchRequest);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(user), SearchAction.NAME, searchRequest),
SearchAction.NAME, "test user");
verify(auditTrail).accessDenied(user, SearchAction.NAME, searchRequest);
verifyNoMoreInteractions(auditTrail);
}
{
@ -312,16 +286,13 @@ public class AuthorizationServiceTests extends ESTestCase {
when(clusterService.state()).thenReturn(state);
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
try {
authorizationService.authorize(createAuthentication(user), "indices:a", request);
fail("indices request for b should be denied since there is no such index");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user]"));
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
verify(clusterService, times(2)).state();
verify(state, times(3)).metaData();
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(user), "indices:a", request),
"indices:a", "test user");
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
verify(clusterService, times(2)).state();
verify(state, times(3)).metaData();
}
public void testCreateIndexWithAliasWithoutPermissions() {
@ -333,17 +304,13 @@ public class AuthorizationServiceTests extends ESTestCase {
when(clusterService.state()).thenReturn(state);
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
try {
authorizationService.authorize(createAuthentication(user), CreateIndexAction.NAME, request);
fail("indices creation request with alias should be denied since user does not have permission to alias");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [" + IndicesAliasesAction.NAME + "] is unauthorized for user [test user]"));
verify(auditTrail).accessDenied(user, IndicesAliasesAction.NAME, request);
verifyNoMoreInteractions(auditTrail);
verify(clusterService).state();
verify(state, times(2)).metaData();
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(user), CreateIndexAction.NAME, request),
IndicesAliasesAction.NAME, "test user");
verify(auditTrail).accessDenied(user, IndicesAliasesAction.NAME, request);
verifyNoMoreInteractions(auditTrail);
verify(clusterService).state();
verify(state, times(2)).metaData();
}
public void testCreateIndexWithAlias() {
@ -409,17 +376,13 @@ public class AuthorizationServiceTests extends ESTestCase {
when(clusterService.state()).thenReturn(state);
when(state.metaData()).thenReturn(MetaData.EMPTY_META_DATA);
try {
authorizationService.authorize(createAuthentication(anonymousUser), "indices:a", request);
fail("indices request for b should be denied since there is no such index");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:a] is unauthorized for user [" + anonymousUser.principal() + "]"));
verify(auditTrail).accessDenied(anonymousUser, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
verify(clusterService, times(2)).state();
verify(state, times(3)).metaData();
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(anonymousUser), "indices:a", request),
"indices:a", anonymousUser.principal());
verify(auditTrail).accessDenied(anonymousUser, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
verify(clusterService, times(2)).state();
verify(state, times(3)).metaData();
}
public void testDenialForAnonymousUserAuthorizationExceptionDisabled() {
@ -453,14 +416,11 @@ public class AuthorizationServiceTests extends ESTestCase {
TransportRequest request = mock(TransportRequest.class);
User user = new User("test user", null, new User("run as me", new String[] { "admin" }));
assertThat(user.runAs(), is(notNullValue()));
try {
authorizationService.authorize(createAuthentication(user), "indices:a", request);
fail("user without roles should be denied for run as");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]"));
verify(auditTrail).runAsDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationExceptionRunAs(
() -> authorizationService.authorize(createAuthentication(user), "indices:a", request),
"indices:a", "test user", "run as me"); // run as [run as me]
verify(auditTrail).runAsDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
public void testRunAsRequestRunningAsUnAllowedUser() {
@ -473,14 +433,11 @@ public class AuthorizationServiceTests extends ESTestCase {
.add(IndexPrivilege.ALL, "a")
.build());
try {
authorizationService.authorize(createAuthentication(user), "indices:a", request);
fail("user without roles should be denied for run as");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]"));
verify(auditTrail).runAsDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationExceptionRunAs(
() -> authorizationService.authorize(createAuthentication(user), "indices:a", request),
"indices:a", "test user", "run as me");
verify(auditTrail).runAsDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
public void testRunAsRequestWithRunAsUserWithoutPermission() {
@ -507,15 +464,12 @@ public class AuthorizationServiceTests extends ESTestCase {
.build());
}
try {
authorizationService.authorize(createAuthentication(user), "indices:a", request);
fail("the run as user's role doesn't exist so they should not get authorized");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:a] is unauthorized for user [test user] run as [run as me]"));
verify(auditTrail).runAsGranted(user, "indices:a", request);
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationExceptionRunAs(
() -> authorizationService.authorize(createAuthentication(user), "indices:a", request),
"indices:a", "test user", "run as me");
verify(auditTrail).runAsGranted(user, "indices:a", request);
verify(auditTrail).accessDenied(user, "indices:a", request);
verifyNoMoreInteractions(auditTrail);
}
public void testRunAsRequestWithValidPermissions() {
@ -577,14 +531,11 @@ public class AuthorizationServiceTests extends ESTestCase {
for (Tuple<String, TransportRequest> requestTuple : requests) {
String action = requestTuple.v1();
TransportRequest request = requestTuple.v2();
try {
authorizationService.authorize(createAuthentication(user), action, request);
fail("only the xpack user can execute operation [" + action + "] against the internal index");
} catch (ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [" + action + "] is unauthorized for user [all_access_user]"));
verify(auditTrail).accessDenied(user, action, request);
verifyNoMoreInteractions(auditTrail);
}
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(user), action, request),
action, "all_access_user");
verify(auditTrail).accessDenied(user, action, request);
verifyNoMoreInteractions(auditTrail);
}
// we should allow waiting for the health of the index or any index if the user has this permission
@ -729,10 +680,8 @@ public class AuthorizationServiceTests extends ESTestCase {
TransportRequest request = compositeRequest.v2();
User user = new User("test user", "no_indices");
when(rolesStore.role("no_indices")).thenReturn(Role.builder("no_indices").cluster(ClusterPrivilege.action("")).build());
ElasticsearchSecurityException securityException = expectThrows(ElasticsearchSecurityException.class,
() -> authorizationService.authorize(createAuthentication(user), action, request));
assertThat(securityException.status(), is(RestStatus.FORBIDDEN));
assertThat(securityException.getMessage(), containsString("[" + action + "] is unauthorized for user [" + user.principal() + "]"));
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(user), action, request), action, "test user");
verify(auditTrail).accessDenied(user, action, request);
verifyNoMoreInteractions(auditTrail);
}
@ -795,11 +744,8 @@ public class AuthorizationServiceTests extends ESTestCase {
when(rolesStore.role("roleDenied")).thenReturn(Role.builder("roleDenied").add(IndexPrivilege.ALL, "a").build());
mockEmptyMetaData();
authorizationService.authorize(createAuthentication(userAllowed), action, request);
ElasticsearchSecurityException securityException = expectThrows(ElasticsearchSecurityException.class,
() -> authorizationService.authorize(createAuthentication(userDenied), action, request));
assertThat(securityException.status(), is(RestStatus.FORBIDDEN));
assertThat(securityException.getMessage(),
containsString("[" + action + "] is unauthorized for user [" + userDenied.principal() + "]"));
assertThrowsAuthorizationException(
() -> authorizationService.authorize(createAuthentication(userDenied), action, request), action, "userDenied");
}
private static Tuple<String, TransportRequest> randomCompositeRequest() {

View File

@ -5,28 +5,29 @@
*/
package org.elasticsearch.xpack.security.authz;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesAction;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesAction;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequestBuilder;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexAction;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.xpack.security.authc.support.Hasher;
import org.elasticsearch.xpack.security.authc.support.SecuredString;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.junit.Before;
import java.util.Collections;
import java.util.Map;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationException;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER;
import static org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationException;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
public class IndexAliasesTests extends SecurityIntegTestCase {
@ -100,19 +101,13 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
new SecuredString("test123".toCharArray())));
assertAcked(client().filterWithHeader(headers).admin().indices().prepareCreate("test_1").get());
try {
client().filterWithHeader(headers).admin().indices().prepareAliases().addAlias("test_1", "test_alias").get();
fail("add alias should have failed due to missing manage_aliases privileges");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:admin/aliases] is unauthorized for user [create_only]"));
}
assertThrowsAuthorizationException(
client().filterWithHeader(headers).admin().indices().prepareAliases().addAlias("test_1", "test_alias")::get,
IndicesAliasesAction.NAME, "create_only");
try {
client().filterWithHeader(headers).admin().indices().prepareAliases().addAlias("test_*", "test_alias").get();
fail("add alias should have failed due to missing manage_aliases privileges");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[test_*]"));
}
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class,
client().filterWithHeader(headers).admin().indices().prepareAliases().addAlias("test_*", "test_alias")::get);
assertThat(indexNotFoundException.toString(), containsString("[test_*]"));
}
public void testCreateIndexAndAliasesCreateOnlyPermission() {
@ -120,80 +115,56 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
// the same create index request
Map<String, String> headers = Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("create_only",
new SecuredString("test123".toCharArray())));
try {
client().filterWithHeader(headers).admin().indices().prepareCreate("test_1").addAlias(new Alias("test_2")).get();
fail("create index should have failed due to missing manage_aliases privileges");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:admin/aliases] is unauthorized for user [create_only]"));
}
assertThrowsAuthorizationException(
client().filterWithHeader(headers).admin().indices().prepareCreate("test_1").addAlias(new Alias("test_2"))::get,
IndicesAliasesAction.NAME, "create_only");
}
public void testDeleteAliasesCreateOnlyPermission() {
//user has create permission only: allows to create indices, manage_aliases is required to add/remove aliases
Map<String, String> headers = Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("create_only",
new SecuredString("test123".toCharArray())));
try {
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "alias_1").get();
fail("remove alias should have failed due to missing manage_aliases privileges");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:admin/aliases] is unauthorized for user [create_only]"));
}
try {
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "alias_*").get();
fail("remove alias should have failed due to missing manage_aliases privileges");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[alias_*"));
}
assertThrowsAuthorizationException(
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "alias_1")::get,
IndicesAliasesAction.NAME, "create_only");
try {
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "_all").get();
fail("remove alias should have failed due to missing manage_aliases privileges");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class,
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "alias_*")::get);
assertThat(indexNotFoundException.toString(), containsString("[alias_*"));
indexNotFoundException = expectThrows(IndexNotFoundException.class,
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "_all")::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
}
public void testGetAliasesCreateOnlyPermissionStrict() {
//user has create permission only: allows to create indices, manage_aliases is required to retrieve aliases though
Map<String, String> headers = Collections.singletonMap(BASIC_AUTH_HEADER, basicAuthHeaderValue("create_only",
new SecuredString("test123".toCharArray())));
try {
client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_1").setIndices("test_1")
.setIndicesOptions(IndicesOptions.strictExpand()).get();
fail("get alias should have failed due to missing manage_aliases privileges");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:admin/aliases/get] is unauthorized for user [create_only]"));
}
try {
client().filterWithHeader(headers).admin().indices().prepareGetAliases("_all").setIndices("test_1")
.setIndicesOptions(IndicesOptions.strictExpand()).get();
fail("get alias should have failed due to missing manage_aliases privileges");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
assertThrowsAuthorizationException(client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_1")
.setIndices("test_1").setIndicesOptions(IndicesOptions.strictExpand())::get, GetAliasesAction.NAME, "create_only");
try {
client().filterWithHeader(headers).admin().indices().prepareGetAliases().setIndices("test_1")
.setIndicesOptions(IndicesOptions.strictExpand()).get();
fail("get alias should have failed due to missing manage_aliases privileges");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class, client().filterWithHeader(headers)
.admin().indices().prepareGetAliases("_all")
.setIndices("test_1").setIndicesOptions(IndicesOptions.strictExpand())::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
indexNotFoundException = expectThrows(IndexNotFoundException.class, client().filterWithHeader(headers).admin().indices()
.prepareGetAliases().setIndices("test_1").setIndicesOptions(IndicesOptions.strictExpand())::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
GetAliasesResponse getAliasesResponse = client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_alias")
.setIndices("test_*").setIndicesOptions(IndicesOptions.strictExpand()).get();
assertEquals(0, getAliasesResponse.getAliases().size());
try {
//this throws exception no matter what the indices options are because the aliases part cannot be resolved to any alias
//and there is no way to "allow_no_aliases" like we can do with indices.
client().filterWithHeader(headers).admin().indices().prepareGetAliases().get();
fail("get alias should have failed due to missing manage_aliases privileges");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
//this throws exception no matter what the indices options are because the aliases part cannot be resolved to any alias
//and there is no way to "allow_no_aliases" like we can do with indices.
indexNotFoundException = expectThrows(IndexNotFoundException.class,
client().filterWithHeader(headers).admin().indices().prepareGetAliases()::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
}
public void testGetAliasesCreateOnlyPermissionIgnoreUnavailable() {
@ -205,35 +176,24 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
.setIndices("test_1").setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
assertEquals(0, getAliasesResponse.getAliases().size());
try {
client().filterWithHeader(headers).admin().indices().prepareGetAliases("_all").setIndices("test_1")
.setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
fail("get alias should have failed due empty set of indices after indices resolution");
} catch(IndexNotFoundException e) {
assertEquals("no such index", e.getMessage());
}
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class, client().filterWithHeader(headers)
.admin().indices().prepareGetAliases("_all")
.setIndices("test_1").setIndicesOptions(IndicesOptions.lenientExpandOpen())::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
try {
client().filterWithHeader(headers).admin().indices().prepareGetAliases().setIndices("test_1")
.setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
fail("get alias should have failed due empty set of indices after indices resolution");
} catch(IndexNotFoundException e) {
assertEquals("no such index", e.getMessage());
}
indexNotFoundException = expectThrows(IndexNotFoundException.class, client().filterWithHeader(headers).admin().indices()
.prepareGetAliases().setIndices("test_1").setIndicesOptions(IndicesOptions.lenientExpandOpen())::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
getAliasesResponse = client().filterWithHeader(headers).admin().indices().prepareGetAliases("test_alias")
.setIndices("test_*").setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
assertEquals(0, getAliasesResponse.getAliases().size());
try {
//this throws exception no matter what the indices options are because the aliases part cannot be resolved to any alias
//and there is no way to "allow_no_aliases" like we can do with indices.
client().filterWithHeader(headers).admin().indices().prepareGetAliases()
.setIndicesOptions(IndicesOptions.lenientExpandOpen()).get();
fail("get alias should have failed due to missing manage_aliases privileges");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
//this throws exception no matter what the indices options are because the aliases part cannot be resolved to any alias
//and there is no way to "allow_no_aliases" like we can do with indices.
indexNotFoundException = expectThrows(IndexNotFoundException.class, client().filterWithHeader(headers).admin().indices()
.prepareGetAliases().setIndicesOptions(IndicesOptions.lenientExpandOpen())::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
}
public void testCreateIndexThenAliasesCreateAndAliasesPermission() {
@ -250,15 +210,10 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
//ok: user has manage_aliases on test_*
assertAcked(client().filterWithHeader(headers).admin().indices().prepareAliases().addAlias("test_*", "test_alias_2").get());
try {
//fails: user doesn't have manage_aliases on alias_1
client().filterWithHeader(headers).admin().indices().prepareAliases().addAlias("test_1", "alias_1")
.addAlias("test_1", "test_alias").get();
fail("add alias should have failed due to missing manage_aliases privileges on alias_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_test]"));
}
//fails: user doesn't have manage_aliases on alias_1
assertThrowsAuthorizationException(client().filterWithHeader(headers).admin().indices().prepareAliases()
.addAlias("test_1", "alias_1").addAlias("test_1", "test_alias")::get,
IndicesAliasesAction.NAME, "create_test_aliases_test");
}
public void testCreateIndexAndAliasesCreateAndAliasesPermission() {
@ -269,15 +224,10 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
new SecuredString("test123".toCharArray())));
assertAcked(client().filterWithHeader(headers).admin().indices().prepareCreate("test_1").addAlias(new Alias("test_alias")).get());
try {
//fails: user doesn't have manage_aliases on alias_1
client().filterWithHeader(headers).admin().indices().prepareCreate("test_2").addAlias(new Alias("test_alias"))
.addAlias(new Alias("alias_2")).get();
fail("create index should have failed due to missing manage_aliases privileges on alias_2");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_test]"));
}
//fails: user doesn't have manage_aliases on alias_1
assertThrowsAuthorizationException(client().filterWithHeader(headers).admin().indices().prepareCreate("test_2")
.addAlias(new Alias("test_alias")).addAlias(new Alias("alias_2"))::get,
IndicesAliasesAction.NAME, "create_test_aliases_test");
}
public void testDeleteAliasesCreateAndAliasesPermission() {
@ -297,40 +247,23 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
//ok: user has manage_aliases on test_*
assertAcked(client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "test_alias_*").get());
try {
//fails: all aliases have been deleted, no existing aliases match test_alias_*
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "test_alias_*").get();
fail("remove alias should have failed due to no existing matching aliases to expand test_alias_* to");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[test_alias_*]"));
}
//fails: all aliases have been deleted, no existing aliases match test_alias_*
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class,
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "test_alias_*")::get);
assertThat(indexNotFoundException.toString(), containsString("[test_alias_*]"));
try {
//fails: all aliases have been deleted, no existing aliases match _all
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "_all").get();
fail("remove alias should have failed due to no existing matching aliases to expand _all to");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
//fails: all aliases have been deleted, no existing aliases match _all
indexNotFoundException = expectThrows(IndexNotFoundException.class,
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "_all")::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
try {
//fails: user doesn't have manage_aliases on alias_1
client().filterWithHeader(headers).admin().indices().prepareAliases().removeAlias("test_1", "alias_1").get();
fail("remove alias should have failed due to missing manage_aliases privileges on alias_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_test]"));
}
//fails: user doesn't have manage_aliases on alias_1
assertThrowsAuthorizationException(client().filterWithHeader(headers).admin().indices().prepareAliases()
.removeAlias("test_1", "alias_1")::get, IndicesAliasesAction.NAME, "create_test_aliases_test");
try {
//fails: user doesn't have manage_aliases on alias_1
client().filterWithHeader(headers).admin().indices().prepareAliases()
.removeAlias("test_1", new String[]{"_all", "alias_1"}).get();
fail("remove alias should have failed due to missing manage_aliases privileges on alias_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_test]"));
}
//fails: user doesn't have manage_aliases on alias_1
assertThrowsAuthorizationException(client().filterWithHeader(headers).admin().indices().prepareAliases()
.removeAlias("test_1", new String[]{"_all", "alias_1"})::get, IndicesAliasesAction.NAME, "create_test_aliases_test");
}
public void testGetAliasesCreateAndAliasesPermission() {
@ -376,24 +309,14 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
assertAliases(client.admin().indices().prepareGetAliases(),
"test_1", "test_alias");
try {
//fails: user has manage_aliases on test_*, although _all aliases and empty indices can be resolved, the explicit non
// authorized alias (alias_1) causes the request to fail
client.admin().indices().prepareGetAliases().setAliases("_all", "alias_1").get();
fail("get alias should have failed due to missing manage_aliases privileges on alias_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases/get] is unauthorized for user [create_test_aliases_test]"));
}
//fails: user has manage_aliases on test_*, although _all aliases and empty indices can be resolved, the explicit non
// authorized alias (alias_1) causes the request to fail
assertThrowsAuthorizationException(client.admin().indices().prepareGetAliases().setAliases("_all", "alias_1")::get,
GetAliasesAction.NAME, "create_test_aliases_test");
try {
//fails: user doesn't have manage_aliases on alias_1
client.admin().indices().prepareGetAliases().setAliases("alias_1").get();
fail("get alias should have failed due to missing manage_aliases privileges on alias_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases/get] is unauthorized for user [create_test_aliases_test]"));
}
//fails: user doesn't have manage_aliases on alias_1
assertThrowsAuthorizationException(client.admin().indices().prepareGetAliases().setAliases("alias_1")::get,
GetAliasesAction.NAME, "create_test_aliases_test");
}
public void testCreateIndexThenAliasesCreateAndAliasesPermission2() {
@ -405,31 +328,18 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
// on both aliases and indices
assertAcked(client.admin().indices().prepareCreate("test_1"));
try {
//fails: user doesn't have manage_aliases aliases on test_1
client.admin().indices().prepareAliases().addAlias("test_1", "test_alias").get();
fail("add alias should have failed due to missing manage_aliases privileges on test_alias and test_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_alias]"));
}
//fails: user doesn't have manage_aliases aliases on test_1
assertThrowsAuthorizationException(client.admin().indices().prepareAliases().addAlias("test_1", "test_alias")::get,
IndicesAliasesAction.NAME, "create_test_aliases_alias");
try {
//fails: user doesn't have manage_aliases aliases on test_1
client.admin().indices().prepareAliases().addAlias("test_1", "alias_1").get();
fail("add alias should have failed due to missing manage_aliases privileges on test_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_alias]"));
}
//fails: user doesn't have manage_aliases aliases on test_1
assertThrowsAuthorizationException(client.admin().indices().prepareAliases().addAlias("test_1", "alias_1")::get,
IndicesAliasesAction.NAME, "create_test_aliases_alias");
try {
//fails: user doesn't have manage_aliases aliases on test_*, no matching indices to replace wildcards
client.admin().indices().prepareAliases().addAlias("test_*", "alias_1").get();
fail("add alias should have failed due to missing manage_aliases privileges on test_1");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[test_*]"));
}
//fails: user doesn't have manage_aliases aliases on test_*, no matching indices to replace wildcards
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class,
client.admin().indices().prepareAliases().addAlias("test_*", "alias_1")::get);
assertThat(indexNotFoundException.toString(), containsString("[test_*]"));
}
public void testCreateIndexAndAliasesCreateAndAliasesPermission2() {
@ -440,23 +350,10 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
//user has create permission on test_* and manage_aliases permission on alias_*. manage_aliases is required to add/remove aliases
// on both aliases and indices
try {
//fails: user doesn't have manage_aliases on test_1, create index is rejected as a whole
client.admin().indices().prepareCreate("test_1").addAlias(new Alias("test_alias")).get();
fail("create index should have failed due to missing manage_aliases privileges on test_1 and test_alias");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_alias]"));
}
try {
//fails: user doesn't have manage_aliases on test_*, create index is rejected as a whole
client.admin().indices().prepareCreate("test_1").addAlias(new Alias("test_alias")).addAlias(new Alias("alias_1")).get();
fail("create index should have failed due to missing manage_aliases privileges on test_1 and test_alias");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_alias]"));
}
//fails: user doesn't have manage_aliases on test_1, create index is rejected as a whole
assertThrowsAuthorizationException(client.admin().indices().prepareCreate("test_1").addAlias(new Alias("test_alias"))::get,
IndicesAliasesAction.NAME, "create_test_aliases_alias");
}
public void testDeleteAliasesCreateAndAliasesPermission2() {
@ -466,32 +363,15 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
//user has create permission on test_* and manage_aliases permission on alias_*. manage_aliases is required to add/remove aliases
// on both aliases and indices
try {
//fails: user doesn't have manage_aliases on test_1
client.admin().indices().prepareAliases().removeAlias("test_1", "test_alias").get();
fail("remove alias should have failed due to missing manage_aliases privileges on test_alias and test_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_alias]"));
}
try {
//fails: user doesn't have manage_aliases on test_1
client.admin().indices().prepareAliases().removeAlias("test_1", "alias_1").get();
fail("remove alias should have failed due to missing manage_aliases privileges on test_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_alias]"));
}
//fails: user doesn't have manage_aliases on test_1
assertThrowsAuthorizationException(client.admin().indices().prepareAliases().removeAlias("test_1", "test_alias")::get,
IndicesAliasesAction.NAME, "create_test_aliases_alias");
try {
//fails: user doesn't have manage_aliases on test_*, wildcards can't get replaced
client.admin().indices().prepareAliases().removeAlias("test_*", "alias_1").get();
fail("remove alias should have failed due to missing manage_aliases privileges on test_*");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[test_*]"));
//fails: user doesn't have manage_aliases on test_*, wildcards can't get replaced
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class,
client.admin().indices().prepareAliases().removeAlias("test_*", "alias_1")::get);
}
}
public void testGetAliasesCreateAndAliasesPermission2() {
Map<String, String> headers = Collections.singletonMap(BASIC_AUTH_HEADER,
@ -502,14 +382,9 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
// on both aliases and indices
assertAcked(client.admin().indices().prepareCreate("test_1"));
try {
//fails: user doesn't have manage_aliases aliases on test_1, nor test_alias
client.admin().indices().prepareGetAliases().setAliases("test_alias").setIndices("test_1").get();
fail("get alias should have failed due to missing manage_aliases privileges on test_alias and test_1");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases/get] is unauthorized for user [create_test_aliases_alias]"));
}
//fails: user doesn't have manage_aliases aliases on test_1, nor test_alias
assertThrowsAuthorizationException(client.admin().indices().prepareGetAliases().setAliases("test_alias").setIndices("test_1")::get,
GetAliasesAction.NAME, "create_test_aliases_alias");
//user doesn't have manage_aliases aliases on test_*, no matching indices to replace wildcards
GetAliasesResponse getAliasesResponse = client.admin().indices().prepareGetAliases()
@ -520,37 +395,24 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
getAliasesResponse = client.admin().indices().prepareGetAliases().setAliases("test_alias").get();
assertEquals(0, getAliasesResponse.getAliases().size());
try {
//fails: no existing aliases to replace wildcards
client.admin().indices().prepareGetAliases().setIndices("test_1").setAliases("test_*").get();
fail("get alias should have failed due to missing manage_aliases privileges on test_1");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[test_*]"));
}
//fails: no existing aliases to replace wildcards
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class,
client.admin().indices().prepareGetAliases().setIndices("test_1").setAliases("test_*")::get);
assertThat(indexNotFoundException.toString(), containsString("[test_*]"));
try {
//fails: no existing aliases to replace _all
client.admin().indices().prepareGetAliases().setIndices("test_1").setAliases("_all").get();
fail("get alias should have failed due to missing manage_aliases privileges on test_1");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
//fails: no existing aliases to replace _all
indexNotFoundException = expectThrows(IndexNotFoundException.class,
client.admin().indices().prepareGetAliases().setIndices("test_1").setAliases("_all")::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
try {
//fails: no existing aliases to replace empty aliases
client.admin().indices().prepareGetAliases().setIndices("test_1").get();
fail("get alias should have failed due to missing manage_aliases privileges on test_1");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
//fails: no existing aliases to replace empty aliases
indexNotFoundException = expectThrows(IndexNotFoundException.class,
client.admin().indices().prepareGetAliases().setIndices("test_1")::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
try {
//fails: no existing aliases to replace empty aliases
client.admin().indices().prepareGetAliases().get();
fail("get alias should have failed due to missing manage_aliases privileges on test_1");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
//fails: no existing aliases to replace empty aliases
indexNotFoundException = expectThrows(IndexNotFoundException.class, client.admin().indices().prepareGetAliases()::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
}
public void testCreateIndexThenAliasesCreateAndAliasesPermission3() {
@ -588,26 +450,18 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
assertAcked(client.admin().indices().prepareCreate("test_1").addAlias(new Alias("test_alias")).addAlias(new Alias("alias_1"))
.addAlias(new Alias("alias_2")).addAlias(new Alias("alias_3")));
try {
//fails: user doesn't have manage_aliases privilege on non_authorized
client.admin().indices().prepareAliases().removeAlias("test_1", "non_authorized").removeAlias("test_1", "test_alias").get();
fail("remove alias should have failed due to missing manage_aliases privileges on non_authorized");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e,
containsString("action [indices:admin/aliases] is unauthorized for user [create_test_aliases_test_alias]"));
}
//fails: user doesn't have manage_aliases privilege on non_authorized
assertThrowsAuthorizationException(client.admin().indices().prepareAliases().removeAlias("test_1", "non_authorized")
.removeAlias("test_1", "test_alias")::get, IndicesAliasesAction.NAME, "create_test_aliases_test_alias");
assertAcked(client.admin().indices().prepareAliases().removeAlias("test_1", "alias_1"));
assertAcked(client.admin().indices().prepareAliases().removeAlias("test_*", "_all"));
try {
//fails: all aliases have been deleted, _all can't be resolved to any existing authorized aliases
client.admin().indices().prepareAliases().removeAlias("test_1", "_all").get();
fail("remove alias should have failed due to no existing aliases matching _all");
} catch(IndexNotFoundException e) {
assertThat(e.toString(), containsString("[_all]"));
}
//fails: all aliases have been deleted, _all can't be resolved to any existing authorized aliases
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class,
client.admin().indices().prepareAliases().removeAlias("test_1", "_all")::get);
assertThat(indexNotFoundException.toString(), containsString("[_all]"));
}
public void testGetAliasesCreateAndAliasesPermission3() {
@ -646,14 +500,9 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
}
public void testCreateIndexAliasesOnlyPermission() {
try {
client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER,
basicAuthHeaderValue("aliases_only", new SecuredString("test123".toCharArray()))))
.admin().indices().prepareCreate("test_1").get();
fail("Expected ElasticsearchSecurityException");
} catch (ElasticsearchSecurityException e) {
assertThat(e.getMessage(), is("action [indices:admin/create] is unauthorized for user [aliases_only]"));
}
assertThrowsAuthorizationException(client().filterWithHeader(Collections.singletonMap(BASIC_AUTH_HEADER,
basicAuthHeaderValue("aliases_only", new SecuredString("test123".toCharArray()))))
.admin().indices().prepareCreate("test_1")::get, CreateIndexAction.NAME, "aliases_only");
}
public void testGetAliasesAliasesOnlyPermissionStrict() {
@ -662,33 +511,18 @@ public class IndexAliasesTests extends SecurityIntegTestCase {
final Client client = client().filterWithHeader(headers);
//user has manage_aliases only permissions on both alias_* and test_*
//ok: manage_aliases on both test_* and alias_*
try {
//security plugin lets it through, but es core intercepts it due to strict indices options and throws index not found
client.admin().indices().prepareGetAliases("alias_1")
.addIndices("test_1").setIndicesOptions(IndicesOptions.strictExpandOpen()).get();
fail("Expected IndexNotFoundException");
} catch(IndexNotFoundException e) {
assertEquals("no such index", e.getMessage());
}
//security plugin lets it through, but es core intercepts it due to strict indices options and throws index not found
IndexNotFoundException indexNotFoundException = expectThrows(IndexNotFoundException.class, client.admin().indices()
.prepareGetAliases("alias_1").addIndices("test_1").setIndicesOptions(IndicesOptions.strictExpandOpen())::get);
assertEquals("no such index", indexNotFoundException.getMessage());
try {
//fails: no manage_aliases privilege on non_authorized alias
client.admin().indices().prepareGetAliases("non_authorized").addIndices("test_1")
.setIndicesOptions(IndicesOptions.strictExpandOpen()).get();
fail("Expected ElasticsearchSecurityException");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:admin/aliases/get] is unauthorized for user [aliases_only]"));
}
//fails: no manage_aliases privilege on non_authorized alias
assertThrowsAuthorizationException(client.admin().indices().prepareGetAliases("non_authorized").addIndices("test_1")
.setIndicesOptions(IndicesOptions.strictExpandOpen())::get, GetAliasesAction.NAME, "aliases_only");
try {
//fails: no manage_aliases privilege on non_authorized index
client.admin().indices().prepareGetAliases("alias_1").addIndices("non_authorized")
.setIndicesOptions(IndicesOptions.strictExpandOpen()).get();
fail("Expected ElasticsearchSecurityException");
} catch(ElasticsearchSecurityException e) {
assertAuthorizationException(e, containsString("action [indices:admin/aliases/get] is unauthorized for user [aliases_only]"));
}
//fails: no manage_aliases privilege on non_authorized index
assertThrowsAuthorizationException(client.admin().indices().prepareGetAliases("alias_1").addIndices("non_authorized")
.setIndicesOptions(IndicesOptions.strictExpandOpen())::get, GetAliasesAction.NAME, "aliases_only");
}
public void testGetAliasesAliasesOnlyPermissionIgnoreUnavailable() {

View File

@ -6,11 +6,16 @@
package org.elasticsearch.xpack.security.authz;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.get.GetAction;
import org.elasticsearch.action.get.MultiGetAction;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchAction;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.termvectors.MultiTermVectorsAction;
import org.elasticsearch.action.termvectors.MultiTermVectorsResponse;
import org.elasticsearch.action.termvectors.TermVectorsAction;
import org.elasticsearch.client.Requests;
import org.elasticsearch.index.IndexNotFoundException;
import org.elasticsearch.search.SearchHit;
@ -20,9 +25,9 @@ import org.elasticsearch.test.SecuritySettingsSource;
import java.util.ArrayList;
import java.util.List;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationExceptionDefaultUsers;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationExceptionDefaultUsers;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoSearchHits;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.core.IsCollectionContaining.hasItems;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
@ -118,12 +123,12 @@ public class ReadActionsTests extends SecurityIntegTestCase {
public void testExplicitNonAuthorizedIndex() {
createIndicesWithRandomAliases("test1", "test2", "index1");
assertThrowsAuthorizationException(client().prepareSearch("test*", "index1"));
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareSearch("test*", "index1")::get, SearchAction.NAME);
}
public void testIndexNotFound() {
createIndicesWithRandomAliases("test1", "test2", "index1");
assertThrowsAuthorizationException(client().prepareSearch("missing"));
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareSearch("missing")::get, SearchAction.NAME);
}
public void testIndexNotFoundIgnoreUnavailable() {
@ -212,7 +217,7 @@ public class ReadActionsTests extends SecurityIntegTestCase {
assertTrue(multiSearchResponse.getResponses()[1].isFailure());
Exception exception = multiSearchResponse.getResponses()[1].getFailure();
assertThat(exception, instanceOf(ElasticsearchSecurityException.class));
assertAuthorizationException((ElasticsearchSecurityException)exception, containsString("is unauthorized for user ["));
assertAuthorizationExceptionDefaultUsers(exception, SearchAction.NAME);
}
{
MultiSearchResponse multiSearchResponse = client().prepareMultiSearch()
@ -243,7 +248,7 @@ public class ReadActionsTests extends SecurityIntegTestCase {
assertTrue(multiSearchResponse.getResponses()[1].isFailure());
Exception exception = multiSearchResponse.getResponses()[1].getFailure();
assertThat(exception, instanceOf(ElasticsearchSecurityException.class));
assertAuthorizationException((ElasticsearchSecurityException)exception, containsString("is unauthorized for user ["));
assertAuthorizationExceptionDefaultUsers(exception, SearchAction.NAME);
}
{
MultiSearchResponse multiSearchResponse = client().prepareMultiSearch()
@ -333,13 +338,9 @@ public class ReadActionsTests extends SecurityIntegTestCase {
client().prepareGet("test1", "type", "id").get();
ElasticsearchSecurityException securityException = expectThrows(ElasticsearchSecurityException.class,
() -> client().prepareGet("index1", "type", "id").get());
assertAuthorizationException(securityException);
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareGet("index1", "type", "id")::get, GetAction.NAME);
securityException = expectThrows(ElasticsearchSecurityException.class,
() -> client().prepareGet("missing", "type", "id").get());
assertAuthorizationException(securityException);
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareGet("missing", "type", "id")::get, GetAction.NAME);
expectThrows(IndexNotFoundException.class, () -> client().prepareGet("test5", "type", "id").get());
}
@ -357,7 +358,8 @@ public class ReadActionsTests extends SecurityIntegTestCase {
assertEquals("test1", multiGetResponse.getResponses()[0].getResponse().getIndex());
assertTrue(multiGetResponse.getResponses()[1].isFailed());
assertEquals("index1", multiGetResponse.getResponses()[1].getFailure().getIndex());
assertAuthorizationException((ElasticsearchSecurityException) multiGetResponse.getResponses()[1].getFailure().getFailure());
assertAuthorizationExceptionDefaultUsers(multiGetResponse.getResponses()[1].getFailure().getFailure(),
MultiGetAction.NAME + "[shard]");
assertFalse(multiGetResponse.getResponses()[2].isFailed());
assertEquals("test3", multiGetResponse.getResponses()[2].getResponse().getIndex());
assertTrue(multiGetResponse.getResponses()[3].isFailed());
@ -374,13 +376,9 @@ public class ReadActionsTests extends SecurityIntegTestCase {
createIndicesWithRandomAliases("test1", "index1");
client().prepareTermVectors("test1", "type", "id").get();
ElasticsearchSecurityException securityException = expectThrows(ElasticsearchSecurityException.class,
() -> client().prepareTermVectors("index1", "type", "id").get());
assertAuthorizationException(securityException);
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareTermVectors("index1", "type", "id")::get, TermVectorsAction.NAME);
securityException = expectThrows(ElasticsearchSecurityException.class,
() -> client().prepareTermVectors("missing", "type", "id").get());
assertAuthorizationException(securityException);
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareTermVectors("missing", "type", "id")::get, TermVectorsAction.NAME);
expectThrows(IndexNotFoundException.class, () -> client().prepareTermVectors("test5", "type", "id").get());
}
@ -398,12 +396,13 @@ public class ReadActionsTests extends SecurityIntegTestCase {
assertEquals("test1", response.getResponses()[0].getResponse().getIndex());
assertTrue(response.getResponses()[1].isFailed());
assertEquals("index1", response.getResponses()[1].getFailure().getIndex());
assertAuthorizationException((ElasticsearchSecurityException) response.getResponses()[1].getFailure().getCause());
assertAuthorizationExceptionDefaultUsers(response.getResponses()[1].getFailure().getCause(),
MultiTermVectorsAction.NAME + "[shard]");
assertFalse(response.getResponses()[2].isFailed());
assertEquals("test3", response.getResponses()[2].getResponse().getIndex());
assertTrue(response.getResponses()[3].isFailed());
assertEquals("missing", response.getResponses()[3].getFailure().getIndex());
//different behaviour compared to get api: we leak information about a non existing index that the current user is not
//different behaviour compared to term_vector api: we leak information about a non existing index that the current user is not
//authorized for. Should rather be an authorization exception but we only authorize at the shard level in mget. If we
//authorized globally, we would fail the whole mget request which is not desirable.
assertThat(response.getResponses()[3].getFailure().getCause(), instanceOf(IndexNotFoundException.class));

View File

@ -7,16 +7,21 @@ package org.elasticsearch.xpack.security.authz;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.bulk.BulkAction;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteAction;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexAction;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateAction;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.index.engine.DocumentMissingException;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.test.SecuritySettingsSource;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationException;
import static org.elasticsearch.test.SecurityTestsUtils.assertAuthorizationExceptionDefaultUsers;
import static org.elasticsearch.test.SecurityTestsUtils.assertThrowsAuthorizationExceptionDefaultUsers;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
@ -41,14 +46,13 @@ public class WriteActionsTests extends SecurityIntegTestCase {
createIndex("test1", "index1");
client().prepareIndex("test1", "type", "id").setSource("field", "value").get();
assertThrowsAuthorizationException(client().prepareIndex("index1", "type", "id").setSource("field", "value"));
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareIndex("index1", "type", "id").setSource("field", "value")::get,
IndexAction.NAME);
client().prepareIndex("test4", "type", "id").setSource("field", "value").get();
//the missing index gets automatically created (user has permissions for that), but indexing fails due to missing authorization
ElasticsearchSecurityException exception = expectThrows(ElasticsearchSecurityException.class,
() -> client().prepareIndex("missing", "type", "id").setSource("field", "value").get());
assertAuthorizationException(exception);
assertThat(exception.getMessage(), containsString("[indices:data/write/index] is unauthorized"));
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareIndex("missing", "type", "id").setSource("field", "value")::get,
IndexAction.NAME);
}
public void testDelete() {
@ -56,14 +60,11 @@ public class WriteActionsTests extends SecurityIntegTestCase {
client().prepareIndex("test1", "type", "id").setSource("field", "value").get();
assertEquals(RestStatus.OK, client().prepareDelete("test1", "type", "id").get().status());
assertThrowsAuthorizationException(client().prepareDelete("index1", "type", "id"));
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareDelete("index1", "type", "id")::get, DeleteAction.NAME);
assertEquals(RestStatus.NOT_FOUND, client().prepareDelete("test4", "type", "id").get().status());
ElasticsearchSecurityException exception = expectThrows(ElasticsearchSecurityException.class,
() -> client().prepareDelete("missing", "type", "id").get());
assertAuthorizationException(exception);
assertThat(exception.getMessage(), containsString("[indices:data/write/delete] is unauthorized"));
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareDelete("missing", "type", "id")::get, DeleteAction.NAME);
}
public void testUpdate() {
@ -71,14 +72,13 @@ public class WriteActionsTests extends SecurityIntegTestCase {
client().prepareIndex("test1", "type", "id").setSource("field", "value").get();
assertEquals(RestStatus.OK, client().prepareUpdate("test1", "type", "id").setDoc("field2", "value2").get().status());
assertThrowsAuthorizationException(client().prepareUpdate("index1", "type", "id").setDoc("field2", "value2"));
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareUpdate("index1", "type", "id").setDoc("field2", "value2")::get,
UpdateAction.NAME);
expectThrows(DocumentMissingException.class, () -> client().prepareUpdate("test4", "type", "id").setDoc("field2", "value2").get());
ElasticsearchSecurityException exception = expectThrows(ElasticsearchSecurityException.class,
() -> client().prepareUpdate("missing", "type", "id").setDoc("field2", "value2").get());
assertAuthorizationException(exception);
assertThat(exception.getMessage(), containsString("[indices:data/write/update] is unauthorized"));
assertThrowsAuthorizationExceptionDefaultUsers(client().prepareUpdate("missing", "type", "id").setDoc("field2", "value2")::get,
UpdateAction.NAME);
}
public void testBulk() {
@ -105,7 +105,7 @@ public class WriteActionsTests extends SecurityIntegTestCase {
assertTrue(bulkResponse.getItems()[1].isFailed());
assertEquals(DocWriteRequest.OpType.INDEX, bulkResponse.getItems()[1].getOpType());
assertEquals("index1", bulkResponse.getItems()[1].getFailure().getIndex());
assertAuthorizationException((ElasticsearchSecurityException) bulkResponse.getItems()[1].getFailure().getCause());
assertAuthorizationExceptionDefaultUsers(bulkResponse.getItems()[1].getFailure().getCause(), BulkAction.NAME + "[s]");
assertThat(bulkResponse.getItems()[1].getFailure().getCause().getMessage(),
containsString("[indices:data/write/bulk[s]] is unauthorized"));
assertFalse(bulkResponse.getItems()[2].isFailed());
@ -116,7 +116,7 @@ public class WriteActionsTests extends SecurityIntegTestCase {
//the missing index gets automatically created (user has permissions for that), but indexing fails due to missing authorization
assertEquals("missing", bulkResponse.getItems()[3].getFailure().getIndex());
assertThat(bulkResponse.getItems()[3].getFailure().getCause(), instanceOf(ElasticsearchSecurityException.class));
assertAuthorizationException((ElasticsearchSecurityException) bulkResponse.getItems()[3].getFailure().getCause());
assertAuthorizationExceptionDefaultUsers(bulkResponse.getItems()[3].getFailure().getCause(), BulkAction.NAME + "[s]");
assertThat(bulkResponse.getItems()[3].getFailure().getCause().getMessage(),
containsString("[indices:data/write/bulk[s]] is unauthorized"));
assertFalse(bulkResponse.getItems()[4].isFailed());
@ -125,7 +125,7 @@ public class WriteActionsTests extends SecurityIntegTestCase {
assertTrue(bulkResponse.getItems()[5].isFailed());
assertEquals(DocWriteRequest.OpType.DELETE, bulkResponse.getItems()[5].getOpType());
assertEquals("index1", bulkResponse.getItems()[5].getFailure().getIndex());
assertAuthorizationException((ElasticsearchSecurityException) bulkResponse.getItems()[5].getFailure().getCause());
assertAuthorizationExceptionDefaultUsers(bulkResponse.getItems()[5].getFailure().getCause(), BulkAction.NAME + "[s]");
assertThat(bulkResponse.getItems()[5].getFailure().getCause().getMessage(),
containsString("[indices:data/write/bulk[s]] is unauthorized"));
assertFalse(bulkResponse.getItems()[6].isFailed());
@ -134,7 +134,7 @@ public class WriteActionsTests extends SecurityIntegTestCase {
assertTrue(bulkResponse.getItems()[7].isFailed());
assertEquals(DocWriteRequest.OpType.DELETE, bulkResponse.getItems()[7].getOpType());
assertEquals("missing", bulkResponse.getItems()[7].getFailure().getIndex());
assertAuthorizationException((ElasticsearchSecurityException) bulkResponse.getItems()[7].getFailure().getCause());
assertAuthorizationExceptionDefaultUsers(bulkResponse.getItems()[7].getFailure().getCause(), BulkAction.NAME + "[s]");
assertThat(bulkResponse.getItems()[7].getFailure().getCause().getMessage(),
containsString("[indices:data/write/bulk[s]] is unauthorized"));
assertFalse(bulkResponse.getItems()[8].isFailed());
@ -146,7 +146,7 @@ public class WriteActionsTests extends SecurityIntegTestCase {
assertTrue(bulkResponse.getItems()[10].isFailed());
assertEquals(DocWriteRequest.OpType.UPDATE, bulkResponse.getItems()[10].getOpType());
assertEquals("index1", bulkResponse.getItems()[10].getFailure().getIndex());
assertAuthorizationException((ElasticsearchSecurityException) bulkResponse.getItems()[10].getFailure().getCause());
assertAuthorizationExceptionDefaultUsers(bulkResponse.getItems()[10].getFailure().getCause(), BulkAction.NAME + "[s]");
assertThat(bulkResponse.getItems()[10].getFailure().getCause().getMessage(),
containsString("[indices:data/write/bulk[s]] is unauthorized"));
assertTrue(bulkResponse.getItems()[11].isFailed());
@ -157,7 +157,7 @@ public class WriteActionsTests extends SecurityIntegTestCase {
assertEquals(DocWriteRequest.OpType.UPDATE, bulkResponse.getItems()[12].getOpType());
assertEquals("missing", bulkResponse.getItems()[12].getFailure().getIndex());
assertThat(bulkResponse.getItems()[12].getFailure().getCause(), instanceOf(ElasticsearchSecurityException.class));
assertAuthorizationException((ElasticsearchSecurityException) bulkResponse.getItems()[12].getFailure().getCause());
assertAuthorizationExceptionDefaultUsers(bulkResponse.getItems()[12].getFailure().getCause(), BulkAction.NAME + "[s]");
assertThat(bulkResponse.getItems()[12].getFailure().getCause().getMessage(),
containsString("[indices:data/write/bulk[s]] is unauthorized"));
}