From ab091fca239b6a879f73f980678b0e3397f62295 Mon Sep 17 00:00:00 2001 From: skkosuri-amzn Date: Tue, 25 Aug 2020 09:11:33 -0700 Subject: [PATCH] Added secure restclient, and other gradlew settings --- .eclipseformat.xml | 362 ++++++++++++++++++ README.md | 62 ++- backup | 87 +++++ build.gradle | 71 +++- spotless.license.java | 15 + .../commons/ConfigConstants.java | 19 +- .../commons/InjectSecurity.java | 69 +++- .../commons/rest/PemReader.java | 64 ++++ .../commons/rest/SecureRestClientBuilder.java | 182 +++++++++ .../commons/InjectSecurityTest.java | 42 +- 10 files changed, 918 insertions(+), 55 deletions(-) create mode 100644 .eclipseformat.xml create mode 100644 backup create mode 100644 spotless.license.java create mode 100644 src/main/java/com/amazon/opendistroforelasticsearch/commons/rest/PemReader.java create mode 100644 src/main/java/com/amazon/opendistroforelasticsearch/commons/rest/SecureRestClientBuilder.java diff --git a/.eclipseformat.xml b/.eclipseformat.xml new file mode 100644 index 00000000..30b5bdcc --- /dev/null +++ b/.eclipseformat.xml @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 847260ca..3923f115 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,61 @@ -## My Project +# Open Distro for Elasticsearch Common-Utils -TODO: Fill this README out! +Open Distro for Elasticsearch Common-Utils is focused on providing reusable Java components for Elasticsearch plugins. -Be sure to: +This library is composed of following parts: +1. SecureRestClientBuilder - provides methods to create secure low-level and high-level REST client. This is + useful to make secure REST calls to Elasticsearch or other plugin api's. +2. InjectSecurity - provides methods to inject user or roles. This is useful for running background jobs securely. -* Change the title in this README -* Edit your repository description on GitHub +Next: +3. IntegTestsWithSecurity - provides methods to create users, roles for running integ tests with security plugin. +4. Shared Request/Response/Action classes used for plugin to plugin transport layer calls. +5. Any common functionality across Elasticsearch plugins could be moved to this. -## Security -See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. +## Setup -## License +1. Check out this package from version control. +1. Launch Intellij IDEA, choose **Import Project**, and select the `settings.gradle` file in the root of this package. +1. To build from the command line, set `JAVA_HOME` to point to a JDK >= 14 before running `./gradlew`. -This project is licensed under the Apache-2.0 License. +## Build +[todo]: how to publish this project jar to maven/jcenter + + + +### Building from the command line +``` +./gradlew clean +./gradlew build + +./gradlew publishToMavenLocal +``` + +### Logging + +To change loglevel, add below to `config/log4j2.properties` or use REST API to set. +``` +logger.commons.name = com.amazon.opendistroforelasticsearch.commons +logger.commons.level = debug +``` + +## Code of Conduct + +This project has adopted an [Open Source Code of Conduct](https://opendistro.github.io/for-elasticsearch/codeofconduct.html). + + +## Security issue notifications + +If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public GitHub issue. + + +## Licensing + +See the [LICENSE](./LICENSE.txt) file for our project's licensing. We will ask you to confirm the licensing of your contribution. + + +## Copyright + +Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. \ No newline at end of file diff --git a/backup b/backup new file mode 100644 index 00000000..d907d1dc --- /dev/null +++ b/backup @@ -0,0 +1,87 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + +buildscript { + ext { + es_group = "org.elasticsearch" + es_version = '7.8.0' + } + + repositories { + mavenCentral() + maven { url "https://plugins.gradle.org/m2/" } + jcenter() + } + + dependencies { + classpath "${es_group}.gradle:build-tools:${es_version}" + } +} + +plugins { + id 'nebula.ospackage' version "8.3.0" apply false + id 'java-library' + id 'checkstyle' + id 'maven-publish' +} + +repositories { + mavenLocal() + mavenCentral() + maven { url "https://plugins.gradle.org/m2/" } + jcenter() +} + + +group 'com.amazon.opendistroforelasticsearch.commons' + + +sourceCompatibility = 1.8 + +ext { + es_version = '7.8.0' + opendistroVersion = '1.9.0' +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } + } +} + + +apply plugin: 'java' +apply plugin: 'idea' +apply plugin: 'base' +apply plugin: 'jacoco' + +dependencies { + testCompile group: 'junit', name: 'junit', version: '4.12' + compile "org.elasticsearch.client:elasticsearch-rest-high-level-client:${es_version}" +} + + +/* +spotless { + java { + removeUnusedImports() + importOrder 'java', 'javax', 'org', 'com' + licenseHeaderFile 'spotless.license.java' + + eclipse().configFile rootProject.file('.eclipseformat.xml') + } +}*/ diff --git a/build.gradle b/build.gradle index a99a2367..e39177a5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,16 +1,54 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + +buildscript { + ext { + es_group = "org.elasticsearch" + es_version = '7.8.0' + opendistroVersion = '1.9.0' + } + + repositories { + mavenCentral() + maven { url "https://plugins.gradle.org/m2/" } + jcenter() + } + + dependencies { + classpath "${es_group}.gradle:build-tools:${es_version}" + } +} + plugins { - id 'java' + id 'java-library' id 'maven-publish' + id "com.diffplug.gradle.spotless" version "3.26.1" +} + +repositories { + mavenLocal() + mavenCentral() + maven { url "https://plugins.gradle.org/m2/" } + jcenter() } group 'com.amazon.opendistroforelasticsearch.commons' -version '1.9.0.0' sourceCompatibility = 1.8 -ext { - es_version = '7.8.0' -} +version = "${opendistroVersion}.0" publishing { publications { @@ -19,14 +57,25 @@ publishing { } } } -repositories { - mavenLocal() - mavenCentral() - maven { url "https://plugins.gradle.org/m2/" } - jcenter() -} + +apply plugin: 'java' +apply plugin: 'idea' +apply plugin: 'base' +apply plugin: 'jacoco' + dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' compile "org.elasticsearch.client:elasticsearch-rest-high-level-client:${es_version}" + compile 'com.google.googlejavaformat:google-java-format:1.3' +} + +spotless { + java { + removeUnusedImports() + importOrder 'java', 'javax', 'org', 'com' + licenseHeaderFile 'spotless.license.java' + + eclipse().configFile rootProject.file('.eclipseformat.xml') + } } diff --git a/spotless.license.java b/spotless.license.java new file mode 100644 index 00000000..1df3fa69 --- /dev/null +++ b/spotless.license.java @@ -0,0 +1,15 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/commons/ConfigConstants.java b/src/main/java/com/amazon/opendistroforelasticsearch/commons/ConfigConstants.java index 2a3e522b..024b5c22 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/commons/ConfigConstants.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/commons/ConfigConstants.java @@ -1,3 +1,18 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 com.amazon.opendistroforelasticsearch.commons; public class ConfigConstants { @@ -11,9 +26,9 @@ public class ConfigConstants { public static final String CONTENT_TYPE_DEFAULT = "application/json"; public static final String AUTHORIZATION = "authorization"; - //These reside in security plugin. + // These reside in security plugin. public static final String OPENDISTRO_SECURITY_INJECTED_ROLES = "opendistro_security_injected_roles"; public static final String INJECTED_USER = "injected_user"; - public static final String OPENDISTRO_SECURITY_USE_INJECTED_USER_DEFAULT = "false"; + public static final String OPENDISTRO_SECURITY_USE_INJECTED_USER_FOR_PLUGINS = "opendistro_security_use_injected_user_for_plugins"; public static final String OPENDISTRO_SECURITY_SSL_HTTP_ENABLED = "opendistro_security.ssl.http.enabled"; } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/commons/InjectSecurity.java b/src/main/java/com/amazon/opendistroforelasticsearch/commons/InjectSecurity.java index ea529c77..329d54ec 100644 --- a/src/main/java/com/amazon/opendistroforelasticsearch/commons/InjectSecurity.java +++ b/src/main/java/com/amazon/opendistroforelasticsearch/commons/InjectSecurity.java @@ -1,22 +1,36 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 com.amazon.opendistroforelasticsearch.commons; +import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.INJECTED_USER; +import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES; +import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.OPENDISTRO_SECURITY_USE_INJECTED_USER_FOR_PLUGINS; + +import java.util.List; +import java.util.stream.Collectors; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.concurrent.ThreadContext; -import java.util.List; -import java.util.stream.Collectors; - -import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.INJECTED_USER; -import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES; -import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.OPENDISTRO_SECURITY_USE_INJECTED_USER_DEFAULT; - - /** - * For background jobs usage only. Roles injection can be done using transport layer only. - * You can't inject roles using REST api. + * For background jobs usage only. User or Roles injection can be done using transport layer only. + * You can't inject using REST api. * * Java example Usage: * @@ -69,6 +83,12 @@ public class InjectSecurity implements AutoCloseable { private Settings settings; private final Logger log = LogManager.getLogger(this.getClass()); + /** + * Create InjectSecurity object. This is auto-closeable. Id is used only for logging purpose. + * @param id + * @param settings + * @param tc + */ public InjectSecurity(String id, Settings settings, ThreadContext tc) { this.id = id; this.settings = settings; @@ -78,20 +98,29 @@ public InjectSecurity(String id, Settings settings, ThreadContext tc) { log.trace("{}, InjectSecurity constructor: {}", Thread.currentThread().getName(), id); } + /** + * Injects user or roles, based on opendistro_security_use_injected_user_for_plugins setting. By default injects roles. + * @param user + * @param roles + */ public void inject(final String user, final List roles) { - boolean injectUser = settings.getAsBoolean(OPENDISTRO_SECURITY_USE_INJECTED_USER_DEFAULT, false); - if( injectUser) + boolean injectUser = settings.getAsBoolean(OPENDISTRO_SECURITY_USE_INJECTED_USER_FOR_PLUGINS, false); + if (injectUser) injectUser(user); else injectRoles(roles); } + /** + * Injects user. + * @param user + */ public void injectUser(final String user) { - if(Strings.isNullOrEmpty(user)) { + if (Strings.isNullOrEmpty(user)) { return; } - if(threadContext.getTransient(INJECTED_USER) == null) { + if (threadContext.getTransient(INJECTED_USER) == null) { threadContext.putTransient(INJECTED_USER, user); log.debug("{}, InjectSecurity - inject roles: {}", Thread.currentThread().getName(), id); } else { @@ -99,14 +128,18 @@ public void injectUser(final String user) { } } + /** + * Injects roles. + * @param roles + */ public void injectRoles(final List roles) { - if(roles == null || roles.size() == 0) { + if (roles == null || roles.size() == 0) { return; } String rolesStr = roles.stream().collect(Collectors.joining(",")); - String injectStr = "plugin|"+rolesStr; - if(threadContext.getTransient(OPENDISTRO_SECURITY_INJECTED_ROLES) == null) { + String injectStr = "plugin|" + rolesStr; + if (threadContext.getTransient(OPENDISTRO_SECURITY_INJECTED_ROLES) == null) { threadContext.putTransient(OPENDISTRO_SECURITY_INJECTED_ROLES, injectStr); log.debug("{}, InjectSecurity - inject roles: {}", Thread.currentThread().getName(), id); } else { @@ -116,7 +149,7 @@ public void injectRoles(final List roles) { @Override public void close() { - if(ctx != null) { + if (ctx != null) { ctx.close(); log.debug("{}, InjectSecurity close : {}", Thread.currentThread().getName(), id); } diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/commons/rest/PemReader.java b/src/main/java/com/amazon/opendistroforelasticsearch/commons/rest/PemReader.java new file mode 100644 index 00000000..632d0fde --- /dev/null +++ b/src/main/java/com/amazon/opendistroforelasticsearch/commons/rest/PemReader.java @@ -0,0 +1,64 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 com.amazon.opendistroforelasticsearch.commons.rest; + +import java.io.FileInputStream; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Collection; + +/** + * Helper class to read raw pem files to keystore. + */ +public class PemReader { + public static X509Certificate[] loadCertificatesFromFile(String file) throws IOException, GeneralSecurityException { + if (file == null) { + return null; + } + CertificateFactory fact = CertificateFactory.getInstance("X.509"); + try (FileInputStream is = new FileInputStream(file)) { + Collection certs = fact.generateCertificates(is); + X509Certificate[] x509Certs = new X509Certificate[certs.size()]; + int i = 0; + for (Certificate cert : certs) { + x509Certs[i++] = (X509Certificate) cert; + } + return x509Certs; + } + } + + public static KeyStore toTruststore(final String trustCertificatesAliasPrefix, final X509Certificate[] trustCertificates) + throws IOException, + GeneralSecurityException { + if (trustCertificates == null) { + return null; + } + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null); + + if (trustCertificates != null && trustCertificates.length > 0) { + for (int i = 0; i < trustCertificates.length; i++) { + X509Certificate x509Certificate = trustCertificates[i]; + ks.setCertificateEntry(trustCertificatesAliasPrefix + "_" + i, x509Certificate); + } + } + return ks; + } +} diff --git a/src/main/java/com/amazon/opendistroforelasticsearch/commons/rest/SecureRestClientBuilder.java b/src/main/java/com/amazon/opendistroforelasticsearch/commons/rest/SecureRestClientBuilder.java new file mode 100644 index 00000000..2b510804 --- /dev/null +++ b/src/main/java/com/amazon/opendistroforelasticsearch/commons/rest/SecureRestClientBuilder.java @@ -0,0 +1,182 @@ +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 com.amazon.opendistroforelasticsearch.commons.rest; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.X509Certificate; + +import javax.net.ssl.SSLContext; + +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; +import org.apache.http.ssl.SSLContextBuilder; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.settings.Settings; + +import com.amazon.opendistroforelasticsearch.commons.ConfigConstants; + +/** + * Provides builder to create low-level and high-level REST client to make calls to Elasticsearch. + * + * Sample usage: + * SecureRestClientBuilder builder = new SecureRestClientBuilder(settings).build() + * RestClient restClient = builder.build(); + * + * Other usage: + * RestClient restClient = new SecureRestClientBuilder("localhost", 9200, false) + * .setUserPassword("admin", "admin") + * .setTrustCerts(trustStorePath) + * .build(); + * + * + * If https is enabled, creates RestClientBuilder using self-signed certificates or passed pem + * as trusted. + * + * If https is not enabled, creates a http based client. + + * * todo: make the cert configurable, rather than hardcoded to self-signed. + * * + */ +public class SecureRestClientBuilder { + + private final boolean httpSSLEnabled; + private final int port; + private final String host; + + private String trustCerts = null; + private String user = null; + private String passwd = null; + + public SecureRestClientBuilder(Settings settings) { + host = ConfigConstants.HOST_DEFAULT; + port = settings.getAsInt(ConfigConstants.HTTP_PORT, ConfigConstants.HTTP_PORT_DEFAULT); + httpSSLEnabled = settings.getAsBoolean(ConfigConstants.OPENDISTRO_SECURITY_SSL_HTTP_ENABLED, false); + } + + public SecureRestClientBuilder(final String host, final int port, final boolean httpSSLEnabled) { + this.host = host; + this.port = port; + this.httpSSLEnabled = httpSSLEnabled; + } + + /** + * Creates a low-level Rest client. + * @return + * @throws IOException + */ + public RestClient build() throws IOException { + return createRestClientBuilder().build(); + } + + /** + * Creates a high-level Rest client. + * @return + * @throws IOException + */ + public RestHighLevelClient buildHighlevelClient() throws IOException { + return new RestHighLevelClient(createRestClientBuilder()); + } + + /** + * Pass pem cert. If null passed, uses TrustSelfSignedStrategy (trust strategy that accepts self-signed certificates as trusted). + * @param cert + * @return + */ + public SecureRestClientBuilder setTrustCerts(final String cert) { + this.trustCerts = cert; + return this; + } + + /** + * User name and password for credentials. ONLY for integ tests. + * @param user + * @param passwd + * @return + * @throws IOException + */ + public SecureRestClientBuilder setUserPassword(final String user, final String passwd) throws IOException { + if (Strings.isNullOrEmpty(user) || Strings.isNullOrEmpty(passwd)) { + throw new IOException("Invalid user or password"); + } + this.user = user; + this.passwd = passwd; + return this; + } + + private RestClientBuilder createRestClientBuilder() throws IOException { + RestClientBuilder builder = RestClient.builder(createHttpHost()); + final SSLContext sslContext; + try { + sslContext = createSSLContext(); + } catch (GeneralSecurityException | IOException ex) { + throw new IOException(ex); + } + final CredentialsProvider credentialsProvider = createCredsProvider(); + builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { + @Override + public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { + if (sslContext != null) { + httpClientBuilder.setSSLContext(sslContext); + } + if (credentialsProvider != null) { + httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + } + return httpClientBuilder; + } + }); + return builder; + } + + private HttpHost createHttpHost() { + return new HttpHost(host, port, httpSSLEnabled ? ConfigConstants.HTTPS : ConfigConstants.HTTP); + } + + private SSLContext createSSLContext() throws IOException, GeneralSecurityException { + SSLContextBuilder builder = new SSLContextBuilder(); + if (httpSSLEnabled) { + if (trustCerts == null) { + builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); + } else { + final String effectiveKeyAlias = "al"; + X509Certificate[] trustCertificates; + KeyStore trustStore; + trustCertificates = PemReader.loadCertificatesFromFile(trustCerts); + trustStore = PemReader.toTruststore(effectiveKeyAlias, trustCertificates); + builder.loadTrustMaterial(trustStore, null); + } + } + return builder.build(); + } + + private CredentialsProvider createCredsProvider() { + if (Strings.isNullOrEmpty(user) || Strings.isNullOrEmpty(passwd)) + return null; + + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, passwd)); + return credentialsProvider; + } +} diff --git a/src/test/java/com/amazon/opendistroforelasticsearch/commons/InjectSecurityTest.java b/src/test/java/com/amazon/opendistroforelasticsearch/commons/InjectSecurityTest.java index 67f53eed..28e78904 100644 --- a/src/test/java/com/amazon/opendistroforelasticsearch/commons/InjectSecurityTest.java +++ b/src/test/java/com/amazon/opendistroforelasticsearch/commons/InjectSecurityTest.java @@ -1,26 +1,40 @@ -package com.amazon.opendistroforelasticsearch.commons; - -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.util.concurrent.ThreadContext; -import org.junit.Assert; -import org.junit.Test; +/* + * Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ - -import java.util.Arrays; +package com.amazon.opendistroforelasticsearch.commons; import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.INJECTED_USER; import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.OPENDISTRO_SECURITY_INJECTED_ROLES; -import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.OPENDISTRO_SECURITY_USE_INJECTED_USER_DEFAULT; +import static com.amazon.opendistroforelasticsearch.commons.ConfigConstants.OPENDISTRO_SECURITY_USE_INJECTED_USER_FOR_PLUGINS; import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertNull; import static org.junit.Assert.assertEquals; +import java.util.Arrays; + +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.junit.Assert; +import org.junit.Test; + public class InjectSecurityTest { @Test public void testUsersRolesEmpty() { ThreadContext tc = new ThreadContext(Settings.EMPTY); - try(InjectSecurity helper = new InjectSecurity("test-name", Settings.EMPTY,tc)) { + try (InjectSecurity helper = new InjectSecurity("test-name", Settings.EMPTY, tc)) { helper.inject("", null); } Assert.assertNull(tc.getTransient(OPENDISTRO_SECURITY_INJECTED_ROLES)); @@ -39,7 +53,7 @@ public void testInjectRoles() { assertEquals("plugin", threadContext.getTransient("ctx.name")); try (InjectSecurity helper = new InjectSecurity("test-name", settings, threadContext)) { - helper.inject("joe", Arrays.asList("ops-role","logs-role")); + helper.inject("joe", Arrays.asList("ops-role", "logs-role")); assertEquals("1", threadContext.getHeader("default")); assertEquals("opendistro", threadContext.getHeader("name")); assertEquals("plugin", threadContext.getTransient("ctx.name")); @@ -54,9 +68,7 @@ public void testInjectRoles() { @Test public void testInjectUser() { - Settings settings = Settings.builder() - .put(OPENDISTRO_SECURITY_USE_INJECTED_USER_DEFAULT, true) - .build(); + Settings settings = Settings.builder().put(OPENDISTRO_SECURITY_USE_INJECTED_USER_FOR_PLUGINS, true).build(); Settings headerSettings = Settings.builder().put("request.headers.default", "1").build(); ThreadContext threadContext = new ThreadContext(headerSettings); threadContext.putHeader("name", "opendistro"); @@ -67,7 +79,7 @@ public void testInjectUser() { assertEquals("plugin", threadContext.getTransient("ctx.name")); try (InjectSecurity helper = new InjectSecurity("test-name", settings, threadContext)) { - helper.inject("joe", Arrays.asList("ops-role","logs-role")); + helper.inject("joe", Arrays.asList("ops-role", "logs-role")); assertEquals("1", threadContext.getHeader("default")); assertEquals("opendistro", threadContext.getHeader("name")); assertEquals("plugin", threadContext.getTransient("ctx.name"));