From 47d6c1cf6473a46f319999d658d6b3c3e8e51764 Mon Sep 17 00:00:00 2001 From: Rabi Panda Date: Mon, 1 Feb 2021 13:03:04 -0800 Subject: [PATCH] [PURIFY] Remove the AuthorizationEnginePlugin from examples. --- .../build.gradle | 31 --- .../example/CustomAuthorizationEngineIT.java | 163 ------------ .../CustomAuthorizationEngineTests.java | 188 -------------- .../example/AuthorizationEnginePlugin.java | 30 --- .../example/CustomAuthorizationEngine.java | 238 ------------------ .../ExampleAuthorizationEngineExtension.java | 35 --- ...arch.xpack.core.security.SecurityExtension | 1 - 7 files changed, 686 deletions(-) delete mode 100644 plugins/examples/security-authorization-engine/build.gradle delete mode 100644 plugins/examples/security-authorization-engine/src/javaRestTest/java/org/elasticsearch/example/CustomAuthorizationEngineIT.java delete mode 100644 plugins/examples/security-authorization-engine/src/javaRestTest/java/org/elasticsearch/example/CustomAuthorizationEngineTests.java delete mode 100644 plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/AuthorizationEnginePlugin.java delete mode 100644 plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/CustomAuthorizationEngine.java delete mode 100644 plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/ExampleAuthorizationEngineExtension.java delete mode 100644 plugins/examples/security-authorization-engine/src/main/resources/META-INF/services/org.elasticsearch.xpack.core.security.SecurityExtension diff --git a/plugins/examples/security-authorization-engine/build.gradle b/plugins/examples/security-authorization-engine/build.gradle deleted file mode 100644 index 41d01e68d031d..0000000000000 --- a/plugins/examples/security-authorization-engine/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -// apply plugin: 'elasticsearch.esplugin' -// apply plugin: 'elasticsearch.java-rest-test' - -// esplugin { -// name 'security-authorization-engine' -// description 'An example spi extension plugin for security that implements an Authorization Engine' -// classname 'org.elasticsearch.example.AuthorizationEnginePlugin' -// licenseFile rootProject.file('licenses/APACHE-LICENSE-2.0.txt') -// noticeFile rootProject.file('NOTICE.txt') -// } - -// dependencies { -// // let the javaRestTest see the classpath of main -// javaRestTestImplementation project.sourceSets.main.runtimeClasspath -// } -// //no unit tests -// test.enabled = false -// javaRestTest { -// dependsOn buildZip -// systemProperty 'tests.security.manager', 'false' -// } - -// testClusters.javaRestTest { -// // This is important, so that all the modules are available too. -// // There are index templates that use token filters that are in analysis-module and -// // processors are being used that are in ingest-common module. -// testDistribution = 'DEFAULT' - -// user role: 'custom_superuser' -// } - diff --git a/plugins/examples/security-authorization-engine/src/javaRestTest/java/org/elasticsearch/example/CustomAuthorizationEngineIT.java b/plugins/examples/security-authorization-engine/src/javaRestTest/java/org/elasticsearch/example/CustomAuthorizationEngineIT.java deleted file mode 100644 index 9daf9bd01a8bc..0000000000000 --- a/plugins/examples/security-authorization-engine/src/javaRestTest/java/org/elasticsearch/example/CustomAuthorizationEngineIT.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.example; - -import org.apache.http.util.EntityUtils; -import org.elasticsearch.client.Request; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.ResponseException; -import org.elasticsearch.common.network.NetworkModule; -import org.elasticsearch.common.settings.SecureString; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.test.ESIntegTestCase; -import org.elasticsearch.xpack.core.XPackClientPlugin; -import org.elasticsearch.xpack.core.security.authc.support.Hasher; -import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken; -import org.elasticsearch.xpack.core.security.client.SecurityClient; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.Collection; -import java.util.Collections; - -import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.is; - -/** - * Integration tests for the custom authorization engine. These tests are meant to be run against - * an external cluster with the custom authorization plugin installed to validate the functionality - * when running as a plugin - */ -public class CustomAuthorizationEngineIT extends ESIntegTestCase { - - @Override - protected Settings externalClusterClientSettings() { - final String token = "Basic " + - Base64.getEncoder().encodeToString(("test_user:x-pack-test-password").getBytes(StandardCharsets.UTF_8)); - return Settings.builder() - .put(ThreadContext.PREFIX + ".Authorization", token) - .put(NetworkModule.TRANSPORT_TYPE_KEY, "security4") - .build(); - } - - @Override - protected Collection> transportClientPlugins() { - return Collections.singleton(XPackClientPlugin.class); - } - - public void testClusterAction() throws IOException { - SecurityClient securityClient = new SecurityClient(client()); - securityClient.preparePutUser("custom_user", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "custom_superuser").get(); - - { - RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder(); - options.addHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, - basicAuthHeaderValue("custom_user", new SecureString("x-pack-test-password".toCharArray()))); - Request request = new Request("GET", "_cluster/health"); - request.setOptions(options); - Response response = getRestClient().performRequest(request); - assertThat(response.getStatusLine().getStatusCode(), is(200)); - } - - { - securityClient.preparePutUser("custom_user2", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "not_superuser").get(); - RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder(); - options.addHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, - basicAuthHeaderValue("custom_user2", new SecureString("x-pack-test-password".toCharArray()))); - Request request = new Request("GET", "_cluster/health"); - request.setOptions(options); - ResponseException e = expectThrows(ResponseException.class, () -> getRestClient().performRequest(request)); - assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403)); - } - } - - public void testIndexAction() throws IOException { - SecurityClient securityClient = new SecurityClient(client()); - securityClient.preparePutUser("custom_user", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "custom_superuser").get(); - - { - RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder(); - options.addHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, - basicAuthHeaderValue("custom_user", new SecureString("x-pack-test-password".toCharArray()))); - Request request = new Request("PUT", "/index"); - request.setOptions(options); - Response response = getRestClient().performRequest(request); - assertThat(response.getStatusLine().getStatusCode(), is(200)); - } - - { - securityClient.preparePutUser("custom_user2", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "not_superuser").get(); - RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder(); - options.addHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, - basicAuthHeaderValue("custom_user2", new SecureString("x-pack-test-password".toCharArray()))); - Request request = new Request("PUT", "/index"); - request.setOptions(options); - ResponseException e = expectThrows(ResponseException.class, () -> getRestClient().performRequest(request)); - assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403)); - } - } - - public void testRunAs() throws IOException { - SecurityClient securityClient = new SecurityClient(client()); - securityClient.preparePutUser("custom_user", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "custom_superuser").get(); - securityClient.preparePutUser("custom_user2", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "custom_superuser").get(); - securityClient.preparePutUser("custom_user3", "x-pack-test-password".toCharArray(), Hasher.BCRYPT, "not_superuser").get(); - - { - RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder(); - options.addHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, - basicAuthHeaderValue("custom_user", new SecureString("x-pack-test-password".toCharArray()))); - options.addHeader("es-security-runas-user", "custom_user2"); - Request request = new Request("GET", "/_security/_authenticate"); - request.setOptions(options); - Response response = getRestClient().performRequest(request); - assertThat(response.getStatusLine().getStatusCode(), is(200)); - String responseStr = EntityUtils.toString(response.getEntity()); - assertThat(responseStr, containsString("custom_user2")); - } - - { - RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder(); - options.addHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, - basicAuthHeaderValue("custom_user", new SecureString("x-pack-test-password".toCharArray()))); - options.addHeader("es-security-runas-user", "custom_user3"); - Request request = new Request("PUT", "/index"); - request.setOptions(options); - ResponseException e = expectThrows(ResponseException.class, () -> getRestClient().performRequest(request)); - assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403)); - } - - { - RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder(); - options.addHeader(UsernamePasswordToken.BASIC_AUTH_HEADER, - basicAuthHeaderValue("custom_user3", new SecureString("x-pack-test-password".toCharArray()))); - options.addHeader("es-security-runas-user", "custom_user2"); - Request request = new Request("PUT", "/index"); - request.setOptions(options); - ResponseException e = expectThrows(ResponseException.class, () -> getRestClient().performRequest(request)); - assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403)); - } - } -} diff --git a/plugins/examples/security-authorization-engine/src/javaRestTest/java/org/elasticsearch/example/CustomAuthorizationEngineTests.java b/plugins/examples/security-authorization-engine/src/javaRestTest/java/org/elasticsearch/example/CustomAuthorizationEngineTests.java deleted file mode 100644 index f9b181d9dcbb0..0000000000000 --- a/plugins/examples/security-authorization-engine/src/javaRestTest/java/org/elasticsearch/example/CustomAuthorizationEngineTests.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.example; - -import org.elasticsearch.Version; -import org.elasticsearch.action.search.SearchRequest; -import org.elasticsearch.action.support.PlainActionFuture; -import org.elasticsearch.cluster.metadata.IndexAbstraction; -import org.elasticsearch.cluster.metadata.IndexAbstraction.Index; -import org.elasticsearch.cluster.metadata.IndexMetadata; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.transport.TransportRequest; -import org.elasticsearch.xpack.core.security.authc.Authentication; -import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef; -import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.AuthorizationInfo; -import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.AuthorizationResult; -import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.IndexAuthorizationResult; -import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.RequestInfo; -import org.elasticsearch.xpack.core.security.authz.ResolvedIndices; -import org.elasticsearch.xpack.core.security.authz.accesscontrol.IndicesAccessControl; -import org.elasticsearch.xpack.core.security.user.User; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import static org.hamcrest.Matchers.is; - -/** - * Unit tests for the custom authorization engine. These are basic tests that validate the - * engine's functionality outside of being used by the AuthorizationService - */ -public class CustomAuthorizationEngineTests extends ESTestCase { - - public void testGetAuthorizationInfo() { - PlainActionFuture future = new PlainActionFuture<>(); - CustomAuthorizationEngine engine = new CustomAuthorizationEngine(); - engine.resolveAuthorizationInfo(getRequestInfo(), future); - assertNotNull(future.actionGet()); - } - - public void testAuthorizeRunAs() { - final String action = "cluster:monitor/foo"; - final TransportRequest request = new TransportRequest() {}; - CustomAuthorizationEngine engine = new CustomAuthorizationEngine(); - // unauthorized - { - Authentication authentication = - new Authentication(new User("joe", new String[]{"custom_superuser"}, new User("bar", "not_superuser")), - new RealmRef("test", "test", "node"), new RealmRef("test", "test", "node")); - RequestInfo info = new RequestInfo(authentication, request, action); - PlainActionFuture future = new PlainActionFuture<>(); - engine.resolveAuthorizationInfo(info, future); - AuthorizationInfo authzInfo = future.actionGet(); - - PlainActionFuture resultFuture = new PlainActionFuture<>(); - engine.authorizeRunAs(info, authzInfo, resultFuture); - AuthorizationResult result = resultFuture.actionGet(); - assertThat(result.isGranted(), is(false)); - assertThat(result.isAuditable(), is(true)); - } - - // authorized - { - Authentication authentication = - new Authentication(new User("joe", new String[]{"not_superuser"}, new User("bar", "custom_superuser")), - new RealmRef("test", "test", "node"), new RealmRef("test", "test", "node")); - RequestInfo info = new RequestInfo(authentication, request, action); - PlainActionFuture future = new PlainActionFuture<>(); - engine.resolveAuthorizationInfo(info, future); - AuthorizationInfo authzInfo = future.actionGet(); - PlainActionFuture resultFuture = new PlainActionFuture<>(); - engine.authorizeRunAs(info, authzInfo, resultFuture); - AuthorizationResult result = resultFuture.actionGet(); - assertThat(result.isGranted(), is(true)); - assertThat(result.isAuditable(), is(true)); - } - } - - public void testAuthorizeClusterAction() { - CustomAuthorizationEngine engine = new CustomAuthorizationEngine(); - RequestInfo requestInfo = getRequestInfo(); - // authorized - { - PlainActionFuture future = new PlainActionFuture<>(); - engine.resolveAuthorizationInfo(requestInfo, future); - AuthorizationInfo authzInfo = future.actionGet(); - - PlainActionFuture resultFuture = new PlainActionFuture<>(); - engine.authorizeClusterAction(requestInfo, authzInfo, resultFuture); - AuthorizationResult result = resultFuture.actionGet(); - assertThat(result.isGranted(), is(true)); - assertThat(result.isAuditable(), is(true)); - } - - // unauthorized - { - RequestInfo unauthReqInfo = - new RequestInfo(new Authentication(new User("joe", "not_superuser"), new RealmRef("test", "test", "node"), null), - requestInfo.getRequest(), requestInfo.getAction()); - PlainActionFuture future = new PlainActionFuture<>(); - engine.resolveAuthorizationInfo(unauthReqInfo, future); - AuthorizationInfo authzInfo = future.actionGet(); - - PlainActionFuture resultFuture = new PlainActionFuture<>(); - engine.authorizeClusterAction(unauthReqInfo, authzInfo, resultFuture); - AuthorizationResult result = resultFuture.actionGet(); - assertThat(result.isGranted(), is(false)); - assertThat(result.isAuditable(), is(true)); - } - } - - public void testAuthorizeIndexAction() { - CustomAuthorizationEngine engine = new CustomAuthorizationEngine(); - Map indicesMap = new HashMap<>(); - indicesMap.put("index", new Index(IndexMetadata.builder("index") - .settings(Settings.builder().put("index.version.created", Version.CURRENT)) - .numberOfShards(1) - .numberOfReplicas(0) - .build())); - // authorized - { - RequestInfo requestInfo = - new RequestInfo(new Authentication(new User("joe", "custom_superuser"), new RealmRef("test", "test", "node"), null), - new SearchRequest(), "indices:data/read/search"); - PlainActionFuture future = new PlainActionFuture<>(); - engine.resolveAuthorizationInfo(requestInfo, future); - AuthorizationInfo authzInfo = future.actionGet(); - - PlainActionFuture resultFuture = new PlainActionFuture<>(); - engine.authorizeIndexAction(requestInfo, authzInfo, - listener -> listener.onResponse(new ResolvedIndices(Collections.singletonList("index"), Collections.emptyList())), - indicesMap, resultFuture); - IndexAuthorizationResult result = resultFuture.actionGet(); - assertThat(result.isGranted(), is(true)); - assertThat(result.isAuditable(), is(true)); - IndicesAccessControl indicesAccessControl = result.getIndicesAccessControl(); - assertNotNull(indicesAccessControl.getIndexPermissions("index")); - assertThat(indicesAccessControl.getIndexPermissions("index").isGranted(), is(true)); - } - - // unauthorized - { - RequestInfo requestInfo = - new RequestInfo(new Authentication(new User("joe", "not_superuser"), new RealmRef("test", "test", "node"), null), - new SearchRequest(), "indices:data/read/search"); - PlainActionFuture future = new PlainActionFuture<>(); - engine.resolveAuthorizationInfo(requestInfo, future); - AuthorizationInfo authzInfo = future.actionGet(); - - PlainActionFuture resultFuture = new PlainActionFuture<>(); - engine.authorizeIndexAction(requestInfo, authzInfo, - listener -> listener.onResponse(new ResolvedIndices(Collections.singletonList("index"), Collections.emptyList())), - indicesMap, resultFuture); - IndexAuthorizationResult result = resultFuture.actionGet(); - assertThat(result.isGranted(), is(false)); - assertThat(result.isAuditable(), is(true)); - IndicesAccessControl indicesAccessControl = result.getIndicesAccessControl(); - assertNull(indicesAccessControl.getIndexPermissions("index")); - } - } - - private RequestInfo getRequestInfo() { - final String action = "cluster:monitor/foo"; - final TransportRequest request = new TransportRequest() {}; - final Authentication authentication = - new Authentication(new User("joe", "custom_superuser"), new RealmRef("test", "test", "node"), null); - return new RequestInfo(authentication, request, action); - } -} diff --git a/plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/AuthorizationEnginePlugin.java b/plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/AuthorizationEnginePlugin.java deleted file mode 100644 index 1878bb90a0c85..0000000000000 --- a/plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/AuthorizationEnginePlugin.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.example; - -import org.elasticsearch.plugins.ActionPlugin; -import org.elasticsearch.plugins.Plugin; - -/** - * Plugin class that is required so that the code contained here may be loaded as a plugin. - * Additional items such as settings and actions can be registered using this plugin class. - */ -public class AuthorizationEnginePlugin extends Plugin implements ActionPlugin { -} diff --git a/plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/CustomAuthorizationEngine.java b/plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/CustomAuthorizationEngine.java deleted file mode 100644 index 3e2756c5ba80b..0000000000000 --- a/plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/CustomAuthorizationEngine.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.example; - -import org.elasticsearch.action.ActionListener; -import org.elasticsearch.cluster.metadata.IndexAbstraction; -import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesRequest; -import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesResponse; -import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesResponse.Indices; -import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesRequest; -import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesResponse; -import org.elasticsearch.xpack.core.security.authc.Authentication; -import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine; -import org.elasticsearch.xpack.core.security.authz.ResolvedIndices; -import org.elasticsearch.xpack.core.security.authz.RoleDescriptor; -import org.elasticsearch.xpack.core.security.authz.RoleDescriptor.IndicesPrivileges; -import org.elasticsearch.xpack.core.security.authz.accesscontrol.IndicesAccessControl; -import org.elasticsearch.xpack.core.security.authz.accesscontrol.IndicesAccessControl.IndexAccessControl; -import org.elasticsearch.xpack.core.security.authz.permission.FieldPermissions; -import org.elasticsearch.xpack.core.security.authz.permission.ResourcePrivileges; -import org.elasticsearch.xpack.core.security.authz.privilege.ApplicationPrivilegeDescriptor; -import org.elasticsearch.xpack.core.security.authz.privilege.ConfigurableClusterPrivilege; -import org.elasticsearch.xpack.core.security.user.User; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * A custom implementation of an authorization engine. This engine is extremely basic in that it - * authorizes based upon the name of a single role. If users have this role they are granted access. - */ -public class CustomAuthorizationEngine implements AuthorizationEngine { - - @Override - public void resolveAuthorizationInfo(RequestInfo requestInfo, ActionListener listener) { - final Authentication authentication = requestInfo.getAuthentication(); - if (authentication.getUser().isRunAs()) { - final CustomAuthorizationInfo authenticatedUserAuthzInfo = - new CustomAuthorizationInfo(authentication.getUser().authenticatedUser().roles(), null); - listener.onResponse(new CustomAuthorizationInfo(authentication.getUser().roles(), authenticatedUserAuthzInfo)); - } else { - listener.onResponse(new CustomAuthorizationInfo(authentication.getUser().roles(), null)); - } - } - - @Override - public void authorizeRunAs(RequestInfo requestInfo, AuthorizationInfo authorizationInfo, ActionListener listener) { - if (isSuperuser(requestInfo.getAuthentication().getUser().authenticatedUser())) { - listener.onResponse(AuthorizationResult.granted()); - } else { - listener.onResponse(AuthorizationResult.deny()); - } - } - - @Override - public void authorizeClusterAction(RequestInfo requestInfo, AuthorizationInfo authorizationInfo, - ActionListener listener) { - if (isSuperuser(requestInfo.getAuthentication().getUser())) { - listener.onResponse(AuthorizationResult.granted()); - } else { - listener.onResponse(AuthorizationResult.deny()); - } - } - - @Override - public void authorizeIndexAction(RequestInfo requestInfo, AuthorizationInfo authorizationInfo, - AsyncSupplier indicesAsyncSupplier, - Map aliasOrIndexLookup, - ActionListener listener) { - if (isSuperuser(requestInfo.getAuthentication().getUser())) { - indicesAsyncSupplier.getAsync(ActionListener.wrap(resolvedIndices -> { - Map indexAccessControlMap = new HashMap<>(); - for (String name : resolvedIndices.getLocal()) { - indexAccessControlMap.put(name, new IndexAccessControl(true, FieldPermissions.DEFAULT, null)); - } - IndicesAccessControl indicesAccessControl = - new IndicesAccessControl(true, Collections.unmodifiableMap(indexAccessControlMap)); - listener.onResponse(new IndexAuthorizationResult(true, indicesAccessControl)); - }, listener::onFailure)); - } else { - listener.onResponse(new IndexAuthorizationResult(true, IndicesAccessControl.DENIED)); - } - } - - @Override - public void loadAuthorizedIndices(RequestInfo requestInfo, AuthorizationInfo authorizationInfo, - Map indicesLookup, ActionListener> listener) { - if (isSuperuser(requestInfo.getAuthentication().getUser())) { - listener.onResponse(new ArrayList<>(indicesLookup.keySet())); - } else { - listener.onResponse(Collections.emptyList()); - } - } - - @Override - public void validateIndexPermissionsAreSubset(RequestInfo requestInfo, AuthorizationInfo authorizationInfo, - Map> indexNameToNewNames, - ActionListener listener) { - if (isSuperuser(requestInfo.getAuthentication().getUser())) { - listener.onResponse(AuthorizationResult.granted()); - } else { - listener.onResponse(AuthorizationResult.deny()); - } - } - - @Override - public void checkPrivileges(Authentication authentication, AuthorizationInfo authorizationInfo, - HasPrivilegesRequest hasPrivilegesRequest, - Collection applicationPrivilegeDescriptors, - ActionListener listener) { - if (isSuperuser(authentication.getUser())) { - listener.onResponse(getHasPrivilegesResponse(authentication, hasPrivilegesRequest, true)); - } else { - listener.onResponse(getHasPrivilegesResponse(authentication, hasPrivilegesRequest, false)); - } - } - - @Override - public void getUserPrivileges(Authentication authentication, AuthorizationInfo authorizationInfo, GetUserPrivilegesRequest request, - ActionListener listener) { - if (isSuperuser(authentication.getUser())) { - listener.onResponse(getUserPrivilegesResponse(true)); - } else { - listener.onResponse(getUserPrivilegesResponse(false)); - } - } - - private HasPrivilegesResponse getHasPrivilegesResponse(Authentication authentication, HasPrivilegesRequest hasPrivilegesRequest, - boolean authorized) { - Map clusterPrivMap = new HashMap<>(); - for (String clusterPriv : hasPrivilegesRequest.clusterPrivileges()) { - clusterPrivMap.put(clusterPriv, authorized); - } - final Map indices = new LinkedHashMap<>(); - for (IndicesPrivileges check : hasPrivilegesRequest.indexPrivileges()) { - for (String index : check.getIndices()) { - final Map privileges = new HashMap<>(); - final ResourcePrivileges existing = indices.get(index); - if (existing != null) { - privileges.putAll(existing.getPrivileges()); - } - for (String privilege : check.getPrivileges()) { - privileges.put(privilege, authorized); - } - indices.put(index, ResourcePrivileges.builder(index).addPrivileges(privileges).build()); - } - } - final Map> privilegesByApplication = new HashMap<>(); - Set applicationNames = Arrays.stream(hasPrivilegesRequest.applicationPrivileges()) - .map(RoleDescriptor.ApplicationResourcePrivileges::getApplication) - .collect(Collectors.toSet()); - for (String applicationName : applicationNames) { - final Map appPrivilegesByResource = new LinkedHashMap<>(); - for (RoleDescriptor.ApplicationResourcePrivileges p : hasPrivilegesRequest.applicationPrivileges()) { - if (applicationName.equals(p.getApplication())) { - for (String resource : p.getResources()) { - final Map privileges = new HashMap<>(); - final ResourcePrivileges existing = appPrivilegesByResource.get(resource); - if (existing != null) { - privileges.putAll(existing.getPrivileges()); - } - for (String privilege : p.getPrivileges()) { - privileges.put(privilege, authorized); - } - appPrivilegesByResource.put(resource, ResourcePrivileges.builder(resource).addPrivileges(privileges).build()); - } - } - } - privilegesByApplication.put(applicationName, appPrivilegesByResource.values()); - } - return new HasPrivilegesResponse(authentication.getUser().principal(), authorized, clusterPrivMap, indices.values(), - privilegesByApplication); - } - - private GetUserPrivilegesResponse getUserPrivilegesResponse(boolean isSuperuser) { - final Set cluster = isSuperuser ? Collections.singleton("ALL") : Collections.emptySet(); - final Set conditionalCluster = Collections.emptySet(); - final Set indices = isSuperuser ? Collections.singleton(new Indices(Collections.singleton("*"), - Collections.singleton("*"), Collections.emptySet(), Collections.emptySet(), true)) : Collections.emptySet(); - - final Set application = isSuperuser ? - Collections.singleton( - RoleDescriptor.ApplicationResourcePrivileges.builder().application("*").privileges("*").resources("*").build()) : - Collections.emptySet(); - final Set runAs = isSuperuser ? Collections.singleton("*") : Collections.emptySet(); - return new GetUserPrivilegesResponse(cluster, conditionalCluster, indices, application, runAs); - } - - public static class CustomAuthorizationInfo implements AuthorizationInfo { - - private final String[] roles; - private final CustomAuthorizationInfo authenticatedAuthzInfo; - - CustomAuthorizationInfo(String[] roles, CustomAuthorizationInfo authenticatedAuthzInfo) { - this.roles = roles; - this.authenticatedAuthzInfo = authenticatedAuthzInfo; - } - - @Override - public Map asMap() { - return Collections.singletonMap("roles", roles); - } - - @Override - public CustomAuthorizationInfo getAuthenticatedUserAuthorizationInfo() { - return authenticatedAuthzInfo; - } - } - - private boolean isSuperuser(User user) { - return Arrays.asList(user.roles()).contains("custom_superuser"); - } -} diff --git a/plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/ExampleAuthorizationEngineExtension.java b/plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/ExampleAuthorizationEngineExtension.java deleted file mode 100644 index cba064fae27ad..0000000000000 --- a/plugins/examples/security-authorization-engine/src/main/java/org/elasticsearch/example/ExampleAuthorizationEngineExtension.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -package org.elasticsearch.example; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.xpack.core.security.SecurityExtension; -import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine; - -/** - * Security extension class that registers the custom authorization engine to be used - */ -public class ExampleAuthorizationEngineExtension implements SecurityExtension { - - @Override - public AuthorizationEngine getAuthorizationEngine(Settings settings) { - return new CustomAuthorizationEngine(); - } -} diff --git a/plugins/examples/security-authorization-engine/src/main/resources/META-INF/services/org.elasticsearch.xpack.core.security.SecurityExtension b/plugins/examples/security-authorization-engine/src/main/resources/META-INF/services/org.elasticsearch.xpack.core.security.SecurityExtension deleted file mode 100644 index 73029aef8fd63..0000000000000 --- a/plugins/examples/security-authorization-engine/src/main/resources/META-INF/services/org.elasticsearch.xpack.core.security.SecurityExtension +++ /dev/null @@ -1 +0,0 @@ -org.elasticsearch.example.ExampleAuthorizationEngineExtension \ No newline at end of file