diff --git a/adminapi/src/main/java/io/minio/admin/AddServiceAccountReq.java b/adminapi/src/main/java/io/minio/admin/AddServiceAccountReq.java
deleted file mode 100644
index 87120e6f3..000000000
--- a/adminapi/src/main/java/io/minio/admin/AddServiceAccountReq.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * MinIO Java SDK for Amazon S3 Compatible Cloud Storage,
- * (C) 2021 MinIO, Inc.
- *
- * Licensed 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 io.minio.admin;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import javax.annotation.Nullable;
-
-/**
- * add service account request info.
- *
- *
* @see user-commands.go
- */
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class AddServiceAccountReq {
- @JsonProperty("secretKey")
- private String secretKey;
-
- @JsonProperty("policy")
- private byte[] policy;
-
- @JsonProperty("targetUser")
- private String targetUser;
-
- @JsonProperty("accessKey")
- private String accessKey;
-
- @JsonProperty("name")
- private String name;
-
- @JsonProperty("description")
- private String description;
-
- @JsonProperty("expiration")
- private String expiration;
-
- public AddServiceAccountReq() {}
-
- public AddServiceAccountReq(
- @Nullable @JsonProperty("secretKey") String secretKey,
- @Nullable @JsonProperty("policy") byte[] policy,
- @Nullable @JsonProperty("targetUser") String targetUser,
- @Nullable @JsonProperty("accessKey") String accessKey,
- @Nullable @JsonProperty("name") String name,
- @Nullable @JsonProperty("description") String description,
- @Nullable @JsonProperty("expiration") String expiration) {
- this.secretKey = secretKey;
- this.policy = policy;
- this.targetUser = targetUser;
- this.accessKey = accessKey;
- this.name = name;
- this.description = description;
- this.expiration = expiration;
- }
-
- public String secretKey() {
- return secretKey;
- }
-
- public byte[] policy() {
- return policy;
- }
-
- public String targetUser() {
- return targetUser;
- }
-
- public String accessKey() {
- return accessKey;
- }
-
- public String description() {
- return description;
- }
-
- public String name() {
- return name;
- }
-
- public String expiration() {
- return expiration;
- }
-}
diff --git a/adminapi/src/main/java/io/minio/admin/ListServiceAccountResp.java b/adminapi/src/main/java/io/minio/admin/ListServiceAccountResp.java
index d89d05781..addc940f8 100644
--- a/adminapi/src/main/java/io/minio/admin/ListServiceAccountResp.java
+++ b/adminapi/src/main/java/io/minio/admin/ListServiceAccountResp.java
@@ -25,9 +25,25 @@
@JsonIgnoreProperties(ignoreUnknown = true)
public class ListServiceAccountResp {
@JsonProperty("accounts")
- private List accounts;
+ private List accounts;
- public List accounts() {
+ public List accounts() {
return accounts;
}
+
+ public static class ListServiceAccountInfo {
+ @JsonProperty("accessKey")
+ private String accessKey;
+
+ @JsonProperty("expiration")
+ private String expiration;
+
+ public String expiration() {
+ return expiration;
+ }
+
+ public String accessKey() {
+ return accessKey;
+ }
+ }
}
diff --git a/adminapi/src/main/java/io/minio/admin/MinioAdminClient.java b/adminapi/src/main/java/io/minio/admin/MinioAdminClient.java
index 003553e51..622e0e4cd 100644
--- a/adminapi/src/main/java/io/minio/admin/MinioAdminClient.java
+++ b/adminapi/src/main/java/io/minio/admin/MinioAdminClient.java
@@ -37,6 +37,7 @@
import io.minio.credentials.StaticProvider;
import io.minio.http.HttpUtils;
import io.minio.http.Method;
+import io.minio.messages.ResponseDate;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
@@ -46,14 +47,12 @@
import java.security.InvalidKeyException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -620,6 +619,43 @@ public Message getServerInfo() throws IOException, NoSuchAlgorithmException, Inv
}
}
+ private Map buildServiceAccount(
+ String targetUser,
+ String name,
+ String secretKey,
+ String accessKey,
+ String newStatus,
+ String policy,
+ String description,
+ boolean updateFlag,
+ String expiryTime) {
+ Map serviceAccount = new HashMap<>(7);
+ if (!updateFlag) {
+ serviceAccount.put("targetUser", targetUser);
+ serviceAccount.put("accessKey", accessKey);
+ }
+ if (updateFlag && newStatus != null && !newStatus.isEmpty()) {
+ serviceAccount.put("newStatus", newStatus);
+ }
+ if (name != null && !name.isEmpty()) {
+ serviceAccount.put(updateFlag ? "newName" : "name", name);
+ }
+ if (secretKey != null && !secretKey.isEmpty()) {
+ serviceAccount.put(updateFlag ? "newSecretKey" : "secretKey", secretKey);
+ }
+ if (policy != null && !policy.isEmpty()) {
+ serviceAccount.put(
+ updateFlag ? "newPolicy" : "policy", policy.getBytes(StandardCharsets.UTF_8));
+ }
+ if (description != null && !description.isEmpty()) {
+ serviceAccount.put(updateFlag ? "newDescription" : "description", description);
+ }
+ if (expiryTime != null && !expiryTime.isEmpty()) {
+ serviceAccount.put(updateFlag ? "newExpiration" : "expiration", expiryTime);
+ }
+ return serviceAccount;
+ }
+
/**
* Creates a new service account belonging to the user sending.
*
@@ -650,7 +686,7 @@ public Message getServerInfo() throws IOException, NoSuchAlgorithmException, Inv
* @throws IOException thrown to indicate I/O error on MinIO REST operation.
* @throws InvalidCipherTextException thrown to indicate data cannot be encrypted/decrypted.
*/
- public AddServiceAccountReq addServiceAccount(
+ public Credentials addServiceAccount(
@Nonnull String targetUser,
@Nullable String name,
@Nullable String secretKey,
@@ -668,29 +704,27 @@ public AddServiceAccountReq addServiceAccount(
if (description != null && description.length() > 256) {
throw new IllegalArgumentException("description must be at most 256 bytes long");
}
- if (accessKey == null || accessKey.isEmpty()) {
- accessKey = generateCredentials(20);
- }
- if (secretKey == null || secretKey.isEmpty()) {
- secretKey = generateCredentials(40);
- }
- byte[] policyBytes = null;
- if (policy != null && !policy.isEmpty()) {
- policyBytes = policy.getBytes(StandardCharsets.UTF_8);
- }
Credentials creds = getCredentials();
- AddServiceAccountReq addServiceAccountReq =
- new AddServiceAccountReq(
- secretKey, policyBytes, targetUser, accessKey, name, description, expiryTime);
try (Response response =
execute(
Method.PUT,
Command.ADD_SERVICE_ACCOUNT,
ImmutableMultimap.of("accessKey", accessKey),
Crypto.encrypt(
- creds.secretKey(), OBJECT_MAPPER.writeValueAsBytes(addServiceAccountReq)))) {
- return addServiceAccountReq;
+ creds.secretKey(),
+ OBJECT_MAPPER.writeValueAsBytes(
+ buildServiceAccount(
+ targetUser,
+ name,
+ secretKey,
+ accessKey,
+ null,
+ policy,
+ description,
+ false,
+ expiryTime))))) {
+ return new Credentials(accessKey, secretKey, null, ResponseDate.fromString(expiryTime));
}
}
@@ -729,7 +763,7 @@ public void updateServiceAccount(
@Nullable String newName,
@Nullable String newSecretKey,
@Nullable String accessKey,
- @Nullable UpdateServiceAccountReq.Status newStatus,
+ @Nullable String newStatus,
@Nullable String newPolicy,
@Nullable String newDescription,
@Nullable String newExpiration)
@@ -741,39 +775,32 @@ public void updateServiceAccount(
if (accessKey == null || accessKey.isEmpty()) {
throw new IllegalArgumentException("access key must be provided");
}
- byte[] policyBytes = null;
- if (newPolicy != null && !newPolicy.isEmpty()) {
- policyBytes = newPolicy.getBytes(StandardCharsets.UTF_8);
+ if (newStatus != null
+ && !newStatus.isEmpty()
+ && !"on".equals(newStatus)
+ && !"off".equals(newStatus)) {
+ throw new IllegalArgumentException("status key must be on or off");
}
Credentials creds = getCredentials();
- UpdateServiceAccountReq updateServiceAccountReq =
- new UpdateServiceAccountReq(
- newSecretKey, policyBytes, newStatus, newName, newDescription, newExpiration);
try (Response response =
execute(
Method.POST,
Command.UPDATE_SERVICE_ACCOUNT,
ImmutableMultimap.of("accessKey", accessKey),
Crypto.encrypt(
- creds.secretKey(), OBJECT_MAPPER.writeValueAsBytes(updateServiceAccountReq)))) {}
- }
-
- /**
- * Creates randomly generated credentials of maximum.
- *
- * @param length credentials length
- * @return credential
- */
- private String generateCredentials(int length) {
- String characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- StringBuffer randomString = new StringBuffer();
- Random random = new Random(new SecureRandom().nextLong());
- for (int i = 0; i < length; i++) {
- int randomIndex = random.nextInt(length);
- randomString.append(characters.charAt(randomIndex % characters.length()));
- }
- return randomString.toString();
+ creds.secretKey(),
+ OBJECT_MAPPER.writeValueAsBytes(
+ buildServiceAccount(
+ null,
+ newName,
+ newSecretKey,
+ accessKey,
+ newStatus,
+ newPolicy,
+ newDescription,
+ true,
+ newExpiration))))) {}
}
/**
@@ -808,7 +835,7 @@ public void deleteServiceAccount(@Nonnull String accessKey)
* @throws IOException thrown to indicate I/O error on MinIO REST operation.
* @throws InvalidCipherTextException thrown to indicate data cannot be encrypted/decrypted.
*/
- public List listServiceAccount(@Nonnull String userName)
+ public ListServiceAccountResp listServiceAccount(@Nonnull String userName)
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
InvalidCipherTextException {
if (userName == null || userName.isEmpty()) {
@@ -823,7 +850,7 @@ public List listServiceAccount(@Nonnull String userName)
null)) {
Credentials creds = getCredentials();
byte[] jsonData = Crypto.decrypt(creds.secretKey(), response.body().bytes());
- return OBJECT_MAPPER.readValue(jsonData, ListServiceAccountResp.class).accounts();
+ return OBJECT_MAPPER.readValue(jsonData, ListServiceAccountResp.class);
}
}
diff --git a/adminapi/src/main/java/io/minio/admin/UpdateServiceAccountReq.java b/adminapi/src/main/java/io/minio/admin/UpdateServiceAccountReq.java
deleted file mode 100644
index 89dc497f0..000000000
--- a/adminapi/src/main/java/io/minio/admin/UpdateServiceAccountReq.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * MinIO Java SDK for Amazon S3 Compatible Cloud Storage,
- * (C) 2021 MinIO, Inc.
- *
- * Licensed 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 io.minio.admin;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonValue;
-import javax.annotation.Nullable;
-
-/**
- * add service account request info.
- *
- * * @see user-commands.go
- */
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class UpdateServiceAccountReq {
- @JsonProperty("newSecretKey")
- private String newSecretKey;
-
- @JsonProperty("newStatus")
- private Status newStatus;
-
- @JsonProperty("newPolicy")
- private byte[] newPolicy;
-
- @JsonProperty("newName")
- private String newName;
-
- @JsonProperty("newDescription")
- private String newDescription;
-
- @JsonProperty("newExpiration")
- private String newExpiration;
-
- public UpdateServiceAccountReq() {}
-
- public UpdateServiceAccountReq(
- @Nullable @JsonProperty("newSecretKey") String newSecretKey,
- @Nullable @JsonProperty("newPolicy") byte[] newPolicy,
- @Nullable @JsonProperty("newStatus") Status newStatus,
- @Nullable @JsonProperty("newName") String newName,
- @Nullable @JsonProperty("newDescription") String newDescription,
- @Nullable @JsonProperty("newExpiration") String newExpiration) {
- this.newSecretKey = newSecretKey;
- this.newPolicy = newPolicy;
- this.newStatus = newStatus;
- this.newName = newName;
- this.newDescription = newDescription;
- this.newExpiration = newExpiration;
- }
-
- public String newSecretKey() {
- return newSecretKey;
- }
-
- public byte[] newPolicy() {
- return newPolicy;
- }
-
- public Status newStatus() {
- return newStatus;
- }
-
- public String newName() {
- return newName;
- }
-
- public String newDescription() {
- return newDescription;
- }
-
- public String newExpiration() {
- return newExpiration;
- }
-
- public static enum Status {
- ENABLED("on"),
- DISABLED("off");
-
- private final String value;
-
- private Status(String value) {
- this.value = value;
- }
-
- @JsonValue
- public String toString() {
- return this.value;
- }
-
- @JsonCreator
- public static UpdateServiceAccountReq.Status fromString(String statusString) {
- if ("on".equals(statusString)) {
- return ENABLED;
- }
-
- if ("off".equals(statusString)) {
- return DISABLED;
- }
-
- if (statusString.isEmpty()) {
- return null;
- }
-
- throw new IllegalArgumentException("Unknown status " + statusString);
- }
- }
-}