{
}
internalTypes.add(type);
}
+ if (KerberosRealmSettings.TYPE.equals(type)) {
+ kerberosRealmNames.add(name);
+ if (kerberosRealmNames.size() > 1) {
+ throw new IllegalArgumentException("multiple realms " + kerberosRealmNames.toString() + " configured of type [" + type
+ + "], [" + type + "] can only have one such realm configured");
+ }
+ }
realms.add(factory.create(config));
}
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ESNativeRealmMigrateTool.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ESNativeRealmMigrateTool.java
index 4226607f192..f28fe1c297f 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ESNativeRealmMigrateTool.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/esnative/ESNativeRealmMigrateTool.java
@@ -363,9 +363,16 @@ public class ESNativeRealmMigrateTool extends LoggingAwareMultiCommand {
final Logger logger = ESLoggerFactory.getLogger(ESNativeRealmMigrateTool.class);
Loggers.setLevel(logger, Level.ALL);
+ final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
+ final Configuration config = ctx.getConfiguration();
+
// create appender
final Appender appender = new AbstractAppender(ESNativeRealmMigrateTool.class.getName(), null,
- PatternLayout.newBuilder().withPattern("%m").build()) {
+ PatternLayout.newBuilder()
+ // Specify the configuration so log4j doesn't re-initialize
+ .withConfiguration(config)
+ .withPattern("%m")
+ .build()) {
@Override
public void append(LogEvent event) {
switch (event.getLevel().getStandardLevel()) {
@@ -384,8 +391,6 @@ public class ESNativeRealmMigrateTool extends LoggingAwareMultiCommand {
appender.start();
// get the config, detach from parent, remove appenders, add custom appender
- final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
- final Configuration config = ctx.getConfiguration();
final LoggerConfig loggerConfig = config.getLoggerConfig(ESNativeRealmMigrateTool.class.getName());
loggerConfig.setParent(null);
loggerConfig.getAppenders().forEach((s, a) -> Loggers.removeAppender(logger, a));
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealm.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealm.java
index b4a8b6aabf0..71eeb8b2398 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealm.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealm.java
@@ -25,6 +25,7 @@ import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;
import org.elasticsearch.xpack.security.authc.support.mapper.NativeRoleMappingStore;
import org.ietf.jgss.GSSException;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
@@ -87,6 +88,16 @@ public final class KerberosRealm extends Realm implements CachingRealm {
this.kerberosTicketValidator = kerberosTicketValidator;
this.threadPool = threadPool;
this.keytabPath = config.env().configFile().resolve(KerberosRealmSettings.HTTP_SERVICE_KEYTAB_PATH.get(config.settings()));
+
+ if (Files.exists(keytabPath) == false) {
+ throw new IllegalArgumentException("configured service key tab file [" + keytabPath + "] does not exist");
+ }
+ if (Files.isDirectory(keytabPath)) {
+ throw new IllegalArgumentException("configured service key tab file [" + keytabPath + "] is a directory");
+ }
+ if (Files.isReadable(keytabPath) == false) {
+ throw new IllegalArgumentException("configured service key tab file [" + keytabPath + "] must have read permission");
+ }
this.enableKerberosDebug = KerberosRealmSettings.SETTING_KRB_DEBUG_ENABLE.get(config.settings());
this.removeRealmName = KerberosRealmSettings.SETTING_REMOVE_REALM_NAME.get(config.settings());
}
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmBootstrapCheck.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmBootstrapCheck.java
deleted file mode 100644
index bab899a8664..00000000000
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmBootstrapCheck.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.authc.kerberos;
-
-import org.elasticsearch.bootstrap.BootstrapCheck;
-import org.elasticsearch.bootstrap.BootstrapContext;
-import org.elasticsearch.common.Strings;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.env.Environment;
-import org.elasticsearch.xpack.core.security.authc.RealmSettings;
-import org.elasticsearch.xpack.core.security.authc.kerberos.KerberosRealmSettings;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * This class is used to perform bootstrap checks for kerberos realm.
- *
- * We use service keytabs for validating incoming kerberos tickets and is a
- * required configuration. Due to JVM wide system properties for Kerberos we
- * cannot support multiple Kerberos realms. This class adds checks for node to
- * fail if service keytab does not exist or multiple kerberos realms have been
- * configured.
- */
-public class KerberosRealmBootstrapCheck implements BootstrapCheck {
- private final Environment env;
-
- public KerberosRealmBootstrapCheck(final Environment env) {
- this.env = env;
- }
-
- @Override
- public BootstrapCheckResult check(final BootstrapContext context) {
- final Map realmsSettings = RealmSettings.getRealmSettings(context.settings);
- boolean isKerberosRealmConfigured = false;
- for (final Entry entry : realmsSettings.entrySet()) {
- final String name = entry.getKey();
- final Settings realmSettings = entry.getValue();
- final String type = realmSettings.get("type");
- if (Strings.hasText(type) == false) {
- return BootstrapCheckResult.failure("missing realm type for [" + name + "] realm");
- }
- if (KerberosRealmSettings.TYPE.equals(type)) {
- if (isKerberosRealmConfigured) {
- return BootstrapCheckResult.failure(
- "multiple [" + type + "] realms are configured. [" + type + "] can only have one such realm configured");
- }
- isKerberosRealmConfigured = true;
-
- final Path keytabPath = env.configFile().resolve(KerberosRealmSettings.HTTP_SERVICE_KEYTAB_PATH.get(realmSettings));
- if (Files.exists(keytabPath) == false) {
- return BootstrapCheckResult.failure("configured service key tab file [" + keytabPath + "] does not exist");
- }
- }
- }
- return BootstrapCheckResult.success();
- }
-
- @Override
- public boolean alwaysEnforce() {
- return true;
- }
-}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/BulkUpdateTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/BulkUpdateTests.java
index 03ace7fb71d..bb0036e9f87 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/BulkUpdateTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/BulkUpdateTests.java
@@ -5,15 +5,12 @@
*/
package org.elasticsearch.integration;
-import org.apache.http.Header;
-import org.apache.http.entity.ContentType;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetResponse;
-import org.elasticsearch.client.Response;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
@@ -24,10 +21,8 @@ import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import java.io.IOException;
-import java.util.Collections;
import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.equalTo;
public class BulkUpdateTests extends SecurityIntegTestCase {
@@ -77,46 +72,48 @@ public class BulkUpdateTests extends SecurityIntegTestCase {
public void testThatBulkUpdateDoesNotLoseFieldsHttp() throws IOException {
final String path = "/index1/type/1";
- final Header basicAuthHeader = new BasicHeader("Authorization",
- UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
- new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray())));
+ final RequestOptions.Builder optionsBuilder = RequestOptions.DEFAULT.toBuilder();
+ optionsBuilder.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
+ new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray())));
+ final RequestOptions options = optionsBuilder.build();
- StringEntity body = new StringEntity("{\"test\":\"test\"}", ContentType.APPLICATION_JSON);
- Response response = getRestClient().performRequest("PUT", path, Collections.emptyMap(), body, basicAuthHeader);
- assertThat(response.getStatusLine().getStatusCode(), equalTo(201));
+ Request createRequest = new Request("PUT", path);
+ createRequest.setOptions(options);
+ createRequest.setJsonEntity("{\"test\":\"test\"}");
+ getRestClient().performRequest(createRequest);
- response = getRestClient().performRequest("GET", path, basicAuthHeader);
- assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
- assertThat(EntityUtils.toString(response.getEntity()), containsString("\"test\":\"test\""));
+ Request getRequest = new Request("GET", path);
+ getRequest.setOptions(options);
+ assertThat(EntityUtils.toString(getRestClient().performRequest(getRequest).getEntity()), containsString("\"test\":\"test\""));
if (randomBoolean()) {
flushAndRefresh();
}
//update with new field
- body = new StringEntity("{\"doc\": {\"not test\": \"not test\"}}", ContentType.APPLICATION_JSON);
- response = getRestClient().performRequest("POST", path + "/_update", Collections.emptyMap(), body, basicAuthHeader);
- assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
+ Request updateRequest = new Request("POST", path + "/_update");
+ updateRequest.setOptions(options);
+ updateRequest.setJsonEntity("{\"doc\": {\"not test\": \"not test\"}}");
+ getRestClient().performRequest(updateRequest);
- response = getRestClient().performRequest("GET", path, basicAuthHeader);
- assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
- String responseBody = EntityUtils.toString(response.getEntity());
- assertThat(responseBody, containsString("\"test\":\"test\""));
- assertThat(responseBody, containsString("\"not test\":\"not test\""));
+ String afterUpdate = EntityUtils.toString(getRestClient().performRequest(getRequest).getEntity());
+ assertThat(afterUpdate, containsString("\"test\":\"test\""));
+ assertThat(afterUpdate, containsString("\"not test\":\"not test\""));
// this part is important. Without this, the document may be read from the translog which would bypass the bug where
// FLS kicks in because the request can't be found and only returns meta fields
flushAndRefresh();
- body = new StringEntity("{\"update\": {\"_index\": \"index1\", \"_type\": \"type\", \"_id\": \"1\"}}\n" +
- "{\"doc\": {\"bulk updated\":\"bulk updated\"}}\n", ContentType.APPLICATION_JSON);
- response = getRestClient().performRequest("POST", "/_bulk", Collections.emptyMap(), body, basicAuthHeader);
- assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
+ Request bulkRequest = new Request("POST", "/_bulk");
+ bulkRequest.setOptions(options);
+ bulkRequest.setJsonEntity(
+ "{\"update\": {\"_index\": \"index1\", \"_type\": \"type\", \"_id\": \"1\"}}\n" +
+ "{\"doc\": {\"bulk updated\":\"bulk updated\"}}\n");
+ getRestClient().performRequest(bulkRequest);
- response = getRestClient().performRequest("GET", path, basicAuthHeader);
- responseBody = EntityUtils.toString(response.getEntity());
- assertThat(responseBody, containsString("\"test\":\"test\""));
- assertThat(responseBody, containsString("\"not test\":\"not test\""));
- assertThat(responseBody, containsString("\"bulk updated\":\"bulk updated\""));
+ String afterBulk = EntityUtils.toString(getRestClient().performRequest(getRequest).getEntity());
+ assertThat(afterBulk, containsString("\"test\":\"test\""));
+ assertThat(afterBulk, containsString("\"not test\":\"not test\""));
+ assertThat(afterBulk, containsString("\"bulk updated\":\"bulk updated\""));
}
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/ClearRealmsCacheTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/ClearRealmsCacheTests.java
index 8b9e1954264..fc02a5c4d62 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/ClearRealmsCacheTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/ClearRealmsCacheTests.java
@@ -5,10 +5,11 @@
*/
package org.elasticsearch.integration;
-import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.PlainActionFuture;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.SecureString;
@@ -160,10 +161,15 @@ public class ClearRealmsCacheTests extends SecurityIntegTestCase {
}
static void executeHttpRequest(String path, Map params) throws Exception {
- Response response = getRestClient().performRequest("POST", path, params,
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
- new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray()))));
+ Request request = new Request("POST", path);
+ for (Map.Entry param : params.entrySet()) {
+ request.addParameter(param.getKey(), param.getValue());
+ }
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
+ new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray())));
+ request.setOptions(options);
+ Response response = getRestClient().performRequest(request);
assertNotNull(response.getEntity());
assertTrue(EntityUtils.toString(response.getEntity()).contains("cluster_name"));
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/IndexPrivilegeTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/IndexPrivilegeTests.java
index 825bfcd432f..57262822982 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/IndexPrivilegeTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/integration/IndexPrivilegeTests.java
@@ -5,7 +5,8 @@
*/
package org.elasticsearch.integration;
-import org.apache.http.message.BasicHeader;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
@@ -388,9 +389,12 @@ public class IndexPrivilegeTests extends AbstractPrivilegeTestCase {
public void testThatUnknownUserIsRejectedProperly() throws Exception {
try {
- getRestClient().performRequest("GET", "/",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue("idonotexist", new SecureString("passwd".toCharArray()))));
+ Request request = new Request("GET", "/");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization",
+ UsernamePasswordToken.basicAuthHeaderValue("idonotexist", new SecureString("passwd".toCharArray())));
+ request.setOptions(options);
+ getRestClient().performRequest(request);
fail("request should have failed");
} catch(ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401));
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/license/LicensingTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/license/LicensingTests.java
index 012050f4259..7a35b0bc422 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/license/LicensingTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/license/LicensingTests.java
@@ -5,7 +5,6 @@
*/
package org.elasticsearch.license;
-import org.apache.http.message.BasicHeader;
import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse;
@@ -15,6 +14,8 @@ import org.elasticsearch.action.admin.cluster.stats.ClusterStatsResponse;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.Client;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.transport.NoNodeAvailableException;
@@ -189,31 +190,36 @@ public class LicensingTests extends SecurityIntegTestCase {
}
public void testRestAuthenticationByLicenseType() throws Exception {
- Response response = getRestClient().performRequest("GET", "/");
+ Response unauthorizedRootResponse = getRestClient().performRequest(new Request("GET", "/"));
// the default of the licensing tests is basic
- assertThat(response.getStatusLine().getStatusCode(), is(200));
+ assertThat(unauthorizedRootResponse.getStatusLine().getStatusCode(), is(200));
ResponseException e = expectThrows(ResponseException.class,
- () -> getRestClient().performRequest("GET", "/_xpack/security/_authenticate"));
+ () -> getRestClient().performRequest(new Request("GET", "/_xpack/security/_authenticate")));
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403));
// generate a new license with a mode that enables auth
License.OperationMode mode = randomFrom(License.OperationMode.GOLD, License.OperationMode.TRIAL,
License.OperationMode.PLATINUM, License.OperationMode.STANDARD);
enableLicensing(mode);
- e = expectThrows(ResponseException.class, () -> getRestClient().performRequest("GET", "/"));
+ e = expectThrows(ResponseException.class, () -> getRestClient().performRequest(new Request("GET", "/")));
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401));
e = expectThrows(ResponseException.class,
- () -> getRestClient().performRequest("GET", "/_xpack/security/_authenticate"));
+ () -> getRestClient().performRequest(new Request("GET", "/_xpack/security/_authenticate")));
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401));
- final String basicAuthValue = UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
- new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray()));
- response = getRestClient().performRequest("GET", "/", new BasicHeader("Authorization", basicAuthValue));
- assertThat(response.getStatusLine().getStatusCode(), is(200));
- response = getRestClient().performRequest("GET", "/_xpack/security/_authenticate",
- new BasicHeader("Authorization", basicAuthValue));
- assertThat(response.getStatusLine().getStatusCode(), is(200));
+ RequestOptions.Builder optionsBuilder = RequestOptions.DEFAULT.toBuilder();
+ optionsBuilder.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
+ new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray())));
+ RequestOptions options = optionsBuilder.build();
+ Request rootRequest = new Request("GET", "/");
+ rootRequest.setOptions(options);
+ Response authorizedRootResponse = getRestClient().performRequest(rootRequest);
+ assertThat(authorizedRootResponse.getStatusLine().getStatusCode(), is(200));
+ Request authenticateRequest = new Request("GET", "/_xpack/security/_authenticate");
+ authenticateRequest.setOptions(options);
+ Response authorizedAuthenticateResponse = getRestClient().performRequest(authenticateRequest);
+ assertThat(authorizedAuthenticateResponse.getStatusLine().getStatusCode(), is(200));
}
public void testSecurityActionsByLicenseType() throws Exception {
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/test/NativeRealmIntegTestCase.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/test/NativeRealmIntegTestCase.java
index 72550832779..af5b73d889d 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/test/NativeRealmIntegTestCase.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/test/NativeRealmIntegTestCase.java
@@ -5,12 +5,8 @@
*/
package org.elasticsearch.test;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.entity.ContentType;
-import org.apache.http.message.BasicHeader;
-import org.apache.http.nio.entity.NStringEntity;
-import org.elasticsearch.client.Response;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.util.set.Sets;
@@ -26,7 +22,6 @@ import org.junit.Before;
import java.io.IOException;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Set;
/**
@@ -82,23 +77,22 @@ public abstract class NativeRealmIntegTestCase extends SecurityIntegTestCase {
public void setupReservedPasswords(RestClient restClient) throws IOException {
logger.info("setting up reserved passwords for test");
{
- String payload = "{\"password\": \"" + new String(reservedPassword.getChars()) + "\"}";
- HttpEntity entity = new NStringEntity(payload, ContentType.APPLICATION_JSON);
- BasicHeader authHeader = new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(ElasticUser.NAME, BOOTSTRAP_PASSWORD));
- String route = "/_xpack/security/user/elastic/_password";
- Response response = restClient.performRequest("PUT", route, Collections.emptyMap(), entity, authHeader);
- assertEquals(response.getStatusLine().getReasonPhrase(), 200, response.getStatusLine().getStatusCode());
+ Request request = new Request("PUT", "/_xpack/security/user/elastic/_password");
+ request.setJsonEntity("{\"password\": \"" + new String(reservedPassword.getChars()) + "\"}");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(ElasticUser.NAME, BOOTSTRAP_PASSWORD));
+ request.setOptions(options);
+ restClient.performRequest(request);
}
+ RequestOptions.Builder optionsBuilder = RequestOptions.DEFAULT.toBuilder();
+ optionsBuilder.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(ElasticUser.NAME, reservedPassword));
+ RequestOptions options = optionsBuilder.build();
for (String username : Arrays.asList(KibanaUser.NAME, LogstashSystemUser.NAME, BeatsSystemUser.NAME)) {
- String payload = "{\"password\": \"" + new String(reservedPassword.getChars()) + "\"}";
- HttpEntity entity = new NStringEntity(payload, ContentType.APPLICATION_JSON);
- BasicHeader authHeader = new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(ElasticUser.NAME, reservedPassword));
- String route = "/_xpack/security/user/" + username + "/_password";
- Response response = restClient.performRequest("PUT", route, Collections.emptyMap(), entity, authHeader);
- assertEquals(response.getStatusLine().getReasonPhrase(), 200, response.getStatusLine().getStatusCode());
+ Request request = new Request("PUT", "/_xpack/security/user/" + username + "/_password");
+ request.setJsonEntity("{\"password\": \"" + new String(reservedPassword.getChars()) + "\"}");
+ request.setOptions(options);
+ restClient.performRequest(request);
}
logger.info("setting up reserved passwords finished");
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/FIPS140LicenseBootstrapCheckTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/FIPS140LicenseBootstrapCheckTests.java
new file mode 100644
index 00000000000..a2ec8f9fb20
--- /dev/null
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/FIPS140LicenseBootstrapCheckTests.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import org.elasticsearch.bootstrap.BootstrapContext;
+import org.elasticsearch.cluster.metadata.MetaData;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.license.License;
+import org.elasticsearch.license.TestUtils;
+import org.elasticsearch.test.ESTestCase;
+
+public class FIPS140LicenseBootstrapCheckTests extends ESTestCase {
+
+ public void testBootstrapCheck() throws Exception {
+ assertTrue(new FIPS140LicenseBootstrapCheck(false)
+ .check(new BootstrapContext(Settings.EMPTY, MetaData.EMPTY_META_DATA)).isSuccess());
+ assertTrue(new FIPS140LicenseBootstrapCheck(randomBoolean())
+ .check(new BootstrapContext(Settings.EMPTY, MetaData.EMPTY_META_DATA)).isSuccess());
+
+ License license = TestUtils.generateSignedLicense(TimeValue.timeValueHours(24));
+ MetaData.Builder builder = MetaData.builder();
+ TestUtils.putLicense(builder, license);
+ MetaData metaData = builder.build();
+ if (FIPS140LicenseBootstrapCheck.ALLOWED_LICENSE_OPERATION_MODES.contains(license.operationMode())) {
+ assertTrue(new FIPS140LicenseBootstrapCheck(true).check(new BootstrapContext(
+ Settings.builder().put("xpack.security.fips_mode.enabled", true).build(), metaData)).isSuccess());
+ assertTrue(new FIPS140LicenseBootstrapCheck(false).check(new BootstrapContext(
+ Settings.builder().put("xpack.security.fips_mode.enabled", false).build(), metaData)).isSuccess());
+ } else {
+ assertTrue(new FIPS140LicenseBootstrapCheck(false).check(new BootstrapContext(
+ Settings.builder().put("xpack.security.fips_mode.enabled", false).build(), metaData)).isSuccess());
+ assertTrue(new FIPS140LicenseBootstrapCheck(true).check(new BootstrapContext(
+ Settings.builder().put("xpack.security.fips_mode.enabled", true).build(), metaData)).isFailure());
+ assertEquals("FIPS mode is only allowed with a Platinum or Trial license",
+ new FIPS140LicenseBootstrapCheck(true).check(new BootstrapContext(
+ Settings.builder().put("xpack.security.fips_mode.enabled", true).build(), metaData)).getMessage());
+ }
+ }
+}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/FIPS140PasswordHashingAlgorithmBootstrapCheckTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/FIPS140PasswordHashingAlgorithmBootstrapCheckTests.java
index b424986876a..8632400866a 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/FIPS140PasswordHashingAlgorithmBootstrapCheckTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/FIPS140PasswordHashingAlgorithmBootstrapCheckTests.java
@@ -21,7 +21,7 @@ public class FIPS140PasswordHashingAlgorithmBootstrapCheckTests extends ESTestCa
public void testPBKDF2AlgorithmIsAllowed() {
{
final Settings settings = Settings.builder()
- .put(Security.FIPS_MODE_ENABLED.getKey(), true)
+ .put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true)
.put(XPackSettings.PASSWORD_HASHING_ALGORITHM.getKey(), "PBKDF2_10000")
.build();
final BootstrapCheck.BootstrapCheckResult result =
@@ -31,7 +31,7 @@ public class FIPS140PasswordHashingAlgorithmBootstrapCheckTests extends ESTestCa
{
final Settings settings = Settings.builder()
- .put(Security.FIPS_MODE_ENABLED.getKey(), true)
+ .put(XPackSettings.FIPS_MODE_ENABLED.getKey(), true)
.put(XPackSettings.PASSWORD_HASHING_ALGORITHM.getKey(), "PBKDF2")
.build();
final BootstrapCheck.BootstrapCheckResult result =
@@ -49,7 +49,7 @@ public class FIPS140PasswordHashingAlgorithmBootstrapCheckTests extends ESTestCa
}
private void runBCRYPTTest(final boolean fipsModeEnabled, final String passwordHashingAlgorithm) {
- final Settings.Builder builder = Settings.builder().put(Security.FIPS_MODE_ENABLED.getKey(), fipsModeEnabled);
+ final Settings.Builder builder = Settings.builder().put(XPackSettings.FIPS_MODE_ENABLED.getKey(), fipsModeEnabled);
if (passwordHashingAlgorithm != null) {
builder.put(XPackSettings.PASSWORD_HASHING_ALGORITHM.getKey(), passwordHashingAlgorithm);
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityPluginTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityPluginTests.java
index 368449adeed..d57a5d151a9 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityPluginTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityPluginTests.java
@@ -5,14 +5,14 @@
*/
package org.elasticsearch.xpack.security;
-import org.apache.http.message.BasicHeader;
+import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.test.SecurityIntegTestCase;
import org.elasticsearch.test.SecuritySettingsSource;
import org.elasticsearch.test.SecuritySettingsSourceField;
-import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import java.io.IOException;
@@ -31,17 +31,20 @@ public class SecurityPluginTests extends SecurityIntegTestCase {
public void testThatPluginIsLoaded() throws IOException {
try {
logger.info("executing unauthorized request to /_xpack info");
- getRestClient().performRequest("GET", "/_xpack");
+ getRestClient().performRequest(new Request("GET", "/_xpack"));
fail("request should have failed");
} catch(ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(UNAUTHORIZED.getStatus()));
}
logger.info("executing authorized request to /_xpack infos");
- Response response = getRestClient().performRequest("GET", "/_xpack",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
- new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray()))));
+
+ Request request = new Request("GET", "/_xpack");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
+ new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray())));
+ request.setOptions(options);
+ Response response = getRestClient().performRequest(request);
assertThat(response.getStatusLine().getStatusCode(), is(OK.getStatus()));
}
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java
index e88b1905a7a..857b1694ac8 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityTests.java
@@ -292,6 +292,26 @@ public class SecurityTests extends ESTestCase {
assertThat(e.getMessage(), containsString("cannot deserialize the license format"));
}
+ public void testJoinValidatorForFIPSLicense() throws Exception {
+ DiscoveryNode node = new DiscoveryNode("foo", buildNewFakeTransportAddress(),
+ VersionUtils.randomVersionBetween(random(), null, Version.CURRENT));
+ MetaData.Builder builder = MetaData.builder();
+ License license = TestUtils.generateSignedLicense(TimeValue.timeValueHours(24));
+ TestUtils.putLicense(builder, license);
+ ClusterState state = ClusterState.builder(ClusterName.DEFAULT).metaData(builder.build()).build();
+ new Security.ValidateLicenseForFIPS(false).accept(node, state);
+
+ final boolean isLicenseValidForFips =
+ FIPS140LicenseBootstrapCheck.ALLOWED_LICENSE_OPERATION_MODES.contains(license.operationMode());
+ if (isLicenseValidForFips) {
+ new Security.ValidateLicenseForFIPS(true).accept(node, state);
+ } else {
+ IllegalStateException e = expectThrows(IllegalStateException.class,
+ () -> new Security.ValidateLicenseForFIPS(true).accept(node, state));
+ assertThat(e.getMessage(), containsString("FIPS mode cannot be used"));
+ }
+ }
+
public void testIndexJoinValidator_Old_And_Rolling() throws Exception {
createComponents(Settings.EMPTY);
BiConsumer joinValidator = security.getJoinValidator();
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/index/AuditTrailTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/index/AuditTrailTests.java
index 453820ea519..ef3c6aa56ae 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/index/AuditTrailTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/index/AuditTrailTests.java
@@ -5,12 +5,13 @@
*/
package org.elasticsearch.xpack.security.audit.index;
-import org.apache.http.message.BasicHeader;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.client.Client;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.common.settings.Settings;
@@ -89,10 +90,12 @@ public class AuditTrailTests extends SecurityIntegTestCase {
public void testAuditAccessDeniedWithRunAsUser() throws Exception {
try {
- getRestClient().performRequest("GET", "/.security/_search",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(AUTHENTICATE_USER, TEST_PASSWORD_SECURE_STRING)),
- new BasicHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, EXECUTE_USER));
+ Request request = new Request("GET", "/.security/_search");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(AUTHENTICATE_USER, TEST_PASSWORD_SECURE_STRING));
+ options.addHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, EXECUTE_USER);
+ request.setOptions(options);
+ getRestClient().performRequest(request);
fail("request should have failed");
} catch (final ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403));
@@ -111,10 +114,12 @@ public class AuditTrailTests extends SecurityIntegTestCase {
public void testAuditRunAsDeniedEmptyUser() throws Exception {
try {
- getRestClient().performRequest("GET", "/.security/_search",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(AUTHENTICATE_USER, TEST_PASSWORD_SECURE_STRING)),
- new BasicHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, ""));
+ Request request = new Request("GET", "/.security/_search");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(AUTHENTICATE_USER, TEST_PASSWORD_SECURE_STRING));
+ options.addHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, "");
+ request.setOptions(options);
+ getRestClient().performRequest(request);
fail("request should have failed");
} catch (final ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401));
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java
index a71f5cb1cf7..9d795826298 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/RealmsTests.java
@@ -27,6 +27,7 @@ import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.junit.Before;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -51,13 +52,16 @@ public class RealmsTests extends ESTestCase {
private XPackLicenseState licenseState;
private ThreadContext threadContext;
private ReservedRealm reservedRealm;
+ private int randomRealmTypesCount;
@Before
public void init() throws Exception {
factories = new HashMap<>();
factories.put(FileRealmSettings.TYPE, config -> new DummyRealm(FileRealmSettings.TYPE, config));
factories.put(NativeRealmSettings.TYPE, config -> new DummyRealm(NativeRealmSettings.TYPE, config));
- for (int i = 0; i < randomIntBetween(1, 5); i++) {
+ factories.put(KerberosRealmSettings.TYPE, config -> new DummyRealm(KerberosRealmSettings.TYPE, config));
+ randomRealmTypesCount = randomIntBetween(1, 5);
+ for (int i = 0; i < randomRealmTypesCount; i++) {
String name = "type_" + i;
factories.put(name, config -> new DummyRealm(name, config));
}
@@ -73,13 +77,13 @@ public class RealmsTests extends ESTestCase {
public void testWithSettings() throws Exception {
Settings.Builder builder = Settings.builder()
.put("path.home", createTempDir());
- List orders = new ArrayList<>(factories.size() - 2);
- for (int i = 0; i < factories.size() - 2; i++) {
+ List orders = new ArrayList<>(randomRealmTypesCount);
+ for (int i = 0; i < randomRealmTypesCount; i++) {
orders.add(i);
}
Collections.shuffle(orders, random());
Map orderToIndex = new HashMap<>();
- for (int i = 0; i < factories.size() - 2; i++) {
+ for (int i = 0; i < randomRealmTypesCount; i++) {
builder.put("xpack.security.authc.realms.realm_" + i + ".type", "type_" + i);
builder.put("xpack.security.authc.realms.realm_" + i + ".order", orders.get(i));
orderToIndex.put(orders.get(i), i);
@@ -107,14 +111,14 @@ public class RealmsTests extends ESTestCase {
public void testWithSettingsWhereDifferentRealmsHaveSameOrder() throws Exception {
Settings.Builder builder = Settings.builder()
.put("path.home", createTempDir());
- List randomSeq = new ArrayList<>(factories.size() - 2);
- for (int i = 0; i < factories.size() - 2; i++) {
+ List randomSeq = new ArrayList<>(randomRealmTypesCount);
+ for (int i = 0; i < randomRealmTypesCount; i++) {
randomSeq.add(i);
}
Collections.shuffle(randomSeq, random());
TreeMap nameToRealmId = new TreeMap<>();
- for (int i = 0; i < factories.size() - 2; i++) {
+ for (int i = 0; i < randomRealmTypesCount; i++) {
int randomizedRealmId = randomSeq.get(i);
String randomizedRealmName = randomAlphaOfLengthBetween(12,32);
nameToRealmId.put("realm_" + randomizedRealmName, randomizedRealmId);
@@ -181,13 +185,13 @@ public class RealmsTests extends ESTestCase {
public void testUnlicensedWithOnlyCustomRealms() throws Exception {
Settings.Builder builder = Settings.builder()
.put("path.home", createTempDir());
- List orders = new ArrayList<>(factories.size() - 2);
- for (int i = 0; i < factories.size() - 2; i++) {
+ List orders = new ArrayList<>(randomRealmTypesCount);
+ for (int i = 0; i < randomRealmTypesCount; i++) {
orders.add(i);
}
Collections.shuffle(orders, random());
Map orderToIndex = new HashMap<>();
- for (int i = 0; i < factories.size() - 2; i++) {
+ for (int i = 0; i < randomRealmTypesCount; i++) {
builder.put("xpack.security.authc.realms.realm_" + i + ".type", "type_" + i);
builder.put("xpack.security.authc.realms.realm_" + i + ".order", orders.get(i));
orderToIndex.put(orders.get(i), i);
@@ -384,13 +388,13 @@ public class RealmsTests extends ESTestCase {
public void testDisabledRealmsAreNotAdded() throws Exception {
Settings.Builder builder = Settings.builder()
.put("path.home", createTempDir());
- List orders = new ArrayList<>(factories.size() - 2);
- for (int i = 0; i < factories.size() - 2; i++) {
+ List orders = new ArrayList<>(randomRealmTypesCount);
+ for (int i = 0; i < randomRealmTypesCount; i++) {
orders.add(i);
}
Collections.shuffle(orders, random());
Map orderToIndex = new HashMap<>();
- for (int i = 0; i < factories.size() - 2; i++) {
+ for (int i = 0; i < randomRealmTypesCount; i++) {
builder.put("xpack.security.authc.realms.realm_" + i + ".type", "type_" + i);
builder.put("xpack.security.authc.realms.realm_" + i + ".order", orders.get(i));
boolean enabled = randomBoolean();
@@ -520,6 +524,20 @@ public class RealmsTests extends ESTestCase {
}
}
+ public void testInitRealmsFailsForMultipleKerberosRealms() throws IOException {
+ final Settings.Builder builder = Settings.builder().put("path.home", createTempDir());
+ builder.put("xpack.security.authc.realms.realm_1.type", "kerberos");
+ builder.put("xpack.security.authc.realms.realm_1.order", 1);
+ builder.put("xpack.security.authc.realms.realm_2.type", "kerberos");
+ builder.put("xpack.security.authc.realms.realm_2.order", 2);
+ final Settings settings = builder.build();
+ Environment env = TestEnvironment.newEnvironment(settings);
+ final IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
+ () -> new Realms(settings, env, factories, licenseState, threadContext, reservedRealm));
+ assertThat(iae.getMessage(), is(equalTo(
+ "multiple realms [realm_1, realm_2] configured of type [kerberos], [kerberos] can only have one such realm configured")));
+ }
+
static class DummyRealm extends Realm {
DummyRealm(String type, RealmConfig config) {
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/RunAsIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/RunAsIntegTests.java
index 9311b9c02f6..6d5c6770bf2 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/RunAsIntegTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/RunAsIntegTests.java
@@ -5,12 +5,12 @@
*/
package org.elasticsearch.xpack.security.authc;
-import org.apache.http.message.BasicHeader;
import org.elasticsearch.ElasticsearchSecurityException;
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;
-import org.elasticsearch.client.Response;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.SecureString;
@@ -126,11 +126,13 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
public void testUserImpersonationUsingHttp() throws Exception {
// use the transport client user and try to run as
try {
- getRestClient().performRequest("GET", "/_nodes",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(TRANSPORT_CLIENT_USER,
- TEST_PASSWORD_SECURE_STRING)),
- new BasicHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, SecuritySettingsSource.TEST_USER_NAME));
+ Request request = new Request("GET", "/_nodes");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization",
+ UsernamePasswordToken.basicAuthHeaderValue(TRANSPORT_CLIENT_USER, TEST_PASSWORD_SECURE_STRING));
+ options.addHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, SecuritySettingsSource.TEST_USER_NAME);
+ request.setOptions(options);
+ getRestClient().performRequest(request);
fail("request should have failed");
} catch(ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403));
@@ -139,10 +141,11 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
if (runAsHasSuperUserRole == false) {
try {
//the run as user shouldn't have access to the nodes api
- getRestClient().performRequest("GET", "/_nodes",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER,
- TEST_PASSWORD_SECURE_STRING)));
+ Request request = new Request("GET", "/_nodes");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER, TEST_PASSWORD_SECURE_STRING));
+ request.setOptions(options);
+ getRestClient().performRequest(request);
fail("request should have failed");
} catch (ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403));
@@ -150,12 +153,7 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
}
// but when running as a different user it should work
- Response response = getRestClient().performRequest("GET", "/_nodes",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER,
- TEST_PASSWORD_SECURE_STRING)),
- new BasicHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, SecuritySettingsSource.TEST_USER_NAME));
- assertThat(response.getStatusLine().getStatusCode(), is(200));
+ getRestClient().performRequest(requestForUserRunAsUser(SecuritySettingsSource.TEST_USER_NAME));
}
public void testEmptyUserImpersonationHeader() throws Exception {
@@ -183,11 +181,7 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
public void testEmptyHeaderUsingHttp() throws Exception {
try {
- getRestClient().performRequest("GET", "/_nodes",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER,
- TEST_PASSWORD_SECURE_STRING)),
- new BasicHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, ""));
+ getRestClient().performRequest(requestForUserRunAsUser(""));
fail("request should have failed");
} catch(ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401));
@@ -219,17 +213,22 @@ public class RunAsIntegTests extends SecurityIntegTestCase {
public void testNonExistentRunAsUserUsingHttp() throws Exception {
try {
- getRestClient().performRequest("GET", "/_nodes",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER,
- TEST_PASSWORD_SECURE_STRING)),
- new BasicHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, "idontexist"));
+ getRestClient().performRequest(requestForUserRunAsUser("idontexist"));
fail("request should have failed");
} catch (ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403));
}
}
+ private static Request requestForUserRunAsUser(String user) {
+ Request request = new Request("GET", "/_nodes");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(RUN_AS_USER, TEST_PASSWORD_SECURE_STRING));
+ options.addHeader(AuthenticationServiceField.RUN_AS_USER_HEADER, user);
+ request.setOptions(options);
+ return request;
+ }
+
// build our own here to better mimic an actual client...
TransportClient getTransportClient(Settings extraSettings) {
NodesInfoResponse nodeInfos = client().admin().cluster().prepareNodesInfo().get();
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmBootstrapCheckTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmBootstrapCheckTests.java
deleted file mode 100644
index b6e1df9ddbb..00000000000
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmBootstrapCheckTests.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.authc.kerberos;
-
-import org.elasticsearch.bootstrap.BootstrapCheck;
-import org.elasticsearch.bootstrap.BootstrapContext;
-import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.env.TestEnvironment;
-import org.elasticsearch.test.ESTestCase;
-import org.elasticsearch.xpack.core.security.authc.RealmSettings;
-import org.elasticsearch.xpack.core.security.authc.kerberos.KerberosRealmSettings;
-import org.elasticsearch.xpack.core.security.authc.pki.PkiRealmSettings;
-
-import java.io.IOException;
-import java.nio.file.Path;
-
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-
-public class KerberosRealmBootstrapCheckTests extends ESTestCase {
-
- public void testBootstrapCheckFailsForMultipleKerberosRealms() throws IOException {
- final Path tempDir = createTempDir();
- final Settings settings1 = buildKerberosRealmSettings("kerb1", false, tempDir);
- final Settings settings2 = buildKerberosRealmSettings("kerb2", false, tempDir);
- final Settings settings3 = realm("pki1", PkiRealmSettings.TYPE, Settings.builder()).build();
- final Settings settings =
- Settings.builder().put("path.home", tempDir).put(settings1).put(settings2).put(settings3).build();
- final BootstrapContext context = new BootstrapContext(settings, null);
- final KerberosRealmBootstrapCheck kerbRealmBootstrapCheck =
- new KerberosRealmBootstrapCheck(TestEnvironment.newEnvironment(settings));
- final BootstrapCheck.BootstrapCheckResult result = kerbRealmBootstrapCheck.check(context);
- assertThat(result, is(notNullValue()));
- assertThat(result.isFailure(), is(true));
- assertThat(result.getMessage(), equalTo("multiple [" + KerberosRealmSettings.TYPE + "] realms are configured. ["
- + KerberosRealmSettings.TYPE + "] can only have one such realm configured"));
- }
-
- public void testBootstrapCheckFailsForMissingKeytabFile() throws IOException {
- final Path tempDir = createTempDir();
- final Settings settings =
- Settings.builder().put("path.home", tempDir).put(buildKerberosRealmSettings("kerb1", true, tempDir)).build();
- final BootstrapContext context = new BootstrapContext(settings, null);
- final KerberosRealmBootstrapCheck kerbRealmBootstrapCheck =
- new KerberosRealmBootstrapCheck(TestEnvironment.newEnvironment(settings));
- final BootstrapCheck.BootstrapCheckResult result = kerbRealmBootstrapCheck.check(context);
- assertThat(result, is(notNullValue()));
- assertThat(result.isFailure(), is(true));
- assertThat(result.getMessage(),
- equalTo("configured service key tab file [" + tempDir.resolve("kerb1.keytab").toString() + "] does not exist"));
- }
-
- public void testBootstrapCheckFailsForMissingRealmType() throws IOException {
- final Path tempDir = createTempDir();
- final String name = "kerb1";
- final Settings settings1 = buildKerberosRealmSettings("kerb1", false, tempDir);
- final Settings settings2 = realm(name, randomFrom("", " "), Settings.builder()).build();
- final Settings settings =
- Settings.builder().put("path.home", tempDir).put(settings1).put(settings2).build();
- final BootstrapContext context = new BootstrapContext(settings, null);
- final KerberosRealmBootstrapCheck kerbRealmBootstrapCheck =
- new KerberosRealmBootstrapCheck(TestEnvironment.newEnvironment(settings));
- final BootstrapCheck.BootstrapCheckResult result = kerbRealmBootstrapCheck.check(context);
- assertThat(result, is(notNullValue()));
- assertThat(result.isFailure(), is(true));
- assertThat(result.getMessage(), equalTo("missing realm type for [" + name + "] realm"));
- }
-
- public void testBootstrapCheckSucceedsForCorrectConfiguration() throws IOException {
- final Path tempDir = createTempDir();
- final Settings finalSettings =
- Settings.builder().put("path.home", tempDir).put(buildKerberosRealmSettings("kerb1", false, tempDir)).build();
- final BootstrapContext context = new BootstrapContext(finalSettings, null);
- final KerberosRealmBootstrapCheck kerbRealmBootstrapCheck =
- new KerberosRealmBootstrapCheck(TestEnvironment.newEnvironment(finalSettings));
- final BootstrapCheck.BootstrapCheckResult result = kerbRealmBootstrapCheck.check(context);
- assertThat(result, is(notNullValue()));
- assertThat(result.isSuccess(), is(true));
- }
-
- public void testBootstrapCheckSucceedsForNoKerberosRealms() throws IOException {
- final Path tempDir = createTempDir();
- final Settings finalSettings = Settings.builder().put("path.home", tempDir).build();
- final BootstrapContext context = new BootstrapContext(finalSettings, null);
- final KerberosRealmBootstrapCheck kerbRealmBootstrapCheck =
- new KerberosRealmBootstrapCheck(TestEnvironment.newEnvironment(finalSettings));
- final BootstrapCheck.BootstrapCheckResult result = kerbRealmBootstrapCheck.check(context);
- assertThat(result, is(notNullValue()));
- assertThat(result.isSuccess(), is(true));
- }
-
- private Settings buildKerberosRealmSettings(final String name, final boolean missingKeytab, final Path tempDir) throws IOException {
- final Settings.Builder builder = Settings.builder();
- if (missingKeytab == false) {
- KerberosTestCase.writeKeyTab(tempDir.resolve(name + ".keytab"), null);
- }
- builder.put(KerberosTestCase.buildKerberosRealmSettings(tempDir.resolve(name + ".keytab").toString()));
- return realm(name, KerberosRealmSettings.TYPE, builder).build();
- }
-
- private Settings.Builder realm(final String name, final String type, final Settings.Builder settings) {
- final String prefix = RealmSettings.PREFIX + name + ".";
- if (type != null) {
- settings.put("type", type);
- }
- final Settings.Builder builder = Settings.builder().put(settings.normalizePrefix(prefix).build(), false);
- return builder;
- }
-}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmTests.java
index 43536abaf29..0f972498ab3 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosRealmTests.java
@@ -11,17 +11,30 @@ import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.SecureString;
+import org.elasticsearch.common.util.concurrent.ThreadContext;
+import org.elasticsearch.env.TestEnvironment;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.xpack.core.security.authc.AuthenticationResult;
+import org.elasticsearch.xpack.core.security.authc.RealmConfig;
import org.elasticsearch.xpack.core.security.authc.kerberos.KerberosRealmSettings;
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper.UserData;
import org.ietf.jgss.GSSException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SeekableByteChannel;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Set;
import javax.security.auth.login.LoginException;
@@ -31,6 +44,7 @@ import static org.hamcrest.Matchers.nullValue;
import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -94,4 +108,44 @@ public class KerberosRealmTests extends KerberosRealmTestCase {
assertThat(future.actionGet(), is(nullValue()));
}
+ public void testKerberosRealmWithInvalidKeytabPathConfigurations() throws IOException {
+ final String keytabPathCase = randomFrom("keytabPathAsDirectory", "keytabFileDoesNotExist", "keytabPathWithNoReadPermissions");
+ final String expectedErrorMessage;
+ final String keytabPath;
+ final Set filePerms;
+ switch (keytabPathCase) {
+ case "keytabPathAsDirectory":
+ final String dirName = randomAlphaOfLength(5);
+ Files.createDirectory(dir.resolve(dirName));
+ keytabPath = dir.resolve(dirName).toString();
+ expectedErrorMessage = "configured service key tab file [" + keytabPath + "] is a directory";
+ break;
+ case "keytabFileDoesNotExist":
+ keytabPath = dir.resolve(randomAlphaOfLength(5) + ".keytab").toString();
+ expectedErrorMessage = "configured service key tab file [" + keytabPath + "] does not exist";
+ break;
+ case "keytabPathWithNoReadPermissions":
+ filePerms = PosixFilePermissions.fromString("---------");
+ final String keytabFileName = randomAlphaOfLength(5) + ".keytab";
+ final FileAttribute> fileAttributes = PosixFilePermissions.asFileAttribute(filePerms);
+ try (SeekableByteChannel byteChannel = Files.newByteChannel(dir.resolve(keytabFileName),
+ EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE), fileAttributes)) {
+ byteChannel.write(ByteBuffer.wrap(randomByteArrayOfLength(10)));
+ }
+ keytabPath = dir.resolve(keytabFileName).toString();
+ expectedErrorMessage = "configured service key tab file [" + keytabPath + "] must have read permission";
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown test case :" + keytabPathCase);
+ }
+
+ settings = KerberosTestCase.buildKerberosRealmSettings(keytabPath, 100, "10m", true, randomBoolean());
+ config = new RealmConfig("test-kerb-realm", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
+ new ThreadContext(globalSettings));
+ mockNativeRoleMappingStore = roleMappingStore(Arrays.asList("user"));
+ mockKerberosTicketValidator = mock(KerberosTicketValidator.class);
+ final IllegalArgumentException iae = expectThrows(IllegalArgumentException.class,
+ () -> new KerberosRealm(config, mockNativeRoleMappingStore, mockKerberosTicketValidator, threadPool, null));
+ assertThat(iae.getMessage(), is(equalTo(expectedErrorMessage)));
+ }
}
\ No newline at end of file
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosTestCase.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosTestCase.java
index 891f400c7be..cad9f689d3d 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosTestCase.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosTestCase.java
@@ -133,7 +133,7 @@ public abstract class KerberosTestCase extends ESTestCase {
* @param dir Directory where the key tab would be created.
* @param princNames principal names to be created
* @return {@link Path} to key tab file.
- * @throws Exception
+ * @throws Exception thrown if principal or keytab could not be created
*/
protected Path createPrincipalKeyTab(final Path dir, final String... princNames) throws Exception {
final Path path = dir.resolve(randomAlphaOfLength(10) + ".keytab");
@@ -146,7 +146,7 @@ public abstract class KerberosTestCase extends ESTestCase {
*
* @param principalName Principal name
* @param password Password
- * @throws Exception
+ * @throws Exception thrown if principal could not be created
*/
protected void createPrincipal(final String principalName, final char[] password) throws Exception {
simpleKdcLdapServer.createPrincipal(principalName, new String(password));
@@ -168,8 +168,8 @@ public abstract class KerberosTestCase extends ESTestCase {
* @param subject {@link Subject}
* @param action {@link PrivilegedExceptionAction} action for performing inside
* Subject.doAs
- * @return Type of value as returned by PrivilegedAction
- * @throws PrivilegedActionException
+ * @return T Type of value as returned by PrivilegedAction
+ * @throws PrivilegedActionException when privileged action threw exception
*/
static T doAsWrapper(final Subject subject, final PrivilegedExceptionAction action) throws PrivilegedActionException {
return AccessController.doPrivileged((PrivilegedExceptionAction) () -> Subject.doAs(subject, action));
@@ -181,7 +181,7 @@ public abstract class KerberosTestCase extends ESTestCase {
* @param keytabPath {@link Path} to keytab file.
* @param content Content for keytab
* @return key tab path
- * @throws IOException
+ * @throws IOException if I/O error occurs while writing keytab file
*/
public static Path writeKeyTab(final Path keytabPath, final String content) throws IOException {
try (BufferedWriter bufferedWriter = Files.newBufferedWriter(keytabPath, StandardCharsets.US_ASCII)) {
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/SimpleKdcLdapServer.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/SimpleKdcLdapServer.java
index 426cacb1a03..53bf9e2b78d 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/SimpleKdcLdapServer.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/SimpleKdcLdapServer.java
@@ -66,7 +66,7 @@ public class SimpleKdcLdapServer {
* @param orgName Org name for base dn
* @param domainName domain name for base dn
* @param ldiff for ldap directory.
- * @throws Exception
+ * @throws Exception when KDC or Ldap server initialization fails
*/
public SimpleKdcLdapServer(final Path workDir, final String orgName, final String domainName, final Path ldiff) throws Exception {
this.workDir = workDir;
@@ -194,7 +194,7 @@ public class SimpleKdcLdapServer {
/**
* Stop Simple Kdc Server
*
- * @throws PrivilegedActionException
+ * @throws PrivilegedActionException when privileged action threw exception
*/
public synchronized void stop() throws PrivilegedActionException {
AccessController.doPrivileged(new PrivilegedExceptionAction() {
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/SpnegoClient.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/SpnegoClient.java
index 1f883b928bd..7fcca3d9f58 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/SpnegoClient.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/SpnegoClient.java
@@ -11,7 +11,6 @@ import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.settings.SecureString;
-import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.security.authc.kerberos.KerberosTicketValidator;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
@@ -67,8 +66,8 @@ class SpnegoClient implements AutoCloseable {
* @param password password for client
* @param servicePrincipalName Service principal name with whom this client
* interacts with.
- * @throws PrivilegedActionException
- * @throws GSSException
+ * @throws PrivilegedActionException when privileged action threw exception
+ * @throws GSSException thrown when GSS API error occurs
*/
SpnegoClient(final String userPrincipalName, final SecureString password, final String servicePrincipalName)
throws PrivilegedActionException, GSSException {
@@ -99,7 +98,7 @@ class SpnegoClient implements AutoCloseable {
* base64 encoded token to be sent to server.
*
* @return Base64 encoded token
- * @throws PrivilegedActionException
+ * @throws PrivilegedActionException when privileged action threw exception
*/
String getBase64EncodedTokenForSpnegoHeader() throws PrivilegedActionException {
final byte[] outToken = KerberosTestCase.doAsWrapper(loginContext.getSubject(),
@@ -114,7 +113,7 @@ class SpnegoClient implements AutoCloseable {
* gss negotiation
* @return Base64 encoded token to be sent to server. May return {@code null} if
* nothing to be sent.
- * @throws PrivilegedActionException
+ * @throws PrivilegedActionException when privileged action threw exception
*/
String handleResponse(final String base64Token) throws PrivilegedActionException {
if (gssContext.isEstablished()) {
@@ -160,10 +159,9 @@ class SpnegoClient implements AutoCloseable {
*
* @param principal Principal name
* @param password {@link SecureString}
- * @param settings {@link Settings}
* @return authenticated {@link LoginContext} instance. Note: This needs to be
* closed {@link LoginContext#logout()} after usage.
- * @throws LoginException
+ * @throws LoginException thrown if problem with login configuration or when login fails
*/
private static LoginContext loginUsingPassword(final String principal, final SecureString password) throws LoginException {
final Set principals = Collections.singleton(new KerberosPrincipal(principal));
@@ -182,8 +180,8 @@ class SpnegoClient implements AutoCloseable {
* Instead of an additional file setting as we do not want the options to be
* customizable we are constructing it in memory.
*
- * As we are uing this instead of jaas.conf, this requires refresh of
- * {@link Configuration} and reqires appropriate security permissions to do so.
+ * As we are using this instead of jaas.conf, this requires refresh of
+ * {@link Configuration} and requires appropriate security permissions to do so.
*/
static class PasswordJaasConf extends Configuration {
private final String principal;
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiOptionalClientAuthTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiOptionalClientAuthTests.java
index d47ffe4a344..4fb94c74949 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiOptionalClientAuthTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiOptionalClientAuthTests.java
@@ -5,8 +5,9 @@
*/
package org.elasticsearch.xpack.security.authc.pki;
-import org.apache.http.message.BasicHeader;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.RestClient;
@@ -76,13 +77,15 @@ public class PkiOptionalClientAuthTests extends SecuritySingleNodeTestCase {
public void testRestClientWithoutClientCertificate() throws Exception {
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(getSSLContext());
try (RestClient restClient = createRestClient(httpClientBuilder -> httpClientBuilder.setSSLStrategy(sessionStrategy), "https")) {
- ResponseException e = expectThrows(ResponseException.class, () -> restClient.performRequest("GET", "_nodes"));
+ ResponseException e = expectThrows(ResponseException.class, () -> restClient.performRequest(new Request("GET", "_nodes")));
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(401));
- Response response = restClient.performRequest("GET", "_nodes",
- new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
- new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray()))));
+ Request request = new Request("GET", "_nodes");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", UsernamePasswordToken.basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
+ new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray())));
+ request.setOptions(options);
+ Response response = restClient.performRequest(request);
assertThat(response.getStatusLine().getStatusCode(), is(200));
}
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/RestAuthenticateActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/RestAuthenticateActionTests.java
index 67bfc2ecdcb..13a124e4bdc 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/RestAuthenticateActionTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/rest/action/RestAuthenticateActionTests.java
@@ -5,7 +5,8 @@
*/
package org.elasticsearch.xpack.security.rest.action;
-import org.apache.http.message.BasicHeader;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.common.settings.SecureString;
@@ -52,11 +53,12 @@ public class RestAuthenticateActionTests extends SecurityIntegTestCase {
}
public void testAuthenticateApi() throws Exception {
- Response response = getRestClient().performRequest("GET", "/_xpack/security/_authenticate",
- new BasicHeader("Authorization", basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
- new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray()))));
- assertThat(response.getStatusLine().getStatusCode(), is(200));
- ObjectPath objectPath = ObjectPath.createFromResponse(response);
+ Request request = new Request("GET", "/_xpack/security/_authenticate");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", basicAuthHeaderValue(SecuritySettingsSource.TEST_USER_NAME,
+ new SecureString(SecuritySettingsSourceField.TEST_PASSWORD.toCharArray())));
+ request.setOptions(options);
+ ObjectPath objectPath = ObjectPath.createFromResponse(getRestClient().performRequest(request));
assertThat(objectPath.evaluate("username").toString(), equalTo(SecuritySettingsSource.TEST_USER_NAME));
List roles = objectPath.evaluate("roles");
assertThat(roles.size(), is(1));
@@ -65,7 +67,7 @@ public class RestAuthenticateActionTests extends SecurityIntegTestCase {
public void testAuthenticateApiWithoutAuthentication() throws Exception {
try {
- Response response = getRestClient().performRequest("GET", "/_xpack/security/_authenticate");
+ Response response = getRestClient().performRequest(new Request("GET", "/_xpack/security/_authenticate"));
if (anonymousEnabled) {
assertThat(response.getStatusLine().getStatusCode(), is(200));
ObjectPath objectPath = ObjectPath.createFromResponse(response);
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/user/AnonymousUserIntegTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/user/AnonymousUserIntegTests.java
index 9529a12a30a..431b3e855c6 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/user/AnonymousUserIntegTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/user/AnonymousUserIntegTests.java
@@ -6,6 +6,7 @@
package org.elasticsearch.xpack.security.user;
import org.apache.http.util.EntityUtils;
+import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.common.settings.Settings;
@@ -46,7 +47,7 @@ public class AnonymousUserIntegTests extends SecurityIntegTestCase {
public void testAnonymousViaHttp() throws Exception {
try {
- getRestClient().performRequest("GET", "/_nodes");
+ getRestClient().performRequest(new Request("GET", "/_nodes"));
fail("request should have failed");
} catch(ResponseException e) {
int statusCode = e.getResponse().getStatusLine().getStatusCode();
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/ssl/SSLClientAuthTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/ssl/SSLClientAuthTests.java
index d205c7cd933..21da604374f 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/ssl/SSLClientAuthTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/ssl/SSLClientAuthTests.java
@@ -6,12 +6,13 @@
package org.elasticsearch.xpack.ssl;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
-import org.apache.http.message.BasicHeader;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ExceptionsHelper;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.transport.TransportClient;
@@ -71,7 +72,7 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
public void testThatHttpFailsWithoutSslClientAuth() throws IOException {
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(SSLContexts.createDefault(), NoopHostnameVerifier.INSTANCE);
try (RestClient restClient = createRestClient(httpClientBuilder -> httpClientBuilder.setSSLStrategy(sessionStrategy), "https")) {
- restClient.performRequest("GET", "/");
+ restClient.performRequest(new Request("GET", "/"));
fail("Expected SSLHandshakeException");
} catch (IOException e) {
Throwable t = ExceptionsHelper.unwrap(e, CertPathBuilderException.class);
@@ -87,8 +88,11 @@ public class SSLClientAuthTests extends SecurityIntegTestCase {
public void testThatHttpWorksWithSslClientAuth() throws IOException {
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(getSSLContext(), NoopHostnameVerifier.INSTANCE);
try (RestClient restClient = createRestClient(httpClientBuilder -> httpClientBuilder.setSSLStrategy(sessionStrategy), "https")) {
- Response response = restClient.performRequest("GET", "/",
- new BasicHeader("Authorization", basicAuthHeaderValue(transportClientUsername(), transportClientPassword())));
+ Request request = new Request("GET", "/");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader("Authorization", basicAuthHeaderValue(transportClientUsername(), transportClientPassword()));
+ request.setOptions(options);
+ Response response = restClient.performRequest(request);
assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
assertThat(EntityUtils.toString(response.getEntity()), containsString("You Know, for Search"));
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/ssl/SSLTrustRestrictionsTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/ssl/SSLTrustRestrictionsTests.java
index cf77ca975a4..e1896e01365 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/ssl/SSLTrustRestrictionsTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/ssl/SSLTrustRestrictionsTests.java
@@ -7,6 +7,7 @@ package org.elasticsearch.xpack.ssl;
import org.apache.logging.log4j.message.ParameterizedMessage;
import org.elasticsearch.ElasticsearchException;
+import org.elasticsearch.bootstrap.JavaVersion;
import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
@@ -173,6 +174,8 @@ public class SSLTrustRestrictionsTests extends SecurityIntegTestCase {
}
public void testCertificateWithUntrustedNameFails() throws Exception {
+ // see https://github.com/elastic/elasticsearch/issues/29989
+ assumeTrue("test fails on JDK 11 currently", JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0);
writeRestrictions("*.trusted");
try {
tryConnect(untrustedCert);
@@ -183,6 +186,8 @@ public class SSLTrustRestrictionsTests extends SecurityIntegTestCase {
}
public void testRestrictionsAreReloaded() throws Exception {
+ // see https://github.com/elastic/elasticsearch/issues/29989
+ assumeTrue("test fails on JDK 11 currently", JavaVersion.current().compareTo(JavaVersion.parse("11")) < 0);
writeRestrictions("*");
assertBusy(() -> {
try {
diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/rest/action/RestDeleteWatchAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/rest/action/RestDeleteWatchAction.java
index e41d52c1954..28eb884bbe8 100644
--- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/rest/action/RestDeleteWatchAction.java
+++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/rest/action/RestDeleteWatchAction.java
@@ -14,8 +14,8 @@ import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.rest.action.RestBuilderListener;
import org.elasticsearch.xpack.core.watcher.client.WatcherClient;
-import org.elasticsearch.xpack.core.watcher.transport.actions.delete.DeleteWatchRequest;
-import org.elasticsearch.xpack.core.watcher.transport.actions.delete.DeleteWatchResponse;
+import org.elasticsearch.protocol.xpack.watcher.DeleteWatchRequest;
+import org.elasticsearch.protocol.xpack.watcher.DeleteWatchResponse;
import org.elasticsearch.xpack.watcher.rest.WatcherRestHandler;
import java.io.IOException;
diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java
index d7ff25b623f..9cc94820554 100644
--- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java
+++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/transport/actions/delete/TransportDeleteWatchAction.java
@@ -18,8 +18,8 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.core.watcher.transport.actions.delete.DeleteWatchAction;
-import org.elasticsearch.xpack.core.watcher.transport.actions.delete.DeleteWatchRequest;
-import org.elasticsearch.xpack.core.watcher.transport.actions.delete.DeleteWatchResponse;
+import org.elasticsearch.protocol.xpack.watcher.DeleteWatchRequest;
+import org.elasticsearch.protocol.xpack.watcher.DeleteWatchResponse;
import org.elasticsearch.xpack.core.watcher.watch.Watch;
import java.util.function.Supplier;
diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/BasicWatcherTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/BasicWatcherTests.java
index 18f151b4f6a..c07e6ba3db1 100644
--- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/BasicWatcherTests.java
+++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/test/integration/BasicWatcherTests.java
@@ -19,7 +19,7 @@ import org.elasticsearch.test.junit.annotations.TestLogging;
import org.elasticsearch.xpack.core.watcher.client.WatchSourceBuilder;
import org.elasticsearch.xpack.core.watcher.client.WatcherClient;
import org.elasticsearch.xpack.core.watcher.support.xcontent.XContentSource;
-import org.elasticsearch.xpack.core.watcher.transport.actions.delete.DeleteWatchResponse;
+import org.elasticsearch.protocol.xpack.watcher.DeleteWatchResponse;
import org.elasticsearch.xpack.core.watcher.transport.actions.get.GetWatchResponse;
import org.elasticsearch.xpack.core.watcher.watch.Watch;
import org.elasticsearch.xpack.watcher.condition.CompareCondition;
diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transport/action/WatchRequestValidationTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transport/action/WatchRequestValidationTests.java
index 64b913f96a0..62985cad1f1 100644
--- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transport/action/WatchRequestValidationTests.java
+++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transport/action/WatchRequestValidationTests.java
@@ -14,7 +14,7 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.watcher.execution.ActionExecutionMode;
import org.elasticsearch.xpack.core.watcher.transport.actions.ack.AckWatchRequest;
import org.elasticsearch.xpack.core.watcher.transport.actions.activate.ActivateWatchRequest;
-import org.elasticsearch.xpack.core.watcher.transport.actions.delete.DeleteWatchRequest;
+import org.elasticsearch.protocol.xpack.watcher.DeleteWatchRequest;
import org.elasticsearch.xpack.core.watcher.transport.actions.execute.ExecuteWatchRequest;
import org.elasticsearch.xpack.core.watcher.transport.actions.get.GetWatchRequest;
diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transport/action/delete/DeleteWatchTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transport/action/delete/DeleteWatchTests.java
index 76f71b9c95e..2f502cb95aa 100644
--- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transport/action/delete/DeleteWatchTests.java
+++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/transport/action/delete/DeleteWatchTests.java
@@ -13,7 +13,7 @@ import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer;
import org.elasticsearch.xpack.core.watcher.history.HistoryStoreField;
import org.elasticsearch.xpack.core.watcher.support.xcontent.ObjectPath;
-import org.elasticsearch.xpack.core.watcher.transport.actions.delete.DeleteWatchResponse;
+import org.elasticsearch.protocol.xpack.watcher.DeleteWatchResponse;
import org.elasticsearch.xpack.core.watcher.transport.actions.execute.ExecuteWatchResponse;
import org.elasticsearch.xpack.core.watcher.transport.actions.get.GetWatchResponse;
import org.elasticsearch.xpack.watcher.common.http.HttpRequestTemplate;
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/delete/DeleteWatchRequest.java b/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/watcher/DeleteWatchRequest.java
similarity index 67%
rename from x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/delete/DeleteWatchRequest.java
rename to x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/watcher/DeleteWatchRequest.java
index f8c1a71f1eb..1ec83a8c05a 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/watcher/transport/actions/delete/DeleteWatchRequest.java
+++ b/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/watcher/DeleteWatchRequest.java
@@ -1,9 +1,22 @@
/*
- * 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.
+ * 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.xpack.core.watcher.transport.actions.delete;
+package org.elasticsearch.protocol.xpack.watcher;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
@@ -11,7 +24,6 @@ import org.elasticsearch.action.ValidateActions;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.uid.Versions;
-import org.elasticsearch.xpack.core.watcher.support.WatcherUtils;
import java.io.IOException;
@@ -50,7 +62,7 @@ public class DeleteWatchRequest extends ActionRequest {
ActionRequestValidationException validationException = null;
if (id == null){
validationException = ValidateActions.addValidationError("watch id is missing", validationException);
- } else if (WatcherUtils.isValidId(id) == false) {
+ } else if (PutWatchRequest.isValidId(id) == false) {
validationException = ValidateActions.addValidationError("watch id contains whitespace", validationException);
}
return validationException;
diff --git a/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/watcher/DeleteWatchResponse.java b/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/watcher/DeleteWatchResponse.java
new file mode 100644
index 00000000000..b644a6a854c
--- /dev/null
+++ b/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/watcher/DeleteWatchResponse.java
@@ -0,0 +1,123 @@
+/*
+ * 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.protocol.xpack.watcher;
+
+import org.elasticsearch.action.ActionResponse;
+import org.elasticsearch.common.ParseField;
+import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.common.io.stream.StreamOutput;
+import org.elasticsearch.common.xcontent.ObjectParser;
+import org.elasticsearch.common.xcontent.ToXContentObject;
+import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentParser;
+
+import java.io.IOException;
+import java.util.Objects;
+
+public class DeleteWatchResponse extends ActionResponse implements ToXContentObject {
+
+ private static final ObjectParser PARSER
+ = new ObjectParser<>("x_pack_delete_watch_response", DeleteWatchResponse::new);
+ static {
+ PARSER.declareString(DeleteWatchResponse::setId, new ParseField("_id"));
+ PARSER.declareLong(DeleteWatchResponse::setVersion, new ParseField("_version"));
+ PARSER.declareBoolean(DeleteWatchResponse::setFound, new ParseField("found"));
+ }
+
+ private String id;
+ private long version;
+ private boolean found;
+
+ public DeleteWatchResponse() {
+ }
+
+ public DeleteWatchResponse(String id, long version, boolean found) {
+ this.id = id;
+ this.version = version;
+ this.found = found;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public boolean isFound() {
+ return found;
+ }
+
+ private void setId(String id) {
+ this.id = id;
+ }
+
+ private void setVersion(long version) {
+ this.version = version;
+ }
+
+ private void setFound(boolean found) {
+ this.found = found;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ DeleteWatchResponse that = (DeleteWatchResponse) o;
+
+ return Objects.equals(id, that.id) && Objects.equals(version, that.version) && Objects.equals(found, that.found);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, version, found);
+ }
+
+ @Override
+ public void readFrom(StreamInput in) throws IOException {
+ super.readFrom(in);
+ id = in.readString();
+ version = in.readVLong();
+ found = in.readBoolean();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ super.writeTo(out);
+ out.writeString(id);
+ out.writeVLong(version);
+ out.writeBoolean(found);
+ }
+
+ @Override
+ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
+ return builder.startObject()
+ .field("_id", id)
+ .field("_version", version)
+ .field("found", found)
+ .endObject();
+ }
+
+ public static DeleteWatchResponse fromXContent(XContentParser parser) throws IOException {
+ return PARSER.parse(parser, null);
+ }
+}
diff --git a/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/watcher/DeleteWatchResponseTests.java b/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/watcher/DeleteWatchResponseTests.java
new file mode 100644
index 00000000000..1dbc4cec321
--- /dev/null
+++ b/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/watcher/DeleteWatchResponseTests.java
@@ -0,0 +1,45 @@
+/*
+ * 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.protocol.xpack.watcher;
+
+import org.elasticsearch.common.xcontent.XContentParser;
+import org.elasticsearch.test.AbstractXContentTestCase;
+
+import java.io.IOException;
+
+public class DeleteWatchResponseTests extends AbstractXContentTestCase {
+
+ @Override
+ protected DeleteWatchResponse createTestInstance() {
+ String id = randomAlphaOfLength(10);
+ long version = randomLongBetween(1, 10);
+ boolean found = randomBoolean();
+ return new DeleteWatchResponse(id, version, found);
+ }
+
+ @Override
+ protected DeleteWatchResponse doParseInstance(XContentParser parser) throws IOException {
+ return DeleteWatchResponse.fromXContent(parser);
+ }
+
+ @Override
+ protected boolean supportsUnknownFields() {
+ return false;
+ }
+}
diff --git a/x-pack/qa/kerberos-tests/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosAuthenticationIT.java b/x-pack/qa/kerberos-tests/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosAuthenticationIT.java
index d5928cb58f6..a36040d1ba8 100644
--- a/x-pack/qa/kerberos-tests/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosAuthenticationIT.java
+++ b/x-pack/qa/kerberos-tests/src/test/java/org/elasticsearch/xpack/security/authc/kerberos/KerberosAuthenticationIT.java
@@ -82,6 +82,7 @@ public class KerberosAuthenticationIT extends ESRestTestCase {
assertOK(response);
}
+ @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/32498")
public void testLoginByKeytab() throws IOException, PrivilegedActionException {
final String userPrincipalName = System.getProperty(TEST_USER_WITH_KEYTAB_KEY);
final String keytabPath = System.getProperty(TEST_USER_WITH_KEYTAB_PATH_KEY);
@@ -91,6 +92,7 @@ public class KerberosAuthenticationIT extends ESRestTestCase {
executeRequestAndVerifyResponse(userPrincipalName, callbackHandler);
}
+ @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/32498")
public void testLoginByUsernamePassword() throws IOException, PrivilegedActionException {
final String userPrincipalName = System.getProperty(TEST_USER_WITH_PWD_KEY);
final String password = System.getProperty(TEST_USER_WITH_PWD_PASSWD_KEY);
@@ -100,6 +102,10 @@ public class KerberosAuthenticationIT extends ESRestTestCase {
executeRequestAndVerifyResponse(userPrincipalName, callbackHandler);
}
+ public void testSoDoesNotFailWithNoTests() {
+ // intentionally empty - this is just needed to ensure the build does not fail because we mute its only test.
+ }
+
private void executeRequestAndVerifyResponse(final String userPrincipalName,
final SpnegoHttpClientConfigCallbackHandler callbackHandler) throws PrivilegedActionException, IOException {
final Request request = new Request("GET", "/_xpack/security/_authenticate");
diff --git a/x-pack/qa/security-example-spi-extension/src/test/java/org/elasticsearch/example/realm/CustomRealmIT.java b/x-pack/qa/security-example-spi-extension/src/test/java/org/elasticsearch/example/realm/CustomRealmIT.java
index 65ec595a0d4..f7bdb0d0baa 100644
--- a/x-pack/qa/security-example-spi-extension/src/test/java/org/elasticsearch/example/realm/CustomRealmIT.java
+++ b/x-pack/qa/security-example-spi-extension/src/test/java/org/elasticsearch/example/realm/CustomRealmIT.java
@@ -5,10 +5,11 @@
*/
package org.elasticsearch.example.realm;
-import org.apache.http.message.BasicHeader;
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;
+import org.elasticsearch.client.Request;
+import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.client.transport.NoNodeAvailableException;
@@ -50,7 +51,7 @@ public class CustomRealmIT extends ESIntegTestCase {
public void testHttpConnectionWithNoAuthentication() throws Exception {
try {
- getRestClient().performRequest("GET", "/");
+ getRestClient().performRequest(new Request("GET", "/"));
fail("request should have failed");
} catch(ResponseException e) {
Response response = e.getResponse();
@@ -61,9 +62,12 @@ public class CustomRealmIT extends ESIntegTestCase {
}
public void testHttpAuthentication() throws Exception {
- Response response = getRestClient().performRequest("GET", "/",
- new BasicHeader(CustomRealm.USER_HEADER, CustomRealm.KNOWN_USER),
- new BasicHeader(CustomRealm.PW_HEADER, CustomRealm.KNOWN_PW.toString()));
+ Request request = new Request("GET", "/");
+ RequestOptions.Builder options = request.getOptions().toBuilder();
+ options.addHeader(CustomRealm.USER_HEADER, CustomRealm.KNOWN_USER);
+ options.addHeader(CustomRealm.PW_HEADER, CustomRealm.KNOWN_PW.toString());
+ request.setOptions(options);
+ Response response = getRestClient().performRequest(request);
assertThat(response.getStatusLine().getStatusCode(), is(200));
}
diff --git a/x-pack/qa/security-example-spi-extension/src/test/java/org/elasticsearch/example/role/CustomRolesProviderIT.java b/x-pack/qa/security-example-spi-extension/src/test/java/org/elasticsearch/example/role/CustomRolesProviderIT.java
index bd3c53a3b41..57a895848e3 100644
--- a/x-pack/qa/security-example-spi-extension/src/test/java/org/elasticsearch/example/role/CustomRolesProviderIT.java
+++ b/x-pack/qa/security-example-spi-extension/src/test/java/org/elasticsearch/example/role/CustomRolesProviderIT.java
@@ -5,7 +5,8 @@
*/
package org.elasticsearch.example.role;
-import org.apache.http.message.BasicHeader;
+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;
@@ -33,10 +34,17 @@ import static org.hamcrest.Matchers.is;
* Integration test for custom roles providers.
*/
public class CustomRolesProviderIT extends ESIntegTestCase {
-
private static final String TEST_USER = "test_user";
private static final String TEST_PWD = "change_me";
+ private static final RequestOptions AUTH_OPTIONS;
+ static {
+ RequestOptions.Builder options = RequestOptions.DEFAULT.toBuilder();
+ options.addHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
+ basicAuthHeaderValue(TEST_USER, new SecureString(TEST_PWD.toCharArray())));
+ AUTH_OPTIONS = options.build();
+ }
+
@Override
protected Settings externalClusterClientSettings() {
return Settings.builder()
@@ -59,7 +67,9 @@ public class CustomRolesProviderIT extends ESIntegTestCase {
public void testAuthorizedCustomRoleSucceeds() throws Exception {
setupTestUser(ROLE_B);
// roleB has all permissions on index "foo", so creating "foo" should succeed
- Response response = getRestClient().performRequest("PUT", "/" + INDEX, authHeader());
+ Request request = new Request("PUT", "/" + INDEX);
+ request.setOptions(AUTH_OPTIONS);
+ Response response = getRestClient().performRequest(request);
assertThat(response.getStatusLine().getStatusCode(), is(200));
}
@@ -71,7 +81,9 @@ public class CustomRolesProviderIT extends ESIntegTestCase {
setupTestUser(ROLE_A);
// roleB has all permissions on index "foo", so creating "foo" should succeed
try {
- getRestClient().performRequest("PUT", "/" + INDEX, authHeader());
+ Request request = new Request("PUT", "/" + INDEX);
+ request.setOptions(AUTH_OPTIONS);
+ getRestClient().performRequest(request);
fail(ROLE_A + " should not be authorized to create index " + INDEX);
} catch (ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403));
@@ -82,15 +94,12 @@ public class CustomRolesProviderIT extends ESIntegTestCase {
setupTestUser("unknown");
// roleB has all permissions on index "foo", so creating "foo" should succeed
try {
- getRestClient().performRequest("PUT", "/" + INDEX, authHeader());
+ Request request = new Request("PUT", "/" + INDEX);
+ request.setOptions(AUTH_OPTIONS);
+ getRestClient().performRequest(request);
fail(ROLE_A + " should not be authorized to create index " + INDEX);
} catch (ResponseException e) {
assertThat(e.getResponse().getStatusLine().getStatusCode(), is(403));
}
}
-
- private BasicHeader authHeader() {
- return new BasicHeader(UsernamePasswordToken.BASIC_AUTH_HEADER,
- basicAuthHeaderValue(TEST_USER, new SecureString(TEST_PWD.toCharArray())));
- }
}
diff --git a/x-pack/qa/sql/no-security/src/test/java/org/elasticsearch/xpack/qa/sql/nosecurity/JdbcShardFailureIT.java b/x-pack/qa/sql/no-security/src/test/java/org/elasticsearch/xpack/qa/sql/nosecurity/JdbcShardFailureIT.java
new file mode 100644
index 00000000000..e88b6b94d20
--- /dev/null
+++ b/x-pack/qa/sql/no-security/src/test/java/org/elasticsearch/xpack/qa/sql/nosecurity/JdbcShardFailureIT.java
@@ -0,0 +1,51 @@
+/*
+ * 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.qa.sql.nosecurity;
+
+import org.elasticsearch.client.Request;
+import org.elasticsearch.xpack.qa.sql.jdbc.JdbcIntegrationTestCase;
+import org.junit.Before;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import static org.hamcrest.Matchers.containsString;
+
+public class JdbcShardFailureIT extends JdbcIntegrationTestCase {
+ @Before
+ public void createTestIndex() throws IOException {
+ Request createTest1 = new Request("PUT", "/test1");
+ String body1 = "{\"aliases\":{\"test\":{}}, \"mappings\": {\"doc\": {\"properties\": {\"test_field\":{\"type\":\"integer\"}}}}}";
+ createTest1.setJsonEntity(body1);
+ client().performRequest(createTest1);
+
+ Request createTest2 = new Request("PUT", "/test2");
+ String body2 = "{\"aliases\":{\"test\":{}}, \"mappings\": {\"doc\": {\"properties\": {\"test_field\":{\"type\":\"integer\"}}}}," +
+ "\"settings\": {\"index.routing.allocation.include.node\": \"nowhere\"}}";
+ createTest2.setJsonEntity(body2);
+ createTest2.addParameter("timeout", "100ms");
+ client().performRequest(createTest2);
+
+ Request request = new Request("PUT", "/test1/doc/_bulk");
+ request.addParameter("refresh", "true");
+ StringBuilder bulk = new StringBuilder();
+ for (int i = 0; i < 20; i++) {
+ bulk.append("{\"index\":{}}\n");
+ bulk.append("{\"test_field\":" + i + "}\n");
+ }
+ request.setJsonEntity(bulk.toString());
+ client().performRequest(request);
+ }
+
+ public void testPartialResponseHandling() throws SQLException {
+ try (Connection c = esJdbc(); Statement s = c.createStatement()) {
+ SQLException exception = expectThrows(SQLException.class, () -> s.executeQuery("SELECT * FROM test ORDER BY test_field ASC"));
+ assertThat(exception.getMessage(), containsString("Search rejected due to missing shards"));
+ }
+ }
+}