From 2a9c2c85db5abda92c55b0ffed8e3515307da3db Mon Sep 17 00:00:00 2001 From: jaymode Date: Thu, 6 Sep 2018 12:10:13 -0600 Subject: [PATCH 1/2] HLRC: add enable and disable user API support This change adds support for enable and disable user APIs to the high level rest client. There is a common request base class for both requests with specific requests that simplify the use of these APIs. The response for these APIs is simply an empty object so a new response class has been created for cases where we expect an empty response to be returned. Finally, the put user documentation has been moved to the proper location that is not within an x-pack sub directory and the document tags no longer contain x-pack. See #29827 --- .../elasticsearch/client/SecurityClient.java | 59 ++++++++++ .../client/SecurityRequestConverters.java | 25 +++- .../client/security/DisableUserRequest.java | 30 +++++ .../client/security/EmptyResponse.java | 37 ++++++ .../client/security/EnableUserRequest.java | 30 +++++ .../security/SetUserEnabledRequest.java | 52 +++++++++ .../SecurityRequestConvertersTests.java | 41 ++++++- .../SecurityDocumentationIT.java | 108 ++++++++++++++++-- .../client/security/EmptyResponseTests.java | 51 +++++++++ .../high-level/security/disable-user.asciidoc | 46 ++++++++ .../high-level/security/enable-user.asciidoc | 46 ++++++++ .../{x-pack => }/security/put-user.asciidoc | 20 ++-- .../high-level/supported-apis.asciidoc | 12 ++ 13 files changed, 532 insertions(+), 25 deletions(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/security/DisableUserRequest.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/security/EmptyResponse.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/security/EnableUserRequest.java create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/security/SetUserEnabledRequest.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/security/EmptyResponseTests.java create mode 100644 docs/java-rest/high-level/security/disable-user.asciidoc create mode 100644 docs/java-rest/high-level/security/enable-user.asciidoc rename docs/java-rest/high-level/{x-pack => }/security/put-user.asciidoc (70%) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java index 19f56fbd1ec93..a4bc34004c247 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityClient.java @@ -20,8 +20,11 @@ package org.elasticsearch.client; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.client.security.DisableUserRequest; +import org.elasticsearch.client.security.EnableUserRequest; import org.elasticsearch.client.security.PutUserRequest; import org.elasticsearch.client.security.PutUserResponse; +import org.elasticsearch.client.security.EmptyResponse; import java.io.IOException; @@ -66,4 +69,60 @@ public void putUserAsync(PutUserRequest request, RequestOptions options, ActionL restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::putUser, options, PutUserResponse::fromXContent, listener, emptySet()); } + + /** + * Enable a native realm or built-in user synchronously. + * See + * the docs for more. + * @param request the request with the user to enable + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return the response from the enable user call + * @throws IOException in case there is a problem sending the request or parsing back the response + */ + public EmptyResponse enableUser(EnableUserRequest request, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::enableUser, options, + EmptyResponse::fromXContent, emptySet()); + } + + /** + * Enable a native realm or built-in user asynchronously. + * See + * the docs for more. + * @param request the request with the user to enable + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @param listener the listener to be notified upon request completion + */ + public void enableUserAsync(EnableUserRequest request, RequestOptions options, + ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::enableUser, options, + EmptyResponse::fromXContent, listener, emptySet()); + } + + /** + * Disable a native realm or built-in user synchronously. + * See + * the docs for more. + * @param request the request with the user to disable + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return the response from the enable user call + * @throws IOException in case there is a problem sending the request or parsing back the response + */ + public EmptyResponse disableUser(DisableUserRequest request, RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, SecurityRequestConverters::disableUser, options, + EmptyResponse::fromXContent, emptySet()); + } + + /** + * Disable a native realm or built-in user asynchronously. + * See + * the docs for more. + * @param request the request with the user to disable + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @param listener the listener to be notified upon request completion + */ + public void disableUserAsync(DisableUserRequest request, RequestOptions options, + ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(request, SecurityRequestConverters::disableUser, options, + EmptyResponse::fromXContent, listener, emptySet()); + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityRequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityRequestConverters.java index c414cdf82708a..8533e0f1b4cd4 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityRequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/SecurityRequestConverters.java @@ -20,14 +20,17 @@ package org.elasticsearch.client; import org.apache.http.client.methods.HttpPut; +import org.elasticsearch.client.security.DisableUserRequest; +import org.elasticsearch.client.security.EnableUserRequest; import org.elasticsearch.client.security.PutUserRequest; +import org.elasticsearch.client.security.SetUserEnabledRequest; import java.io.IOException; import static org.elasticsearch.client.RequestConverters.REQUEST_BODY_CONTENT_TYPE; import static org.elasticsearch.client.RequestConverters.createEntity; -public final class SecurityRequestConverters { +final class SecurityRequestConverters { private SecurityRequestConverters() {} @@ -42,4 +45,24 @@ static Request putUser(PutUserRequest putUserRequest) throws IOException { params.withRefreshPolicy(putUserRequest.getRefreshPolicy()); return request; } + + static Request enableUser(EnableUserRequest enableUserRequest) { + return setUserEnabled(enableUserRequest); + } + + static Request disableUser(DisableUserRequest disableUserRequest) { + return setUserEnabled(disableUserRequest); + } + + private static Request setUserEnabled(SetUserEnabledRequest setUserEnabledRequest) { + String endpoint = new RequestConverters.EndpointBuilder() + .addPathPartAsIs("_xpack/security/user") + .addPathPart(setUserEnabledRequest.getUsername()) + .addPathPart(setUserEnabledRequest.isEnabled() ? "_enable" : "_disable") + .build(); + Request request = new Request(HttpPut.METHOD_NAME, endpoint); + RequestConverters.Params params = new RequestConverters.Params(request); + params.withRefreshPolicy(setUserEnabledRequest.getRefreshPolicy()); + return request; + } } diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/DisableUserRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/DisableUserRequest.java new file mode 100644 index 0000000000000..dc5411f3be7d1 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/DisableUserRequest.java @@ -0,0 +1,30 @@ +/* + * 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.client.security; + +/** + * Request object to disable a native realm or built-in user. + */ +public final class DisableUserRequest extends SetUserEnabledRequest { + + public DisableUserRequest(String username, RefreshPolicy refreshPolicy) { + super(false, username, refreshPolicy); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/EmptyResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/EmptyResponse.java new file mode 100644 index 0000000000000..62fea88e52356 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/EmptyResponse.java @@ -0,0 +1,37 @@ +/* + * 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.client.security; + +import org.elasticsearch.common.xcontent.ObjectParser; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; + +/** + * Response for a request which simply returns an empty object. + */ +public final class EmptyResponse { + + private static final ObjectParser PARSER = new ObjectParser<>("empty_response", false, EmptyResponse::new); + + public static EmptyResponse fromXContent(XContentParser parser) throws IOException { + return PARSER.parse(parser, null); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/EnableUserRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/EnableUserRequest.java new file mode 100644 index 0000000000000..851cb683e0551 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/EnableUserRequest.java @@ -0,0 +1,30 @@ +/* + * 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.client.security; + +/** + * Request object to enable a native realm or built-in user. + */ +public final class EnableUserRequest extends SetUserEnabledRequest { + + public EnableUserRequest(String username, RefreshPolicy refreshPolicy) { + super(true, username, refreshPolicy); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/SetUserEnabledRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/SetUserEnabledRequest.java new file mode 100644 index 0000000000000..ab61f7d879d22 --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/SetUserEnabledRequest.java @@ -0,0 +1,52 @@ +/* + * 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.client.security; + +import org.elasticsearch.client.Validatable; + +import java.util.Objects; + +/** + * Abstract request object to enable or disable a built-in or native user. + */ +public abstract class SetUserEnabledRequest implements Validatable { + + private final boolean enabled; + private final String username; + private final RefreshPolicy refreshPolicy; + + SetUserEnabledRequest(boolean enabled, String username, RefreshPolicy refreshPolicy) { + this.enabled = enabled; + this.username = Objects.requireNonNull(username, "username is required"); + this.refreshPolicy = refreshPolicy == null ? RefreshPolicy.getDefault() : refreshPolicy; + } + + public boolean isEnabled() { + return enabled; + } + + public String getUsername() { + return username; + } + + public RefreshPolicy getRefreshPolicy() { + return refreshPolicy; + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java index 924fc6ddadbed..3670379cd9fee 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/SecurityRequestConvertersTests.java @@ -20,6 +20,8 @@ package org.elasticsearch.client; import org.apache.http.client.methods.HttpPut; +import org.elasticsearch.client.security.DisableUserRequest; +import org.elasticsearch.client.security.EnableUserRequest; import org.elasticsearch.client.security.PutUserRequest; import org.elasticsearch.client.security.RefreshPolicy; import org.elasticsearch.test.ESTestCase; @@ -53,12 +55,7 @@ public void testPutUser() throws IOException { } final RefreshPolicy refreshPolicy = randomFrom(RefreshPolicy.values()); - final Map expectedParams; - if (refreshPolicy != RefreshPolicy.NONE) { - expectedParams = Collections.singletonMap("refresh", refreshPolicy.getValue()); - } else { - expectedParams = Collections.emptyMap(); - } + final Map expectedParams = getExpectedParamsFromRefreshPolicy(refreshPolicy); PutUserRequest putUserRequest = new PutUserRequest(username, password, roles, fullName, email, enabled, metadata, refreshPolicy); Request request = SecurityRequestConverters.putUser(putUserRequest); @@ -67,4 +64,36 @@ public void testPutUser() throws IOException { assertEquals(expectedParams, request.getParameters()); assertToXContentBody(putUserRequest, request.getEntity()); } + + public void testEnableUser() { + final String username = randomAlphaOfLengthBetween(1, 12); + final RefreshPolicy refreshPolicy = randomFrom(RefreshPolicy.values()); + final Map expectedParams = getExpectedParamsFromRefreshPolicy(refreshPolicy); + EnableUserRequest enableUserRequest = new EnableUserRequest(username, refreshPolicy); + Request request = SecurityRequestConverters.enableUser(enableUserRequest); + assertEquals(HttpPut.METHOD_NAME, request.getMethod()); + assertEquals("/_xpack/security/user/" + username + "/_enable", request.getEndpoint()); + assertEquals(expectedParams, request.getParameters()); + assertNull(request.getEntity()); + } + + public void testDisableUser() { + final String username = randomAlphaOfLengthBetween(1, 12); + final RefreshPolicy refreshPolicy = randomFrom(RefreshPolicy.values()); + final Map expectedParams = getExpectedParamsFromRefreshPolicy(refreshPolicy); + DisableUserRequest disableUserRequest = new DisableUserRequest(username, refreshPolicy); + Request request = SecurityRequestConverters.disableUser(disableUserRequest); + assertEquals(HttpPut.METHOD_NAME, request.getMethod()); + assertEquals("/_xpack/security/user/" + username + "/_disable", request.getEndpoint()); + assertEquals(expectedParams, request.getParameters()); + assertNull(request.getEntity()); + } + + private static Map getExpectedParamsFromRefreshPolicy(RefreshPolicy refreshPolicy) { + if (refreshPolicy != RefreshPolicy.NONE) { + return Collections.singletonMap("refresh", refreshPolicy.getValue()); + } else { + return Collections.emptyMap(); + } + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java index 5741b0539ba0e..103b031fc0e03 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SecurityDocumentationIT.java @@ -24,9 +24,12 @@ import org.elasticsearch.client.ESRestHighLevelClientTestCase; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.security.DisableUserRequest; +import org.elasticsearch.client.security.EnableUserRequest; import org.elasticsearch.client.security.PutUserRequest; import org.elasticsearch.client.security.PutUserResponse; import org.elasticsearch.client.security.RefreshPolicy; +import org.elasticsearch.client.security.EmptyResponse; import java.util.Collections; import java.util.concurrent.CountDownLatch; @@ -38,16 +41,16 @@ public void testPutUser() throws Exception { RestHighLevelClient client = highLevelClient(); { - //tag::x-pack-put-user-execute + //tag::put-user-execute char[] password = new char[] { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' }; PutUserRequest request = new PutUserRequest("example", password, Collections.singletonList("superuser"), null, null, true, null, RefreshPolicy.NONE); PutUserResponse response = client.security().putUser(request, RequestOptions.DEFAULT); - //end::x-pack-put-user-execute + //end::put-user-execute - //tag::x-pack-put-user-response + //tag::put-user-response boolean isCreated = response.isCreated(); // <1> - //end::x-pack-put-user-response + //end::put-user-response assertTrue(isCreated); } @@ -56,7 +59,7 @@ public void testPutUser() throws Exception { char[] password = new char[] { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' }; PutUserRequest request = new PutUserRequest("example2", password, Collections.singletonList("superuser"), null, null, true, null, RefreshPolicy.NONE); - // tag::x-pack-put-user-execute-listener + // tag::put-user-execute-listener ActionListener listener = new ActionListener() { @Override public void onResponse(PutUserResponse response) { @@ -68,15 +71,104 @@ public void onFailure(Exception e) { // <2> } }; - // end::x-pack-put-user-execute-listener + // end::put-user-execute-listener // Replace the empty listener by a blocking listener in test final CountDownLatch latch = new CountDownLatch(1); listener = new LatchedActionListener<>(listener, latch); - // tag::x-pack-put-user-execute-async + // tag::put-user-execute-async client.security().putUserAsync(request, RequestOptions.DEFAULT, listener); // <1> - // end::x-pack-put-user-execute-async + // end::put-user-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } + } + + public void testEnableUser() throws Exception { + RestHighLevelClient client = highLevelClient(); + char[] password = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; + PutUserRequest putUserRequest = new PutUserRequest("enable_user", password, Collections.singletonList("superuser"), null, + null, true, null, RefreshPolicy.IMMEDIATE); + PutUserResponse putUserResponse = client.security().putUser(putUserRequest, RequestOptions.DEFAULT); + assertTrue(putUserResponse.isCreated()); + + { + //tag::enable-user-execute + EnableUserRequest request = new EnableUserRequest("enable_user", RefreshPolicy.NONE); + EmptyResponse response = client.security().enableUser(request, RequestOptions.DEFAULT); + //end::enable-user-execute + + assertNotNull(response); + } + + { + //tag::enable-user-execute-listener + EnableUserRequest request = new EnableUserRequest("enable_user", RefreshPolicy.NONE); + ActionListener listener = new ActionListener() { + @Override + public void onResponse(EmptyResponse setUserEnabledResponse) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + //end::enable-user-execute-listener + + // Replace the empty listener by a blocking listener in test + final CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + + // tag::enable-user-execute-async + client.security().enableUserAsync(request, RequestOptions.DEFAULT, listener); // <1> + // end::enable-user-execute-async + + assertTrue(latch.await(30L, TimeUnit.SECONDS)); + } + } + + public void testDisableUser() throws Exception { + RestHighLevelClient client = highLevelClient(); + char[] password = new char[]{'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; + PutUserRequest putUserRequest = new PutUserRequest("disable_user", password, Collections.singletonList("superuser"), null, + null, true, null, RefreshPolicy.IMMEDIATE); + PutUserResponse putUserResponse = client.security().putUser(putUserRequest, RequestOptions.DEFAULT); + assertTrue(putUserResponse.isCreated()); + { + //tag::disable-user-execute + DisableUserRequest request = new DisableUserRequest("disable_user", RefreshPolicy.NONE); + EmptyResponse response = client.security().disableUser(request, RequestOptions.DEFAULT); + //end::disable-user-execute + + assertNotNull(response); + } + + { + //tag::disable-user-execute-listener + DisableUserRequest request = new DisableUserRequest("disable_user", RefreshPolicy.NONE); + ActionListener listener = new ActionListener() { + @Override + public void onResponse(EmptyResponse setUserEnabledResponse) { + // <1> + } + + @Override + public void onFailure(Exception e) { + // <2> + } + }; + //end::disable-user-execute-listener + + // Replace the empty listener by a blocking listener in test + final CountDownLatch latch = new CountDownLatch(1); + listener = new LatchedActionListener<>(listener, latch); + + // tag::disable-user-execute-async + client.security().disableUserAsync(request, RequestOptions.DEFAULT, listener); // <1> + // end::disable-user-execute-async assertTrue(latch.await(30L, TimeUnit.SECONDS)); } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/EmptyResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/EmptyResponseTests.java new file mode 100644 index 0000000000000..37e2e6bb51565 --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/EmptyResponseTests.java @@ -0,0 +1,51 @@ +/* + * 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.client.security; + +import org.elasticsearch.common.xcontent.DeprecationHandler; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; +import org.elasticsearch.common.xcontent.XContentParseException; +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.common.xcontent.json.JsonXContent; +import org.elasticsearch.test.ESTestCase; + +import java.io.IOException; + +import static org.hamcrest.Matchers.containsString; + +public class EmptyResponseTests extends ESTestCase { + + public void testParseFromXContent() throws IOException { + try (XContentParser parser = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, + DeprecationHandler.THROW_UNSUPPORTED_OPERATION, "{}")) { + + EmptyResponse response = EmptyResponse.fromXContent(parser); + assertNotNull(response); + } + + try (XContentParser parser = JsonXContent.jsonXContent.createParser(NamedXContentRegistry.EMPTY, + DeprecationHandler.THROW_UNSUPPORTED_OPERATION, "{\"foo\": \"bar\"}")) { + + XContentParseException exception = + expectThrows(XContentParseException.class, () -> EmptyResponse.fromXContent(parser)); + assertThat(exception.getMessage(), containsString("field [foo]")); + } + } +} diff --git a/docs/java-rest/high-level/security/disable-user.asciidoc b/docs/java-rest/high-level/security/disable-user.asciidoc new file mode 100644 index 0000000000000..b6266d0cd0159 --- /dev/null +++ b/docs/java-rest/high-level/security/disable-user.asciidoc @@ -0,0 +1,46 @@ +[[java-rest-high-security-disable-user]] +=== Disable User API + +[[java-rest-high-security-disable-user-execution]] +==== Execution + +Disabling a user can be performed using the `security().disableUser()` +method: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[disable-user-execute] +-------------------------------------------------- + +[[java-rest-high-security-disable-user-response]] +==== Response + +The returned `EmptyResponse` does not contain any fields. The return of this +response indicates a successful request. + +[[java-rest-high-security-disable-user-async]] +==== Asynchronous Execution + +This request can be executed asynchronously: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[disable-user-execute-async] +-------------------------------------------------- +<1> The `DisableUser` request to execute and the `ActionListener` to use when +the execution completes + +The asynchronous method does not block and returns immediately. Once the request +has completed the `ActionListener` is called back using the `onResponse` method +if the execution successfully completed or using the `onFailure` method if +it failed. + +A typical listener for a `EmptyResponse` looks like: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[disable-user-execute-listener] +-------------------------------------------------- +<1> Called when the execution is successfully completed. The response is +provided as an argument +<2> Called in case of failure. The raised exception is provided as an argument diff --git a/docs/java-rest/high-level/security/enable-user.asciidoc b/docs/java-rest/high-level/security/enable-user.asciidoc new file mode 100644 index 0000000000000..8e1bb6bf13b51 --- /dev/null +++ b/docs/java-rest/high-level/security/enable-user.asciidoc @@ -0,0 +1,46 @@ +[[java-rest-high-security-enable-user]] +=== Enable User API + +[[java-rest-high-security-enable-user-execution]] +==== Execution + +Enabling a disabled user can be performed using the `security().enableUser()` +method: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[enable-user-execute] +-------------------------------------------------- + +[[java-rest-high-security-enable-user-response]] +==== Response + +The returned `EmptyResponse` does not contain any fields. The return of this +response indicates a successful request. + +[[java-rest-high-security-enable-user-async]] +==== Asynchronous Execution + +This request can be executed asynchronously: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[enable-user-execute-async] +-------------------------------------------------- +<1> The `EnableUser` request to execute and the `ActionListener` to use when +the execution completes + +The asynchronous method does not block and returns immediately. Once the request +has completed the `ActionListener` is called back using the `onResponse` method +if the execution successfully completed or using the `onFailure` method if +it failed. + +A typical listener for a `EmptyResponse` looks like: + +["source","java",subs="attributes,callouts,macros"] +-------------------------------------------------- +include-tagged::{doc-tests}/SecurityDocumentationIT.java[enable-user-execute-listener] +-------------------------------------------------- +<1> Called when the execution is successfully completed. The response is +provided as an argument +<2> Called in case of failure. The raised exception is provided as an argument diff --git a/docs/java-rest/high-level/x-pack/security/put-user.asciidoc b/docs/java-rest/high-level/security/put-user.asciidoc similarity index 70% rename from docs/java-rest/high-level/x-pack/security/put-user.asciidoc rename to docs/java-rest/high-level/security/put-user.asciidoc index b6d1e0166eede..d98511fbe06e7 100644 --- a/docs/java-rest/high-level/x-pack/security/put-user.asciidoc +++ b/docs/java-rest/high-level/security/put-user.asciidoc @@ -1,7 +1,7 @@ -[[java-rest-high-x-pack-security-put-user]] -=== X-Pack Put User API +[[java-rest-high-security-put-user]] +=== Put User API -[[java-rest-high-x-pack-security-put-user-execution]] +[[java-rest-high-security-put-user-execution]] ==== Execution Creating and updating a user can be performed using the `security().putUser()` @@ -9,10 +9,10 @@ method: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SecurityDocumentationIT.java[x-pack-put-user-execute] +include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-execute] -------------------------------------------------- -[[java-rest-high-x-pack-security-put-user-response]] +[[java-rest-high-security-put-user-response]] ==== Response The returned `PutUserResponse` contains a single field, `created`. This field @@ -20,20 +20,20 @@ serves as an indication if a user was created or if an existing entry was update ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SecurityDocumentationIT.java[x-pack-put-user-response] +include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-response] -------------------------------------------------- <1> `created` is a boolean indicating whether the user was created or updated -[[java-rest-high-x-pack-security-put-user-async]] +[[java-rest-high-security-put-user-async]] ==== Asynchronous Execution This request can be executed asynchronously: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SecurityDocumentationIT.java[x-pack-put-user-execute-async] +include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-execute-async] -------------------------------------------------- -<1> The `PutUserResponse` to execute and the `ActionListener` to use when +<1> The `PutUserRequest` to execute and the `ActionListener` to use when the execution completes The asynchronous method does not block and returns immediately. Once the request @@ -45,7 +45,7 @@ A typical listener for a `PutUserResponse` looks like: ["source","java",subs="attributes,callouts,macros"] -------------------------------------------------- -include-tagged::{doc-tests}/SecurityDocumentationIT.java[x-pack-put-user-execute-listener] +include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-execute-listener] -------------------------------------------------- <1> Called when the execution is successfully completed. The response is provided as an argument diff --git a/docs/java-rest/high-level/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc index c482c8bccff23..100de2ad3ebdd 100644 --- a/docs/java-rest/high-level/supported-apis.asciidoc +++ b/docs/java-rest/high-level/supported-apis.asciidoc @@ -244,6 +244,18 @@ The Java High Level REST Client supports the following Migration APIs: include::migration/get-assistance.asciidoc[] +== Security APIs + +The Java High Level REST Client supports the following Security APIs: + +* <> +* <> +* <> + +include::security/put-user.asciidoc[] +include::security/enable-user.asciidoc[] +include::security/disable-user.asciidoc[] + == Watcher APIs The Java High Level REST Client supports the following Watcher APIs: From 8358e951f7f59eee48e3d2e5b1004caad618f778 Mon Sep 17 00:00:00 2001 From: jaymode Date: Fri, 7 Sep 2018 08:46:44 -0600 Subject: [PATCH 2/2] add periods --- docs/java-rest/high-level/security/disable-user.asciidoc | 6 +++--- docs/java-rest/high-level/security/enable-user.asciidoc | 6 +++--- docs/java-rest/high-level/security/put-user.asciidoc | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/java-rest/high-level/security/disable-user.asciidoc b/docs/java-rest/high-level/security/disable-user.asciidoc index b6266d0cd0159..8bb2299946c42 100644 --- a/docs/java-rest/high-level/security/disable-user.asciidoc +++ b/docs/java-rest/high-level/security/disable-user.asciidoc @@ -28,7 +28,7 @@ This request can be executed asynchronously: include-tagged::{doc-tests}/SecurityDocumentationIT.java[disable-user-execute-async] -------------------------------------------------- <1> The `DisableUser` request to execute and the `ActionListener` to use when -the execution completes +the execution completes. The asynchronous method does not block and returns immediately. Once the request has completed the `ActionListener` is called back using the `onResponse` method @@ -42,5 +42,5 @@ A typical listener for a `EmptyResponse` looks like: include-tagged::{doc-tests}/SecurityDocumentationIT.java[disable-user-execute-listener] -------------------------------------------------- <1> Called when the execution is successfully completed. The response is -provided as an argument -<2> Called in case of failure. The raised exception is provided as an argument +provided as an argument. +<2> Called in case of failure. The raised exception is provided as an argument. diff --git a/docs/java-rest/high-level/security/enable-user.asciidoc b/docs/java-rest/high-level/security/enable-user.asciidoc index 8e1bb6bf13b51..7601653269789 100644 --- a/docs/java-rest/high-level/security/enable-user.asciidoc +++ b/docs/java-rest/high-level/security/enable-user.asciidoc @@ -28,7 +28,7 @@ This request can be executed asynchronously: include-tagged::{doc-tests}/SecurityDocumentationIT.java[enable-user-execute-async] -------------------------------------------------- <1> The `EnableUser` request to execute and the `ActionListener` to use when -the execution completes +the execution completes. The asynchronous method does not block and returns immediately. Once the request has completed the `ActionListener` is called back using the `onResponse` method @@ -42,5 +42,5 @@ A typical listener for a `EmptyResponse` looks like: include-tagged::{doc-tests}/SecurityDocumentationIT.java[enable-user-execute-listener] -------------------------------------------------- <1> Called when the execution is successfully completed. The response is -provided as an argument -<2> Called in case of failure. The raised exception is provided as an argument +provided as an argument. +<2> Called in case of failure. The raised exception is provided as an argument. diff --git a/docs/java-rest/high-level/security/put-user.asciidoc b/docs/java-rest/high-level/security/put-user.asciidoc index d98511fbe06e7..aca69b8182842 100644 --- a/docs/java-rest/high-level/security/put-user.asciidoc +++ b/docs/java-rest/high-level/security/put-user.asciidoc @@ -34,7 +34,7 @@ This request can be executed asynchronously: include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-execute-async] -------------------------------------------------- <1> The `PutUserRequest` to execute and the `ActionListener` to use when -the execution completes +the execution completes. The asynchronous method does not block and returns immediately. Once the request has completed the `ActionListener` is called back using the `onResponse` method @@ -48,5 +48,5 @@ A typical listener for a `PutUserResponse` looks like: include-tagged::{doc-tests}/SecurityDocumentationIT.java[put-user-execute-listener] -------------------------------------------------- <1> Called when the execution is successfully completed. The response is -provided as an argument -<2> Called in case of failure. The raised exception is provided as an argument +provided as an argument. +<2> Called in case of failure. The raised exception is provided as an argument.