This is an automated email from the ASF dual-hosted git repository.
sodonnell pushed a commit to branch HDDS-13323-sts
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/HDDS-13323-sts by this push:
new a8c868870a2 HDDS-13909. [STS] Introduce STSTokenIdentifier class
(#9277)
a8c868870a2 is described below
commit a8c868870a249c987cd5cb167d031f78a7547864
Author: fmorg-git <[email protected]>
AuthorDate: Mon Nov 17 09:24:31 2025 -0800
HDDS-13909. [STS] Introduce STSTokenIdentifier class (#9277)
---
.../apache/hadoop/ozone/client/ObjectStore.java | 8 +-
.../ozone/client/protocol/ClientProtocol.java | 8 +-
.../apache/hadoop/ozone/client/rpc/RpcClient.java | 8 +-
.../ozone/om/helpers/AssumeRoleResponseInfo.java | 49 +--
.../ozone/om/protocol/OzoneManagerProtocol.java | 12 +-
...OzoneManagerProtocolClientSideTranslatorPB.java | 11 +-
.../om/helpers/TestAssumeRoleResponseInfo.java | 129 ++-----
.../hadoop/ozone/security/STSTokenIdentifier.java | 225 ++++++++++++
.../ozone/security/TestSTSTokenIdentifier.java | 392 +++++++++++++++++++++
9 files changed, 661 insertions(+), 181 deletions(-)
diff --git
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
index 18e28f387c6..e783bafe227 100644
---
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
+++
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
@@ -761,12 +761,8 @@ public Iterator<OzoneSnapshotDiff> listSnapshotDiffJobs(
* @return AssumeRoleResponseInfo The AssumeRole response information
containing temporary credentials
* @throws IOException if an error occurs during the AssumeRole
operation
*/
- public AssumeRoleResponseInfo assumeRole(
- String roleArn,
- String roleSessionName,
- int durationSeconds,
- String awsIamSessionPolicy
- ) throws IOException {
+ public AssumeRoleResponseInfo assumeRole(String roleArn, String
roleSessionName, int durationSeconds,
+ String awsIamSessionPolicy) throws IOException {
return proxy.assumeRole(roleArn, roleSessionName, durationSeconds,
awsIamSessionPolicy);
}
diff --git
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
index 7560f2efc61..d4cc1d1fb51 100644
---
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
+++
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
@@ -1370,10 +1370,6 @@ void deleteObjectTagging(String volumeName, String
bucketName, String keyName)
* @return AssumeRoleResponseInfo The AssumeRole response information
containing temporary credentials
* @throws IOException if an error occurs during the AssumeRole
operation
*/
- AssumeRoleResponseInfo assumeRole(
- String roleArn,
- String roleSessionName,
- int durationSeconds,
- String awsIamSessionPolicy
- ) throws IOException;
+ AssumeRoleResponseInfo assumeRole(String roleArn, String roleSessionName,
int durationSeconds,
+ String awsIamSessionPolicy) throws IOException;
}
diff --git
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
index 115aa0bd20c..5c3b8eb4793 100644
---
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
+++
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
@@ -2792,12 +2792,8 @@ public void deleteObjectTagging(String volumeName,
String bucketName,
}
@Override
- public AssumeRoleResponseInfo assumeRole(
- String roleArn,
- String roleSessionName,
- int durationSeconds,
- String awsIamSessionPolicy
- ) throws IOException {
+ public AssumeRoleResponseInfo assumeRole(String roleArn, String
roleSessionName, int durationSeconds,
+ String awsIamSessionPolicy) throws IOException {
return ozoneManagerClient.assumeRole(roleArn, roleSessionName,
durationSeconds, awsIamSessionPolicy);
}
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/AssumeRoleResponseInfo.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/AssumeRoleResponseInfo.java
index 08bf14ef4a2..5f21abb3cbd 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/AssumeRoleResponseInfo.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/AssumeRoleResponseInfo.java
@@ -53,13 +53,8 @@ public String getAssumedRoleId() {
return assumedRoleId;
}
- public AssumeRoleResponseInfo(
- String accessKeyId,
- String secretAccessKey,
- String sessionToken,
- long expirationEpochSeconds,
- String assumedRoleId
- ) {
+ public AssumeRoleResponseInfo(String accessKeyId, String secretAccessKey,
String sessionToken,
+ long expirationEpochSeconds, String assumedRoleId) {
this.accessKeyId = accessKeyId;
this.secretAccessKey = secretAccessKey;
this.sessionToken = sessionToken;
@@ -67,16 +62,10 @@ public AssumeRoleResponseInfo(
this.assumedRoleId = assumedRoleId;
}
- public static AssumeRoleResponseInfo fromProtobuf(
- AssumeRoleResponse response
- ) {
+ public static AssumeRoleResponseInfo fromProtobuf(AssumeRoleResponse
response) {
return new AssumeRoleResponseInfo(
- response.getAccessKeyId(),
- response.getSecretAccessKey(),
- response.getSessionToken(),
- response.getExpirationEpochSeconds(),
- response.getAssumedRoleId()
- );
+ response.getAccessKeyId(), response.getSecretAccessKey(),
response.getSessionToken(),
+ response.getExpirationEpochSeconds(), response.getAssumedRoleId());
}
public AssumeRoleResponse getProtobuf() {
@@ -91,19 +80,13 @@ public AssumeRoleResponse getProtobuf() {
@Override
public String toString() {
- return "AssumeRoleResponseInfo{" +
- "accessKeyId='" + accessKeyId + '\'' +
- ", secretAccessKey='" + secretAccessKey + '\'' +
- ", sessionToken='" + sessionToken + '\'' +
- ", expirationEpochSeconds=" + expirationEpochSeconds +
- ", assumedRoleId='" + assumedRoleId + '\'' +
- '}';
+ return "AssumeRoleResponseInfo{" + "accessKeyId='" + accessKeyId + "',
secretAccessKey='" + secretAccessKey +
+ "', sessionToken='" + sessionToken + "', expirationEpochSeconds=" +
expirationEpochSeconds +
+ ", assumedRoleId='" + assumedRoleId + "'}";
}
@Override
- public boolean equals(
- Object o
- ) {
+ public boolean equals(Object o) {
if (this == o) {
return true;
}
@@ -113,21 +96,13 @@ public boolean equals(
}
final AssumeRoleResponseInfo that = (AssumeRoleResponseInfo) o;
- return expirationEpochSeconds == that.expirationEpochSeconds &&
- Objects.equals(accessKeyId, that.accessKeyId) &&
- Objects.equals(secretAccessKey, that.secretAccessKey) &&
- Objects.equals(sessionToken, that.sessionToken) &&
+ return expirationEpochSeconds == that.expirationEpochSeconds &&
Objects.equals(accessKeyId, that.accessKeyId) &&
+ Objects.equals(secretAccessKey, that.secretAccessKey) &&
Objects.equals(sessionToken, that.sessionToken) &&
Objects.equals(assumedRoleId, that.assumedRoleId);
}
@Override
public int hashCode() {
- return Objects.hash(
- accessKeyId,
- secretAccessKey,
- sessionToken,
- expirationEpochSeconds,
- assumedRoleId
- );
+ return Objects.hash(accessKeyId, secretAccessKey, sessionToken,
expirationEpochSeconds, assumedRoleId);
}
}
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
index b41510bb2bf..4261f71c4e5 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
@@ -1187,14 +1187,8 @@ default void deleteObjectTagging(OmKeyArgs args) throws
IOException {
* @return AssumeRoleResponseInfo The AssumeRole response information
containing temporary credentials
* @throws IOException if an error occurs during the AssumeRole
operation
*/
- default AssumeRoleResponseInfo assumeRole(
- String roleArn,
- String roleSessionName,
- int durationSeconds,
- String awsIamSessionPolicy
- ) throws IOException {
- throw new UnsupportedOperationException(
- "OzoneManager does not require this to be implemented"
- );
+ default AssumeRoleResponseInfo assumeRole(String roleArn, String
roleSessionName, int durationSeconds,
+ String awsIamSessionPolicy) throws IOException {
+ throw new UnsupportedOperationException("OzoneManager does not require
this to be implemented");
}
}
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
index 222f4bc1f48..c3c173a8cae 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
@@ -2652,12 +2652,8 @@ public void deleteObjectTagging(OmKeyArgs args) throws
IOException {
}
@Override
- public AssumeRoleResponseInfo assumeRole(
- String roleArn,
- String roleSessionName,
- int durationSeconds,
- String awsIamSessionPolicy
- ) throws IOException {
+ public AssumeRoleResponseInfo assumeRole(String roleArn, String
roleSessionName, int durationSeconds,
+ String awsIamSessionPolicy) throws IOException {
final OzoneManagerProtocolProtos.AssumeRoleRequest.Builder request =
OzoneManagerProtocolProtos.AssumeRoleRequest.newBuilder()
.setRoleArn(roleArn)
@@ -2670,8 +2666,7 @@ public AssumeRoleResponseInfo assumeRole(
.build();
return AssumeRoleResponseInfo.fromProtobuf(
- handleError(submitRequest(omRequest)).getAssumeRoleResponse()
- );
+ handleError(submitRequest(omRequest)).getAssumeRoleResponse());
}
private SafeMode toProtoBuf(SafeModeAction action) {
diff --git
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestAssumeRoleResponseInfo.java
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestAssumeRoleResponseInfo.java
index db5a409864d..38c74dc1f26 100644
---
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestAssumeRoleResponseInfo.java
+++
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/om/helpers/TestAssumeRoleResponseInfo.java
@@ -46,12 +46,7 @@ public class TestAssumeRoleResponseInfo {
@Test
public void testConstructor() {
final AssumeRoleResponseInfo response = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
assertEquals(ACCESS_KEY_ID, response.getAccessKeyId());
assertEquals(SECRET_ACCESS_KEY, response.getSecretAccessKey());
@@ -63,12 +58,7 @@ public void testConstructor() {
@Test
public void testProtobufConversion() {
final AssumeRoleResponseInfo response = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
final AssumeRoleResponse proto = response.getProtobuf();
@@ -102,12 +92,7 @@ public void testFromProtobuf() {
@Test
public void testProtobufRoundTrip() {
final AssumeRoleResponseInfo originalResponse = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
final AssumeRoleResponse proto = originalResponse.getProtobuf();
final AssumeRoleResponseInfo recoveredResponse =
AssumeRoleResponseInfo.fromProtobuf(proto);
@@ -118,20 +103,10 @@ public void testProtobufRoundTrip() {
@Test
public void testEqualsAndHashCodeWithIdenticalObjects() {
final AssumeRoleResponseInfo response1 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
final AssumeRoleResponseInfo response2 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
assertEquals(response1, response2);
assertEquals(response1.hashCode(), response2.hashCode());
@@ -140,20 +115,10 @@ public void testEqualsAndHashCodeWithIdenticalObjects() {
@Test
public void testNotEqualsAndHashCodeWithDifferentAccessKeyId() {
final AssumeRoleResponseInfo response1 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
final AssumeRoleResponseInfo response2 = new AssumeRoleResponseInfo(
- "DIFFERENT_KEY_ID",
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ "DIFFERENT_KEY_ID", SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
assertNotEquals(response1, response2);
assertNotEquals(response1.hashCode(), response2.hashCode());
@@ -162,20 +127,10 @@ public void
testNotEqualsAndHashCodeWithDifferentAccessKeyId() {
@Test
public void testNotEqualsAndHashCodeWithDifferentSecretAccessKey() {
final AssumeRoleResponseInfo response1 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
final AssumeRoleResponseInfo response2 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- "DIFFERENT_SECRET_KEY",
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, "DIFFERENT_SECRET_KEY", SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
assertNotEquals(response1, response2);
assertNotEquals(response1.hashCode(), response2.hashCode());
@@ -184,20 +139,10 @@ public void
testNotEqualsAndHashCodeWithDifferentSecretAccessKey() {
@Test
public void testNotEqualsAndHashCodeWithDifferentSessionToken() {
final AssumeRoleResponseInfo response1 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
final AssumeRoleResponseInfo response2 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- "DIFFERENT_TOKEN",
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, "DIFFERENT_TOKEN",
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
assertNotEquals(response1, response2);
assertNotEquals(response1.hashCode(), response2.hashCode());
@@ -206,20 +151,10 @@ public void
testNotEqualsAndHashCodeWithDifferentSessionToken() {
@Test
public void testNotEqualsAndHashCodeWithDifferentExpirationEpochSeconds() {
final AssumeRoleResponseInfo response1 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
final AssumeRoleResponseInfo response2 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- 9999999999L,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN, 9999999999L,
ASSUMED_ROLE_ID);
assertNotEquals(response1, response2);
assertNotEquals(response1.hashCode(), response2.hashCode());
@@ -228,20 +163,10 @@ public void
testNotEqualsAndHashCodeWithDifferentExpirationEpochSeconds() {
@Test
public void testNotEqualsAndHashCodeWithDifferentAssumedRoleId() {
final AssumeRoleResponseInfo response1 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
final AssumeRoleResponseInfo response2 = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- "DIFFERENT_ROLE_ID"
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, "DIFFERENT_ROLE_ID");
assertNotEquals(response1, response2);
assertNotEquals(response1.hashCode(), response2.hashCode());
@@ -250,12 +175,7 @@ public void
testNotEqualsAndHashCodeWithDifferentAssumedRoleId() {
@Test
public void testNotEqualsWithNull() {
final AssumeRoleResponseInfo response = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
assertNotEquals(null, response);
}
@@ -263,21 +183,12 @@ public void testNotEqualsWithNull() {
@Test
public void testToString() {
final AssumeRoleResponseInfo response = new AssumeRoleResponseInfo(
- ACCESS_KEY_ID,
- SECRET_ACCESS_KEY,
- SESSION_TOKEN,
- EXPIRATION_EPOCH_SECONDS,
- ASSUMED_ROLE_ID
- );
+ ACCESS_KEY_ID, SECRET_ACCESS_KEY, SESSION_TOKEN,
EXPIRATION_EPOCH_SECONDS, ASSUMED_ROLE_ID);
final String toString = response.toString();
- final String expectedString = "AssumeRoleResponseInfo{" +
- "accessKeyId='" + ACCESS_KEY_ID + '\'' +
- ", secretAccessKey='" + SECRET_ACCESS_KEY + '\'' +
- ", sessionToken='" + SESSION_TOKEN + '\'' +
- ", expirationEpochSeconds=" + EXPIRATION_EPOCH_SECONDS +
- ", assumedRoleId='" + ASSUMED_ROLE_ID + '\'' +
- '}';
+ final String expectedString = "AssumeRoleResponseInfo{" + "accessKeyId='"
+ ACCESS_KEY_ID +
+ "', secretAccessKey='" + SECRET_ACCESS_KEY + "', sessionToken='" +
SESSION_TOKEN +
+ "', expirationEpochSeconds=" + EXPIRATION_EPOCH_SECONDS + ",
assumedRoleId='" + ASSUMED_ROLE_ID + "'}";
assertNotNull(toString);
assertEquals(expectedString, toString);
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/STSTokenIdentifier.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/STSTokenIdentifier.java
new file mode 100644
index 00000000000..071d7d21a9a
--- /dev/null
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/security/STSTokenIdentifier.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.apache.hadoop.ozone.security;
+
+import com.google.common.base.Preconditions;
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.time.Instant;
+import java.util.Objects;
+import java.util.UUID;
+import org.apache.hadoop.hdds.annotation.InterfaceAudience;
+import org.apache.hadoop.hdds.annotation.InterfaceStability;
+import org.apache.hadoop.hdds.security.token.ShortLivedTokenIdentifier;
+import org.apache.hadoop.io.Text;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMTokenProto;
+
+/**
+ * Token identifier for STS (Security Token Service) tokens.
+ */
[email protected]
[email protected]
+public class STSTokenIdentifier extends ShortLivedTokenIdentifier {
+ public static final Text KIND_NAME = new Text("STSToken");
+
+ // STS-specific fields
+ private String roleArn;
+ private String originalAccessKeyId;
+ private String secretAccessKey;
+ private String sessionPolicy;
+
+ // Service name for STS tokens
+ public static final String STS_SERVICE = "STS";
+
+ /**
+ * Create an empty STS token identifier.
+ */
+ public STSTokenIdentifier() {
+ super();
+ }
+
+ /**
+ * Create a new STS token identifier with encryption support.
+ *
+ * @param tempAccessKeyId the temporary access key ID (owner)
+ * @param originalAccessKeyId the original long-lived access key ID that
created this token
+ * @param roleArn the ARN of the assumed role
+ * @param expiry the token expiration time
+ * @param secretAccessKey the secret access key associated with the
temporary access key ID
+ * @param sessionPolicy an optional opaque identifier that further
limits the scope of
+ * the permissions granted by the role
+ */
+ public STSTokenIdentifier(String tempAccessKeyId, String
originalAccessKeyId, String roleArn, Instant expiry,
+ String secretAccessKey, String sessionPolicy) {
+ super(tempAccessKeyId, expiry);
+ this.originalAccessKeyId = originalAccessKeyId;
+ this.roleArn = roleArn;
+ this.secretAccessKey = secretAccessKey;
+ this.sessionPolicy = sessionPolicy;
+ }
+
+ @Override
+ public Text getKind() {
+ return KIND_NAME;
+ }
+
+ @Override
+ public String getService() {
+ return STS_SERVICE;
+ }
+
+ @Override
+ public void readFromByteArray(byte[] bytes) throws IOException {
+ final DataInputStream in = new DataInputStream(new
ByteArrayInputStream(bytes));
+ readFields(in);
+ }
+
+ @Override
+ public void write(DataOutput out) throws IOException {
+ out.write(toProtoBuf().toByteArray());
+ }
+
+ @Override
+ public void readFields(DataInput in) throws IOException {
+ final OMTokenProto token = OMTokenProto.parseFrom((DataInputStream) in);
+ fromProtoBuf(token);
+ }
+
+ /**
+ * Convert this identifier to protobuf format.
+ */
+ public OMTokenProto toProtoBuf() {
+ final OMTokenProto.Builder builder = OMTokenProto.newBuilder()
+ .setType(OMTokenProto.Type.S3_STS_TOKEN)
+ .setMaxDate(getExpiry().toEpochMilli())
+ .setOwner(getOwnerId() != null ? getOwnerId() : "")
+ .setAccessKeyId(getOwnerId() != null ? getOwnerId() : "")
+ .setOriginalAccessKeyId(originalAccessKeyId != null ?
originalAccessKeyId : "")
+ .setRoleArn(roleArn != null ? roleArn : "")
+ // TODO sts - encrypt secret access key in a future PR
+ .setSecretAccessKey(secretAccessKey != null ? secretAccessKey : "")
+ .setSessionPolicy(sessionPolicy != null ? sessionPolicy : "");
+
+ if (getSecretKeyId() != null) {
+ builder.setSecretKeyId(getSecretKeyId().toString());
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Initialize this identifier from protobuf.
+ */
+ public void fromProtoBuf(OMTokenProto token) throws IOException {
+ Preconditions.checkArgument(
+ token.getType() == OMTokenProto.Type.S3_STS_TOKEN,
+ "Invalid token type for STSTokenIdentifier: " + token.getType());
+
+ setOwnerId(token.getOwner());
+ setExpiry(Instant.ofEpochMilli(token.getMaxDate()));
+
+ if (token.hasOriginalAccessKeyId()) {
+ this.originalAccessKeyId = token.getOriginalAccessKeyId();
+ }
+ if (token.hasRoleArn()) {
+ this.roleArn = token.getRoleArn();
+ }
+ if (token.hasSecretAccessKey()) {
+ // TODO sts - decrypt secret access key in a future PR
+ this.secretAccessKey = token.getSecretAccessKey();
+ }
+
+ if (token.hasSecretKeyId()) {
+ try {
+ setSecretKeyId(UUID.fromString(token.getSecretKeyId()));
+ } catch (IllegalArgumentException e) {
+ // Handle invalid UUID format gracefully
+ throw new IOException(
+ "Invalid secretKeyId format in STS token: " +
token.getSecretKeyId(), e);
+ }
+ }
+
+ if (token.hasSessionPolicy()) {
+ this.sessionPolicy = token.getSessionPolicy();
+ }
+ }
+
+ public String getRoleArn() {
+ return roleArn;
+ }
+
+ public String getSecretAccessKey() {
+ return secretAccessKey;
+ }
+
+ public String getOriginalAccessKeyId() {
+ return originalAccessKeyId;
+ }
+
+ /**
+ * Get the temporary access key ID (same as owner).
+ */
+ public String getTempAccessKeyId() {
+ return getOwnerId();
+ }
+
+ /**
+ * Optional session policy associated with this STS token, or null/empty if
none.
+ */
+ public String getSessionPolicy() {
+ return sessionPolicy;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final STSTokenIdentifier that = (STSTokenIdentifier) o;
+ return Objects.equals(roleArn, that.roleArn) &&
Objects.equals(secretAccessKey, that.secretAccessKey) &&
+ Objects.equals(originalAccessKeyId, that.originalAccessKeyId) &&
+ Objects.equals(sessionPolicy, that.sessionPolicy);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ super.hashCode(), roleArn, secretAccessKey, originalAccessKeyId,
sessionPolicy);
+ }
+
+ @Override
+ public String toString() {
+ // Intentionally left off secretAccessKey
+ return "STSTokenIdentifier{" + "tempAccessKeyId='" + getOwnerId() + "'" +
+ ", originalAccessKeyId='" + originalAccessKeyId + "', roleArn='" +
roleArn + "'" +
+ ", expiry='" + getExpiry() + "', secretKeyId='" + getSecretKeyId() +
"'" +
+ ", sessionPolicy='" + sessionPolicy + "'}";
+ }
+}
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestSTSTokenIdentifier.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestSTSTokenIdentifier.java
new file mode 100644
index 00000000000..37909703a7f
--- /dev/null
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/security/TestSTSTokenIdentifier.java
@@ -0,0 +1,392 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.apache.hadoop.ozone.security;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.UUID;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMTokenProto;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for STSTokenIdentifier.
+ */
+public class TestSTSTokenIdentifier {
+
+ @Test
+ public void testKindAndService() {
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn",
+ Instant.now().plusSeconds(3600), "secretAccessKey", "sessionPolicy");
+
+ assertEquals("STSToken", stsTokenIdentifier.getKind().toString());
+ assertEquals("STS", stsTokenIdentifier.getService());
+ }
+
+ @Test
+ public void testProtoBufRoundTrip() throws IOException {
+ // STSTokenIdentifier persists expiry with millisecond precision (via
toEpochMilli),
+ // so use a millisecond-precision Instant to avoid nanos-only differences
across
+ // platforms/JDKs during round-trips.
+ final Instant expiry =
Instant.now().plusSeconds(7200).truncatedTo(ChronoUnit.MILLIS);
+ final STSTokenIdentifier originalTokenIdentifier = new STSTokenIdentifier(
+ "tempAccess", "origAccess", "arn:aws:iam::123456789012:role/RoleY",
+ expiry, "secretKey", "sessionPolicy");
+ final UUID secretKeyId = UUID.randomUUID();
+ originalTokenIdentifier.setSecretKeyId(secretKeyId);
+
+ final OMTokenProto proto = originalTokenIdentifier.toProtoBuf();
+ assertThat(proto.getType()).isEqualTo(OMTokenProto.Type.S3_STS_TOKEN);
+ assertThat(proto.getOwner()).isEqualTo("tempAccess");
+ assertThat(proto.getMaxDate()).isEqualTo(expiry.toEpochMilli());
+ assertThat(proto.getOriginalAccessKeyId()).isEqualTo("origAccess");
+
assertThat(proto.getRoleArn()).isEqualTo("arn:aws:iam::123456789012:role/RoleY");
+ assertThat(proto.getSecretAccessKey()).isEqualTo("secretKey");
+ assertThat(proto.getSessionPolicy()).isEqualTo("sessionPolicy");
+ assertThat(proto.getSecretKeyId()).isEqualTo(secretKeyId.toString());
+
+ final STSTokenIdentifier parsedTokenIdentifier = new STSTokenIdentifier();
+ parsedTokenIdentifier.fromProtoBuf(proto);
+
+ assertThat(parsedTokenIdentifier.getOwnerId()).isEqualTo("tempAccess");
+ assertThat(parsedTokenIdentifier.getExpiry()).isEqualTo(expiry);
+
assertThat(parsedTokenIdentifier.getOriginalAccessKeyId()).isEqualTo("origAccess");
+
assertThat(parsedTokenIdentifier.getRoleArn()).isEqualTo("arn:aws:iam::123456789012:role/RoleY");
+
assertThat(parsedTokenIdentifier.getSecretAccessKey()).isEqualTo("secretKey");
+ assertThat(parsedTokenIdentifier.getSecretKeyId()).isEqualTo(secretKeyId);
+
assertThat(parsedTokenIdentifier.getSessionPolicy()).isEqualTo("sessionPolicy");
+ assertThat(parsedTokenIdentifier).isEqualTo(originalTokenIdentifier);
+
assertThat(parsedTokenIdentifier.hashCode()).isEqualTo(originalTokenIdentifier.hashCode());
+ }
+
+ @Test
+ public void testFromProtoBufInvalidSecretKeyId() {
+ final OMTokenProto invalid = OMTokenProto.newBuilder()
+ .setType(OMTokenProto.Type.S3_STS_TOKEN)
+ .setOwner("tempAccessKeyId")
+ .setMaxDate(Instant.now().toEpochMilli())
+ .setSecretKeyId("not-a-uuid")
+ .build();
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", Instant.now(),
+ "secretAccessKey", "sessionPolicy");
+
+ final IOException ex = assertThrows(IOException.class, () ->
stsTokenIdentifier.fromProtoBuf(invalid));
+ assertThat(ex.getMessage()).isEqualTo("Invalid secretKeyId format in STS
token: not-a-uuid");
+ }
+
+ @Test
+ public void testProtobufRoundTripWithNullSessionPolicy() throws IOException {
+ final Instant expiry = Instant.now().plusSeconds(7200);
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccess", "origAccess", "arn:aws:iam::123456789012:role/RoleX",
+ expiry, "secretKey", null);
+
+ final OMTokenProto proto = stsTokenIdentifier.toProtoBuf();
+ assertThat(proto.getSessionPolicy()).isEmpty();
+
+ final STSTokenIdentifier parsedTokenIdentifier = new STSTokenIdentifier();
+ parsedTokenIdentifier.fromProtoBuf(proto);
+
+ assertThat(parsedTokenIdentifier.getSessionPolicy()).isEmpty();
+ }
+
+ @Test
+ public void testProtobufRoundTripWithEmptySessionPolicy() throws IOException
{
+ final Instant expiry = Instant.now().plusSeconds(4000);
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccess", "origAccess", "arn:aws:iam::123456789012:role/RoleZ",
+ expiry, "secretKey", "");
+
+ final OMTokenProto proto = stsTokenIdentifier.toProtoBuf();
+ assertThat(proto.getSessionPolicy()).isEmpty();
+
+ final STSTokenIdentifier parsedTokenIdentifier = new STSTokenIdentifier();
+ parsedTokenIdentifier.fromProtoBuf(proto);
+
+ assertThat(parsedTokenIdentifier.getSessionPolicy()).isEmpty();
+ }
+
+ @Test
+ public void testFromProtoBufInvalidTokenType() {
+ final OMTokenProto invalidType = OMTokenProto.newBuilder()
+ .setType(OMTokenProto.Type.DELEGATION_TOKEN) // Wrong type
+ .setOwner("tempAccessKeyId")
+ .setMaxDate(Instant.now().toEpochMilli())
+ .build();
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "origAccessKeyId", "roleArn", Instant.now(),
+ "secretAccessKey", "sessionPolicy");
+
+ final IllegalArgumentException ex = assertThrows(
+ IllegalArgumentException.class, () ->
stsTokenIdentifier.fromProtoBuf(invalidType));
+ assertThat(ex.getMessage()).isEqualTo("Invalid token type for
STSTokenIdentifier: DELEGATION_TOKEN");
+ }
+
+ @Test
+ public void testWriteToAndReadFromByteArray() throws Exception {
+ // Use millisecond-precision Instant so that the value survives the
+ // toEpochMilli() / Instant.ofEpochMilli() round-trip without losing
precision
+ // compared to the original object, which is compared using equals().
+ final Instant expiry =
+ Instant.now().plusSeconds(1000).truncatedTo(ChronoUnit.MILLIS);
+ final STSTokenIdentifier originalTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+ originalTokenIdentifier.setSecretKeyId(UUID.randomUUID());
+
+ final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try (DataOutputStream out = new DataOutputStream(baos)) {
+ originalTokenIdentifier.write(out);
+ }
+
+ final byte[] bytes = baos.toByteArray();
+ final STSTokenIdentifier parsedTokenIdentifier = new STSTokenIdentifier();
+ parsedTokenIdentifier.readFromByteArray(bytes);
+
+ assertThat(parsedTokenIdentifier).isEqualTo(originalTokenIdentifier);
+ }
+
+ @Test
+ public void testWriteToAndReadFromByteArrayWithDifferentSecretKeyIds()
throws Exception {
+ final UUID uuid1 = UUID.randomUUID();
+ UUID uuid2 = UUID.randomUUID();
+ if (uuid2.equals(uuid1)) {
+ uuid2 = UUID.randomUUID();
+ }
+
+ final Instant expiry = Instant.now().plusSeconds(1500);
+ final STSTokenIdentifier originalTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+ originalTokenIdentifier.setSecretKeyId(uuid1);
+
+ final ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
+ try (DataOutputStream out = new DataOutputStream(baos1)) {
+ originalTokenIdentifier.write(out);
+ }
+
+ final STSTokenIdentifier anotherTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+ anotherTokenIdentifier.setSecretKeyId(uuid2);
+
+ final ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
+ try (DataOutputStream out = new DataOutputStream(baos2)) {
+ anotherTokenIdentifier.write(out);
+ }
+
+ // The byte arrays should be different due to different secret key IDs
+ assertThat(baos1.toByteArray()).isNotEqualTo(baos2.toByteArray());
+ }
+
+ @Test
+ public void testWriteToAndReadFromByteArrayWithSameSecretKeyIds() throws
Exception {
+ final UUID uuid = UUID.randomUUID();
+ final Instant expiry = Instant.now().plusSeconds(1700);
+
+ final STSTokenIdentifier originalTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+ originalTokenIdentifier.setSecretKeyId(uuid);
+
+ final ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
+ try (DataOutputStream out = new DataOutputStream(baos1)) {
+ originalTokenIdentifier.write(out);
+ }
+
+ final STSTokenIdentifier anotherTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+ anotherTokenIdentifier.setSecretKeyId(uuid);
+
+ final ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
+ try (DataOutputStream out = new DataOutputStream(baos2)) {
+ anotherTokenIdentifier.write(out);
+ }
+
+ // The byte arrays should be the same since they have the same contents
+ assertThat(baos1.toByteArray()).isEqualTo(baos2.toByteArray());
+ }
+
+ @Test
+ public void testGettersReturnCorrectValues() {
+ final Instant expiry = Instant.now().plusSeconds(3600);
+ final String tempAccessKeyId = "ASIATEMP123456";
+ final String originalAccessKeyId = "AKIAORIGINAL123";
+ final String roleArn = "arn:aws:iam::123456789012:role/MyRole";
+ final String secretAccessKey = "mySecretKey";
+ final String sessionPolicy = "myPolicy";
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ tempAccessKeyId, originalAccessKeyId, roleArn, expiry,
secretAccessKey, sessionPolicy);
+
+ assertThat(stsTokenIdentifier.getOwnerId()).isEqualTo(tempAccessKeyId);
+
assertThat(stsTokenIdentifier.getTempAccessKeyId()).isEqualTo(tempAccessKeyId);
+
assertThat(stsTokenIdentifier.getOriginalAccessKeyId()).isEqualTo(originalAccessKeyId);
+ assertThat(stsTokenIdentifier.getRoleArn()).isEqualTo(roleArn);
+ assertThat(stsTokenIdentifier.getExpiry()).isEqualTo(expiry);
+
assertThat(stsTokenIdentifier.getSecretAccessKey()).isEqualTo(secretAccessKey);
+ assertThat(stsTokenIdentifier.getSessionPolicy()).isEqualTo(sessionPolicy);
+ }
+
+ @Test
+ public void testEqualsAndHashCode() {
+ final Instant expiry = Instant.now().plusSeconds(3600);
+ final UUID uuid = UUID.randomUUID();
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+ stsTokenIdentifier.setSecretKeyId(uuid);
+
+ final STSTokenIdentifier stsTokenIdentifier2 = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+ stsTokenIdentifier2.setSecretKeyId(uuid);
+
+ assertThat(stsTokenIdentifier).isEqualTo(stsTokenIdentifier2);
+
assertThat(stsTokenIdentifier.hashCode()).isEqualTo(stsTokenIdentifier2.hashCode());
+ }
+
+ @Test
+ public void testNotEqualsWhenTempAccessKeyIdDiffers() {
+ final Instant expiry = Instant.now().plusSeconds(3600);
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId1", "originalAccessKeyId", "roleArn",
+ expiry, "secretAccessKey", "sessionPolicy");
+
+ final STSTokenIdentifier stsTokenIdentifier2 = new STSTokenIdentifier(
+ "tempAccessKeyId2", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+
+ assertThat(stsTokenIdentifier).isNotEqualTo(stsTokenIdentifier2);
+ }
+
+ @Test
+ public void testNotEqualsWhenOriginalAccessKeyIdDiffers() {
+ final Instant expiry = Instant.now().plusSeconds(3600);
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId1", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+
+ final STSTokenIdentifier stsTokenIdentifier2 = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId2", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+
+ assertThat(stsTokenIdentifier).isNotEqualTo(stsTokenIdentifier2);
+ }
+
+ @Test
+ public void testNotEqualsWhenRoleArnDiffers() {
+ final Instant expiry = Instant.now().plusSeconds(3600);
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn1", expiry,
+ "secretAccessKey", "sessionPolicy");
+
+ final STSTokenIdentifier stsTokenIdentifier2 = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn2", expiry,
+ "secretAccessKey", "sessionPolicy");
+
+ assertThat(stsTokenIdentifier).isNotEqualTo(stsTokenIdentifier2);
+ }
+
+ @Test
+ public void testNotEqualsWhenExpirationDiffers() {
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn",
+ Instant.now().plusSeconds(3600), "secretAccessKey", "sessionPolicy");
+
+ final STSTokenIdentifier stsTokenIdentifier2 = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn",
+ Instant.now().plusSeconds(7600), "secretAccessKey", "sessionPolicy");
+
+ assertThat(stsTokenIdentifier).isNotEqualTo(stsTokenIdentifier2);
+ }
+
+ @Test
+ public void testNotEqualsWhenSecretAccessKeyDiffers() {
+ final Instant expiry = Instant.now().plusSeconds(3600);
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey1", "sessionPolicy");
+
+ final STSTokenIdentifier stsTokenIdentifier2 = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey2", "sessionPolicy");
+
+ assertThat(stsTokenIdentifier).isNotEqualTo(stsTokenIdentifier2);
+ }
+
+ @Test
+ public void testNotEqualsWhenSessionPolicyDiffers() {
+ final Instant expiry = Instant.now().plusSeconds(3600);
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy1");
+
+ final STSTokenIdentifier stsTokenIdentifier2 = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy2");
+
+ assertThat(stsTokenIdentifier).isNotEqualTo(stsTokenIdentifier2);
+ }
+
+ @Test
+ public void testToString() {
+ final Instant expiry = Instant.now().plusSeconds(3600);
+ final UUID uuid = UUID.randomUUID();
+
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", expiry,
+ "secretAccessKey", "sessionPolicy");
+ stsTokenIdentifier.setSecretKeyId(uuid);
+
+ final String stsTokenIdentifierStr = stsTokenIdentifier.toString();
+ final String expectedString = "STSTokenIdentifier{" +
"tempAccessKeyId='tempAccessKeyId'" +
+ ", originalAccessKeyId='originalAccessKeyId'" + ", roleArn='roleArn'"
+ ", expiry='" + expiry +
+ "', secretKeyId='" + uuid + "', sessionPolicy='sessionPolicy'" + '}';
+
+ assertEquals(expectedString, stsTokenIdentifierStr);
+ }
+
+ @Test
+ public void testNotEqualsWithNull() {
+ final STSTokenIdentifier stsTokenIdentifier = new STSTokenIdentifier(
+ "tempAccessKeyId", "originalAccessKeyId", "roleArn", Instant.now(),
+ "secretAccessKey", "sessionPolicy");
+
+ assertThat(stsTokenIdentifier).isNotEqualTo(null);
+ }
+}
+
+
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]