diff --git a/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/AwsCredentialsIdentity.java b/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/AwsCredentialsIdentity.java index c300967035dc..07e1f26bbdeb 100644 --- a/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/AwsCredentialsIdentity.java +++ b/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/AwsCredentialsIdentity.java @@ -15,11 +15,9 @@ package software.amazon.awssdk.identity.spi; -import java.util.Objects; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.annotations.ThreadSafe; -import software.amazon.awssdk.utils.ToString; -import software.amazon.awssdk.utils.Validate; +import software.amazon.awssdk.identity.spi.internal.DefaultAwsCredentialsIdentity; /** * Provides access to the AWS credentials used for accessing services: AWS access key ID and secret access key. These @@ -45,6 +43,10 @@ public interface AwsCredentialsIdentity extends Identity { */ String secretAccessKey(); + static Builder builder() { + return DefaultAwsCredentialsIdentity.builder(); + } + /** * Constructs a new credentials object, with the specified AWS access key and AWS secret key. * @@ -52,47 +54,22 @@ public interface AwsCredentialsIdentity extends Identity { * @param secretAccessKey The AWS secret access key, used to authenticate the user interacting with services. */ static AwsCredentialsIdentity create(String accessKeyId, String secretAccessKey) { - Validate.paramNotNull(accessKeyId, "accessKeyId"); - Validate.paramNotNull(secretAccessKey, "secretAccessKey"); - - return new AwsCredentialsIdentity() { - @Override - public String accessKeyId() { - return accessKeyId; - } - - @Override - public String secretAccessKey() { - return secretAccessKey; - } + return builder().accessKeyId(accessKeyId) + .secretAccessKey(secretAccessKey) + .build(); + } - @Override - public String toString() { - return ToString.builder("AwsCredentialsIdentity") - .add("accessKeyId", accessKeyId) - .build(); - } + interface Builder { + /** + * The AWS access key, used to identify the user interacting with services. + */ + Builder accessKeyId(String accessKeyId); - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AwsCredentialsIdentity that = (AwsCredentialsIdentity) o; - return Objects.equals(accessKeyId, that.accessKeyId()) && - Objects.equals(secretAccessKey, that.secretAccessKey()); - } + /** + * The AWS secret access key, used to authenticate the user interacting with services. + */ + Builder secretAccessKey(String secretAccessKey); - @Override - public int hashCode() { - int hashCode = 1; - hashCode = 31 * hashCode + Objects.hashCode(accessKeyId()); - hashCode = 31 * hashCode + Objects.hashCode(secretAccessKey()); - return hashCode; - } - }; + AwsCredentialsIdentity build(); } } diff --git a/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/AwsSessionCredentialsIdentity.java b/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/AwsSessionCredentialsIdentity.java index 0a536d94f873..10e0ec0634ce 100644 --- a/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/AwsSessionCredentialsIdentity.java +++ b/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/AwsSessionCredentialsIdentity.java @@ -15,11 +15,9 @@ package software.amazon.awssdk.identity.spi; -import java.util.Objects; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.annotations.ThreadSafe; -import software.amazon.awssdk.utils.ToString; -import software.amazon.awssdk.utils.Validate; +import software.amazon.awssdk.identity.spi.internal.DefaultAwsSessionCredentialsIdentity; /** * A special type of {@link AwsCredentialsIdentity} that provides a session token to be used in service authentication. Session @@ -36,6 +34,10 @@ public interface AwsSessionCredentialsIdentity extends AwsCredentialsIdentity { */ String sessionToken(); + static AwsSessionCredentialsIdentity.Builder builder() { + return DefaultAwsSessionCredentialsIdentity.builder(); + } + /** * Constructs a new session credentials object, with the specified AWS access key, AWS secret key and AWS session token. * @@ -45,56 +47,26 @@ public interface AwsSessionCredentialsIdentity extends AwsCredentialsIdentity { * received temporary permission to access some resource. */ static AwsSessionCredentialsIdentity create(String accessKeyId, String secretAccessKey, String sessionToken) { - Validate.paramNotNull(accessKeyId, "accessKeyId"); - Validate.paramNotNull(secretAccessKey, "secretAccessKey"); - Validate.paramNotNull(sessionToken, "sessionToken"); - - return new AwsSessionCredentialsIdentity() { - @Override - public String accessKeyId() { - return accessKeyId; - } - - @Override - public String secretAccessKey() { - return secretAccessKey; - } - - @Override - public String sessionToken() { - return sessionToken; - } + return builder().accessKeyId(accessKeyId) + .secretAccessKey(secretAccessKey) + .sessionToken(sessionToken) + .build(); + } - @Override - public String toString() { - return ToString.builder("AwsSessionCredentialsIdentity") - .add("accessKeyId", accessKeyId()) - .build(); - } + interface Builder extends AwsCredentialsIdentity.Builder { + @Override + Builder accessKeyId(String accessKeyId); - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } + @Override + Builder secretAccessKey(String secretAccessKey); - AwsSessionCredentialsIdentity that = (AwsSessionCredentialsIdentity) o; - return Objects.equals(accessKeyId, that.accessKeyId()) && - Objects.equals(secretAccessKey, that.secretAccessKey()) && - Objects.equals(sessionToken, that.sessionToken()); - } + /** + * The AWS session token, retrieved from an AWS token service, used for authenticating that this user has + * received temporary permission to access some resource. + */ + Builder sessionToken(String sessionToken); - @Override - public int hashCode() { - int hashCode = 1; - hashCode = 31 * hashCode + Objects.hashCode(accessKeyId()); - hashCode = 31 * hashCode + Objects.hashCode(secretAccessKey()); - hashCode = 31 * hashCode + Objects.hashCode(sessionToken()); - return hashCode; - } - }; + @Override + AwsSessionCredentialsIdentity build(); } } diff --git a/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/internal/DefaultAwsCredentialsIdentity.java b/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/internal/DefaultAwsCredentialsIdentity.java new file mode 100644 index 000000000000..7cca889709b1 --- /dev/null +++ b/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/internal/DefaultAwsCredentialsIdentity.java @@ -0,0 +1,104 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.identity.spi.internal; + +import java.util.Objects; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.Validate; + +@SdkInternalApi +public final class DefaultAwsCredentialsIdentity implements AwsCredentialsIdentity { + + private final String accessKeyId; + private final String secretAccessKey; + + private DefaultAwsCredentialsIdentity(Builder builder) { + this.accessKeyId = builder.accessKeyId; + this.secretAccessKey = builder.secretAccessKey; + + Validate.paramNotNull(accessKeyId, "accessKeyId"); + Validate.paramNotNull(secretAccessKey, "secretAccessKey"); + } + + public static AwsCredentialsIdentity.Builder builder() { + return new Builder(); + } + + @Override + public String accessKeyId() { + return accessKeyId; + } + + @Override + public String secretAccessKey() { + return secretAccessKey; + } + + @Override + public String toString() { + return ToString.builder("AwsCredentialsIdentity") + .add("accessKeyId", accessKeyId) + .build(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AwsCredentialsIdentity that = (AwsCredentialsIdentity) o; + return Objects.equals(accessKeyId, that.accessKeyId()) && + Objects.equals(secretAccessKey, that.secretAccessKey()); + } + + @Override + public int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + Objects.hashCode(accessKeyId); + hashCode = 31 * hashCode + Objects.hashCode(secretAccessKey); + return hashCode; + } + + private static final class Builder implements AwsCredentialsIdentity.Builder { + private String accessKeyId; + private String secretAccessKey; + + private Builder() { + } + + @Override + public Builder accessKeyId(String accessKeyId) { + this.accessKeyId = accessKeyId; + return this; + } + + @Override + public Builder secretAccessKey(String secretAccessKey) { + this.secretAccessKey = secretAccessKey; + return this; + } + + @Override + public AwsCredentialsIdentity build() { + return new DefaultAwsCredentialsIdentity(this); + } + } +} diff --git a/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/internal/DefaultAwsSessionCredentialsIdentity.java b/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/internal/DefaultAwsSessionCredentialsIdentity.java new file mode 100644 index 000000000000..067d490b3838 --- /dev/null +++ b/core/identity-spi/src/main/java/software/amazon/awssdk/identity/spi/internal/DefaultAwsSessionCredentialsIdentity.java @@ -0,0 +1,121 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.identity.spi.internal; + +import java.util.Objects; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity; +import software.amazon.awssdk.utils.ToString; +import software.amazon.awssdk.utils.Validate; + +@SdkInternalApi +public final class DefaultAwsSessionCredentialsIdentity implements AwsSessionCredentialsIdentity { + + private final String accessKeyId; + private final String secretAccessKey; + private final String sessionToken; + + private DefaultAwsSessionCredentialsIdentity(Builder builder) { + this.accessKeyId = builder.accessKeyId; + this.secretAccessKey = builder.secretAccessKey; + this.sessionToken = builder.sessionToken; + + Validate.paramNotNull(accessKeyId, "accessKeyId"); + Validate.paramNotNull(secretAccessKey, "secretAccessKey"); + Validate.paramNotNull(sessionToken, "sessionToken"); + } + + public static AwsSessionCredentialsIdentity.Builder builder() { + return new Builder(); + } + + @Override + public String accessKeyId() { + return accessKeyId; + } + + @Override + public String secretAccessKey() { + return secretAccessKey; + } + + @Override + public String sessionToken() { + return sessionToken; + } + + @Override + public String toString() { + return ToString.builder("AwsSessionCredentialsIdentity") + .add("accessKeyId", accessKeyId) + .build(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AwsSessionCredentialsIdentity that = (AwsSessionCredentialsIdentity) o; + return Objects.equals(accessKeyId, that.accessKeyId()) && + Objects.equals(secretAccessKey, that.secretAccessKey()) && + Objects.equals(sessionToken, that.sessionToken()); + } + + @Override + public int hashCode() { + int hashCode = 1; + hashCode = 31 * hashCode + Objects.hashCode(accessKeyId); + hashCode = 31 * hashCode + Objects.hashCode(secretAccessKey); + hashCode = 31 * hashCode + Objects.hashCode(sessionToken); + return hashCode; + } + + private static final class Builder implements AwsSessionCredentialsIdentity.Builder { + private String accessKeyId; + private String secretAccessKey; + private String sessionToken; + + private Builder() { + } + + @Override + public Builder accessKeyId(String accessKeyId) { + this.accessKeyId = accessKeyId; + return this; + } + + @Override + public Builder secretAccessKey(String secretAccessKey) { + this.secretAccessKey = secretAccessKey; + return this; + } + + @Override + public Builder sessionToken(String sessionToken) { + this.sessionToken = sessionToken; + return this; + } + + @Override + public AwsSessionCredentialsIdentity build() { + return new DefaultAwsSessionCredentialsIdentity(this); + } + } +} diff --git a/core/identity-spi/src/test/java/software/amazon/awssdk/identity/spi/AwsCredentialsIdentityTest.java b/core/identity-spi/src/test/java/software/amazon/awssdk/identity/spi/AwsCredentialsIdentityTest.java new file mode 100644 index 000000000000..33974427ab65 --- /dev/null +++ b/core/identity-spi/src/test/java/software/amazon/awssdk/identity/spi/AwsCredentialsIdentityTest.java @@ -0,0 +1,67 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.identity.spi; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity; +import software.amazon.awssdk.identity.spi.internal.DefaultAwsCredentialsIdentity; + +public class AwsCredentialsIdentityTest { + private static final String ACCESS_KEY_ID = "accessKeyId"; + private static final String SECRET_ACCESS_KEY = "secretAccessKey"; + + @Test + public void equalsHashcode() { + EqualsVerifier.forClass(DefaultAwsCredentialsIdentity.class) + .verify(); + } + + @Test + public void emptyBuilder_ThrowsException() { + assertThrows(NullPointerException.class, () -> AwsCredentialsIdentity.builder().build()); + } + + @Test + public void builderMissingSecretAccessKey_ThrowsException() { + assertThrows(NullPointerException.class, () -> AwsCredentialsIdentity.builder().accessKeyId(ACCESS_KEY_ID).build()); + } + + @Test + public void builderMissingAccessKeyId_ThrowsException() { + assertThrows(NullPointerException.class, () -> AwsCredentialsIdentity.builder().secretAccessKey(SECRET_ACCESS_KEY).build()); + } + + @Test + public void create_isSuccessful() { + AwsCredentialsIdentity identity = AwsCredentialsIdentity.create(ACCESS_KEY_ID, SECRET_ACCESS_KEY); + assertEquals(ACCESS_KEY_ID, identity.accessKeyId()); + assertEquals(SECRET_ACCESS_KEY, identity.secretAccessKey()); + } + + @Test + public void build_isSuccessful() { + AwsCredentialsIdentity identity = AwsCredentialsIdentity.builder() + .accessKeyId(ACCESS_KEY_ID) + .secretAccessKey(SECRET_ACCESS_KEY) + .build(); + assertEquals(ACCESS_KEY_ID, identity.accessKeyId()); + assertEquals(SECRET_ACCESS_KEY, identity.secretAccessKey()); + } +} diff --git a/core/identity-spi/src/test/java/software/amazon/awssdk/identity/spi/AwsSessionCredentialsIdentityTest.java b/core/identity-spi/src/test/java/software/amazon/awssdk/identity/spi/AwsSessionCredentialsIdentityTest.java new file mode 100644 index 000000000000..3702694e4fdd --- /dev/null +++ b/core/identity-spi/src/test/java/software/amazon/awssdk/identity/spi/AwsSessionCredentialsIdentityTest.java @@ -0,0 +1,79 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.identity.spi; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.identity.spi.AwsSessionCredentialsIdentity; +import software.amazon.awssdk.identity.spi.internal.DefaultAwsSessionCredentialsIdentity; + +public class AwsSessionCredentialsIdentityTest { + private static final String ACCESS_KEY_ID = "accessKeyId"; + private static final String SECRET_ACCESS_KEY = "secretAccessKey"; + private static final String SESSION_TOKEN = "sessionToken"; + + @Test + public void equalsHashcode() { + EqualsVerifier.forClass(DefaultAwsSessionCredentialsIdentity.class) + .verify(); + } + + @Test + public void emptyBuilder_ThrowsException() { + assertThrows(NullPointerException.class, () -> AwsSessionCredentialsIdentity.builder().build()); + } + + @Test + public void builderMissingSessionToken_ThrowsException() { + assertThrows(NullPointerException.class, () -> AwsSessionCredentialsIdentity.builder() + .accessKeyId(ACCESS_KEY_ID) + .secretAccessKey(SECRET_ACCESS_KEY) + .build()); + } + + @Test + public void builderMissingAccessKeyId_ThrowsException() { + assertThrows(NullPointerException.class, () -> AwsSessionCredentialsIdentity.builder() + .secretAccessKey(SECRET_ACCESS_KEY) + .sessionToken(SESSION_TOKEN) + .build()); + } + + @Test + public void create_isSuccessful() { + AwsSessionCredentialsIdentity identity = AwsSessionCredentialsIdentity.create(ACCESS_KEY_ID, + SECRET_ACCESS_KEY, + SESSION_TOKEN); + assertEquals(ACCESS_KEY_ID, identity.accessKeyId()); + assertEquals(SECRET_ACCESS_KEY, identity.secretAccessKey()); + assertEquals(SESSION_TOKEN, identity.sessionToken()); + } + + @Test + public void build_isSuccessful() { + AwsSessionCredentialsIdentity identity = AwsSessionCredentialsIdentity.builder() + .accessKeyId(ACCESS_KEY_ID) + .secretAccessKey(SECRET_ACCESS_KEY) + .sessionToken(SESSION_TOKEN) + .build(); + assertEquals(ACCESS_KEY_ID, identity.accessKeyId()); + assertEquals(SECRET_ACCESS_KEY, identity.secretAccessKey()); + assertEquals(SESSION_TOKEN, identity.sessionToken()); + } +}