From 1e94cc69b0b7dfcbb7c8502cc0524b4ba433c051 Mon Sep 17 00:00:00 2001 From: Omico Date: Fri, 13 Oct 2023 03:16:06 -0700 Subject: [PATCH] Implement add service account --- .../java/io/minio/admin/MinioAdminClient.java | 30 +++++++++++++++- .../messages/AddServiceAccountRequest.java | 18 ++++++++++ .../messages/AddServiceAccountResponse.java | 14 ++++++++ .../messages/ServiceAccountCredentials.java | 34 +++++++++++++++++++ .../io/minio/admin/AddServiceAccountTest.java | 24 +++++++++++++ 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 adminapi/src/main/java/io/minio/admin/messages/AddServiceAccountRequest.java create mode 100644 adminapi/src/main/java/io/minio/admin/messages/AddServiceAccountResponse.java create mode 100644 adminapi/src/main/java/io/minio/admin/messages/ServiceAccountCredentials.java create mode 100644 adminapi/src/test/java/io/minio/admin/AddServiceAccountTest.java diff --git a/adminapi/src/main/java/io/minio/admin/MinioAdminClient.java b/adminapi/src/main/java/io/minio/admin/MinioAdminClient.java index ea4bc8adf..79e0cfba3 100644 --- a/adminapi/src/main/java/io/minio/admin/MinioAdminClient.java +++ b/adminapi/src/main/java/io/minio/admin/MinioAdminClient.java @@ -30,7 +30,10 @@ import io.minio.S3Escaper; import io.minio.Signer; import io.minio.Time; +import io.minio.admin.messages.AddServiceAccountRequest; +import io.minio.admin.messages.AddServiceAccountResponse; import io.minio.admin.messages.DataUsageInfo; +import io.minio.admin.messages.ServiceAccountCredentials; import io.minio.admin.messages.info.Message; import io.minio.credentials.Credentials; import io.minio.credentials.Provider; @@ -71,6 +74,7 @@ private enum Command { USER_INFO("user-info"), LIST_USERS("list-users"), REMOVE_USER("remove-user"), + ADD_SERVICE_ACCOUNT("add-service-account"), ADD_CANNED_POLICY("add-canned-policy"), SET_USER_OR_GROUP_POLICY("set-user-or-group-policy"), LIST_CANNED_POLICIES("list-canned-policies"), @@ -307,6 +311,30 @@ public void deleteUser(@Nonnull String accessKey) null)) {} } + /** + * Add a service account for a given user. + * + * @param targetUser Target user. + * @throws NoSuchAlgorithmException thrown to indicate missing of MD5 or SHA-256 digest library. + * @throws InvalidKeyException thrown to indicate missing of HMAC SHA-256 library. + * @throws IOException thrown to indicate I/O error on MinIO REST operation. + * @throws InvalidCipherTextException thrown to indicate data cannot be encrypted/decrypted. + */ + public ServiceAccountCredentials addServiceAccount(String targetUser) + throws NoSuchAlgorithmException, InvalidKeyException, IOException, + InvalidCipherTextException { + Credentials creds = getCredentials(); + AddServiceAccountRequest addServiceAccountRequest = new AddServiceAccountRequest(targetUser); + byte[] body = + Crypto.encrypt( + creds.secretKey(), OBJECT_MAPPER.writeValueAsBytes(addServiceAccountRequest)); + + try (Response response = execute(Method.PUT, Command.ADD_SERVICE_ACCOUNT, null, body)) { + byte[] jsonData = Crypto.decrypt(creds.secretKey(), response.body().bytes()); + return OBJECT_MAPPER.readValue(jsonData, AddServiceAccountResponse.class).credentials(); + } + } + /** * Adds or updates a group. * @@ -674,8 +702,8 @@ public void traceOn(OutputStream traceStream) { /** * Disables HTTP call tracing previously enabled. * - * @see #traceOn * @throws IOException upon connection error + * @see #traceOn */ public void traceOff() throws IOException { this.traceStream = null; diff --git a/adminapi/src/main/java/io/minio/admin/messages/AddServiceAccountRequest.java b/adminapi/src/main/java/io/minio/admin/messages/AddServiceAccountRequest.java new file mode 100644 index 000000000..25bd4526b --- /dev/null +++ b/adminapi/src/main/java/io/minio/admin/messages/AddServiceAccountRequest.java @@ -0,0 +1,18 @@ +package io.minio.admin.messages; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class AddServiceAccountRequest { + @JsonProperty("targetUser") + private final String targetUser; + + public AddServiceAccountRequest(String targetUser) { + this.targetUser = targetUser; + } + + public String targetUser() { + return targetUser; + } +} diff --git a/adminapi/src/main/java/io/minio/admin/messages/AddServiceAccountResponse.java b/adminapi/src/main/java/io/minio/admin/messages/AddServiceAccountResponse.java new file mode 100644 index 000000000..2abca2041 --- /dev/null +++ b/adminapi/src/main/java/io/minio/admin/messages/AddServiceAccountResponse.java @@ -0,0 +1,14 @@ +package io.minio.admin.messages; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class AddServiceAccountResponse { + @JsonProperty("credentials") + private ServiceAccountCredentials credentials; + + public ServiceAccountCredentials credentials() { + return credentials; + } +} diff --git a/adminapi/src/main/java/io/minio/admin/messages/ServiceAccountCredentials.java b/adminapi/src/main/java/io/minio/admin/messages/ServiceAccountCredentials.java new file mode 100644 index 000000000..1b43f719b --- /dev/null +++ b/adminapi/src/main/java/io/minio/admin/messages/ServiceAccountCredentials.java @@ -0,0 +1,34 @@ +package io.minio.admin.messages; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.minio.messages.ResponseDate; + +public class ServiceAccountCredentials { + @JsonProperty("accessKey") + private String accessKey; + + @JsonProperty("secretKey") + private String secretKey; + + @JsonProperty("sessionToken") + private String sessionToken; + + @JsonProperty("expiration") + private ResponseDate expiration; + + public String accessKey() { + return accessKey; + } + + public String secretKey() { + return secretKey; + } + + public String sessionToken() { + return sessionToken; + } + + public ResponseDate expiration() { + return expiration; + } +} diff --git a/adminapi/src/test/java/io/minio/admin/AddServiceAccountTest.java b/adminapi/src/test/java/io/minio/admin/AddServiceAccountTest.java new file mode 100644 index 000000000..5f2718024 --- /dev/null +++ b/adminapi/src/test/java/io/minio/admin/AddServiceAccountTest.java @@ -0,0 +1,24 @@ +package io.minio.admin; + +import io.minio.admin.messages.ServiceAccountCredentials; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import org.bouncycastle.crypto.InvalidCipherTextException; +import org.junit.Test; + +public class AddServiceAccountTest { + @Test + public void canObtainServiceAccount() + throws InvalidCipherTextException, NoSuchAlgorithmException, IOException, + InvalidKeyException { + MinioAdminClient adminClient = + MinioAdminClient.builder() + .endpoint("https://play.min.io") + .credentials("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG") + .build(); + ServiceAccountCredentials credentials = adminClient.addServiceAccount("Q3AM3UQ867SPQQA43P2F"); + System.out.println(credentials.accessKey()); + System.out.println(credentials.secretKey()); + } +}