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 19f56fbd1ec..a4bc34004c2 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 final class SecurityClient {
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 c414cdf8270..8533e0f1b4c 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 @@ public final class SecurityRequestConverters {
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 00000000000..dc5411f3be7
--- /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 00000000000..62fea88e523
--- /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 00000000000..851cb683e05
--- /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 00000000000..ab61f7d879d
--- /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 924fc6ddadb..3670379cd9f 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 class SecurityRequestConvertersTests extends ESTestCase {
}
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 class SecurityRequestConvertersTests extends ESTestCase {
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 5741b0539ba..103b031fc0e 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.action.LatchedActionListener;
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 class SecurityDocumentationIT extends ESRestHighLevelClientTestCase {
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 class SecurityDocumentationIT extends ESRestHighLevelClientTestCase {
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 class SecurityDocumentationIT extends ESRestHighLevelClientTestCase {
// <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 00000000000..37e2e6bb515
--- /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 00000000000..8bb2299946c
--- /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 00000000000..76016532697
--- /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 67%
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 b6d1e0166ee..aca69b81828 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,21 +20,21 @@ 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
-the execution completes
+<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
has completed the `ActionListener` is called back using the `onResponse` method
@@ -45,8 +45,8 @@ 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
-<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/supported-apis.asciidoc b/docs/java-rest/high-level/supported-apis.asciidoc
index eb03d8ee4c6..8d49724353e 100644
--- a/docs/java-rest/high-level/supported-apis.asciidoc
+++ b/docs/java-rest/high-level/supported-apis.asciidoc
@@ -248,6 +248,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: