Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch security to new style Requests #32290

Merged
merged 6 commits into from
Jul 30, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -24,10 +21,8 @@
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 {

Expand Down Expand Up @@ -77,46 +72,48 @@ public void testThatBulkUpdateDoesNotLoseFields() {

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));

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\""));
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);

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\""));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -160,10 +161,15 @@ public void onFailure(Exception e) {
}

static void executeHttpRequest(String path, Map<String, String> 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<String, String> 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"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -388,9 +389,12 @@ public void testUserU14() throws Exception {

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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -15,6 +14,8 @@
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;
Expand Down Expand Up @@ -189,31 +190,36 @@ public void testEnableDisableBehaviour() throws Exception {
}

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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -26,7 +22,6 @@

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;

/**
Expand Down Expand Up @@ -82,23 +77,22 @@ public void setupReservedPasswords() throws IOException {
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");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -31,17 +31,20 @@ protected boolean addMockHttpTransport() {
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()));
}
}
Loading