From 2e5945a5e9fb49bcc89872980eba26078bc309a6 Mon Sep 17 00:00:00 2001 From: Jay Modi Date: Tue, 2 Oct 2018 10:10:32 -0600 Subject: [PATCH] HLRC: PutUserRequest should not be closeable (#34196) The PutUserRequest implemented closeable as it assumed ownership of the password provided to the class. This change removes the ownership of the password, documents it in the javadoc, and removes the closeable implementation. Additionally, the intermediate bytes used for writing the password to XContent are now cleared. This makes the PutUserRequest consistent with the behavior discussed in #33509. --- .../client/security/PutUserRequest.java | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutUserRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutUserRequest.java index f8c30a25aed..11e13f621e6 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutUserRequest.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/PutUserRequest.java @@ -25,7 +25,6 @@ import org.elasticsearch.common.CharArrays; import org.elasticsearch.common.xcontent.ToXContentObject; import org.elasticsearch.common.xcontent.XContentBuilder; -import java.io.Closeable; import java.io.IOException; import java.util.Arrays; import java.util.Collections; @@ -37,7 +36,7 @@ import java.util.Optional; /** * Request object to create or update a user in the native realm. */ -public final class PutUserRequest implements Validatable, Closeable, ToXContentObject { +public final class PutUserRequest implements Validatable, ToXContentObject { private final String username; private final List roles; @@ -48,6 +47,20 @@ public final class PutUserRequest implements Validatable, Closeable, ToXContentO private final boolean enabled; private final RefreshPolicy refreshPolicy; + /** + * Creates a new request that is used to create or update a user in the native realm. + * + * @param username the username of the user to be created or updated + * @param password the password of the user. The password array is not modified by this class. + * It is the responsibility of the caller to clear the password after receiving + * a response. + * @param roles the roles that this user is assigned + * @param fullName the full name of the user that may be used for display purposes + * @param email the email address of the user + * @param enabled true if the user is enabled and allowed to access elasticsearch + * @param metadata a map of additional user attributes that may be used in templating roles + * @param refreshPolicy the refresh policy for the request. + */ public PutUserRequest(String username, char[] password, List roles, String fullName, String email, boolean enabled, Map metadata, RefreshPolicy refreshPolicy) { this.username = Objects.requireNonNull(username, "username is required"); @@ -114,13 +127,6 @@ public final class PutUserRequest implements Validatable, Closeable, ToXContentO return result; } - @Override - public void close() { - if (password != null) { - Arrays.fill(password, (char) 0); - } - } - @Override public Optional validate() { if (metadata != null && metadata.keySet().stream().anyMatch(s -> s.startsWith("_"))) { @@ -137,7 +143,11 @@ public final class PutUserRequest implements Validatable, Closeable, ToXContentO builder.field("username", username); if (password != null) { byte[] charBytes = CharArrays.toUtf8Bytes(password); - builder.field("password").utf8Value(charBytes, 0, charBytes.length); + try { + builder.field("password").utf8Value(charBytes, 0, charBytes.length); + } finally { + Arrays.fill(charBytes, (byte) 0); + } } if (roles != null) { builder.field("roles", roles);