diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/action/user/RestGetUserPrivilegesAction.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/action/user/RestGetUserPrivilegesAction.java index 75c790d861b..2145b6f39dc 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/action/user/RestGetUserPrivilegesAction.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/action/user/RestGetUserPrivilegesAction.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.xpack.security.rest.action.user; +import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.ToXContent; @@ -24,6 +25,7 @@ import org.elasticsearch.xpack.core.security.authz.RoleDescriptor; import org.elasticsearch.xpack.core.security.authz.privilege.ConditionalClusterPrivilege; import org.elasticsearch.xpack.core.security.authz.privilege.ConditionalClusterPrivileges; import org.elasticsearch.xpack.core.security.client.SecurityClient; +import org.elasticsearch.xpack.core.security.user.User; import org.elasticsearch.xpack.security.rest.action.SecurityBaseRestHandler; import java.io.IOException; @@ -52,7 +54,11 @@ public class RestGetUserPrivilegesAction extends SecurityBaseRestHandler { @Override public RestChannelConsumer innerPrepareRequest(RestRequest request, NodeClient client) throws IOException { - final String username = securityContext.getUser().principal(); + final User user = securityContext.getUser(); + if (user == null) { + return restChannel -> { throw new ElasticsearchSecurityException("there is no authenticated user"); }; + } + final String username = user.principal(); final GetUserPrivilegesRequestBuilder requestBuilder = new SecurityClient(client).prepareGetUserPrivileges(username); return channel -> requestBuilder.execute(new RestListener(channel)); } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/action/user/RestHasPrivilegesAction.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/action/user/RestHasPrivilegesAction.java index 4949b18366d..5a47df39f09 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/action/user/RestHasPrivilegesAction.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/rest/action/user/RestHasPrivilegesAction.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.xpack.security.rest.action.user; +import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.collect.Tuple; @@ -24,6 +25,7 @@ import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesRequestBui import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesResponse; import org.elasticsearch.xpack.core.security.authz.RoleDescriptor; import org.elasticsearch.xpack.core.security.client.SecurityClient; +import org.elasticsearch.xpack.core.security.user.User; import org.elasticsearch.xpack.security.rest.action.SecurityBaseRestHandler; import java.io.IOException; @@ -59,6 +61,9 @@ public class RestHasPrivilegesAction extends SecurityBaseRestHandler { @Override public RestChannelConsumer innerPrepareRequest(RestRequest request, NodeClient client) throws IOException { final String username = getUsername(request); + if (username == null) { + return restChannel -> { throw new ElasticsearchSecurityException("there is no authenticated user"); }; + } final Tuple content = request.contentOrSourceParam(); HasPrivilegesRequestBuilder requestBuilder = new SecurityClient(client).prepareHasPrivileges(username, content.v2(), content.v1()); return channel -> requestBuilder.execute(new HasPrivilegesRestResponseBuilder(username, channel)); @@ -69,7 +74,11 @@ public class RestHasPrivilegesAction extends SecurityBaseRestHandler { if (username != null) { return username; } - return securityContext.getUser().principal(); + final User user = securityContext.getUser(); + if (user == null) { + return null; + } + return user.principal(); } static class HasPrivilegesRestResponseBuilder extends RestBuilderListener { diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/user/RestGetUserPrivilegesActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/user/RestGetUserPrivilegesActionTests.java index ed75cec3243..8a637c69435 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/user/RestGetUserPrivilegesActionTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/user/RestGetUserPrivilegesActionTests.java @@ -6,17 +6,24 @@ package org.elasticsearch.xpack.security.rest.action.user; +import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.Strings; import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.set.Sets; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestStatus; import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.rest.FakeRestChannel; +import org.elasticsearch.test.rest.FakeRestRequest; +import org.elasticsearch.xpack.core.security.SecurityContext; import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesResponse; import org.elasticsearch.xpack.core.security.authz.RoleDescriptor.ApplicationResourcePrivileges; import org.elasticsearch.xpack.core.security.authz.permission.FieldPermissionsDefinition; import org.elasticsearch.xpack.core.security.authz.privilege.ConditionalClusterPrivilege; import org.elasticsearch.xpack.core.security.authz.privilege.ConditionalClusterPrivileges; -import org.hamcrest.Matchers; import java.util.Arrays; import java.util.Collections; @@ -24,9 +31,27 @@ import java.util.LinkedHashSet; import java.util.Set; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class RestGetUserPrivilegesActionTests extends ESTestCase { + public void testBasicLicense() throws Exception { + final XPackLicenseState licenseState = mock(XPackLicenseState.class); + final RestGetUserPrivilegesAction action = new RestGetUserPrivilegesAction(Settings.EMPTY, mock(RestController.class), + mock(SecurityContext.class), licenseState); + when(licenseState.isSecurityAvailable()).thenReturn(false); + final FakeRestRequest request = new FakeRestRequest(); + final FakeRestChannel channel = new FakeRestChannel(request, true, 1); + action.handleRequest(request, channel, mock(NodeClient.class)); + assertThat(channel.capturedResponse(), notNullValue()); + assertThat(channel.capturedResponse().status(), equalTo(RestStatus.FORBIDDEN)); + assertThat(channel.capturedResponse().content().utf8ToString(), containsString("current license is non-compliant for [security]")); + } + public void testBuildResponse() throws Exception { final RestGetUserPrivilegesAction.RestListener listener = new RestGetUserPrivilegesAction.RestListener(null); @@ -37,8 +62,8 @@ public class RestGetUserPrivilegesActionTests extends ESTestCase { final Set index = new LinkedHashSet<>(Arrays.asList( new GetUserPrivilegesResponse.Indices(Arrays.asList("index-1", "index-2", "index-3-*"), Arrays.asList("read", "write"), new LinkedHashSet<>(Arrays.asList( - new FieldPermissionsDefinition.FieldGrantExcludeGroup(new String[]{ "public.*" }, new String[0]), - new FieldPermissionsDefinition.FieldGrantExcludeGroup(new String[]{ "*" }, new String[]{ "private.*" }) + new FieldPermissionsDefinition.FieldGrantExcludeGroup(new String[]{"public.*"}, new String[0]), + new FieldPermissionsDefinition.FieldGrantExcludeGroup(new String[]{"*"}, new String[]{"private.*"}) )), new LinkedHashSet<>(Arrays.asList( new BytesArray("{ \"term\": { \"access\": \"public\" } }"), @@ -60,7 +85,7 @@ public class RestGetUserPrivilegesActionTests extends ESTestCase { listener.buildResponse(response, builder); String json = Strings.toString(builder); - assertThat(json, Matchers.equalTo("{" + + assertThat(json, equalTo("{" + "\"cluster\":[\"monitor\",\"manage_ml\",\"manage_watcher\"]," + "\"global\":[" + "{\"application\":{\"manage\":{\"applications\":[\"app01\",\"app02\"]}}}" + diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/user/RestHasPrivilegesActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/user/RestHasPrivilegesActionTests.java new file mode 100644 index 00000000000..3cf985d9cdf --- /dev/null +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/user/RestHasPrivilegesActionTests.java @@ -0,0 +1,39 @@ +/* + * 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.rest.action.user; + +import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.rest.RestController; +import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.rest.FakeRestChannel; +import org.elasticsearch.test.rest.FakeRestRequest; +import org.elasticsearch.xpack.core.security.SecurityContext; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class RestHasPrivilegesActionTests extends ESTestCase { + + public void testBasicLicense() throws Exception { + final XPackLicenseState licenseState = mock(XPackLicenseState.class); + final RestHasPrivilegesAction action = new RestHasPrivilegesAction(Settings.EMPTY, mock(RestController.class), + mock(SecurityContext.class), licenseState); + when(licenseState.isSecurityAvailable()).thenReturn(false); + final FakeRestRequest request = new FakeRestRequest(); + final FakeRestChannel channel = new FakeRestChannel(request, true, 1); + action.handleRequest(request, channel, mock(NodeClient.class)); + assertThat(channel.capturedResponse(), notNullValue()); + assertThat(channel.capturedResponse().status(), equalTo(RestStatus.FORBIDDEN)); + assertThat(channel.capturedResponse().content().utf8ToString(), containsString("current license is non-compliant for [security]")); + } + +}