This is an automated email from the ASF dual-hosted git repository.
sammichen 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 e63936bce0e HDDS-14716. [STS] Use MalformedPolicyDocument error code
for IAM Session Policy validation errors (#9823)
e63936bce0e is described below
commit e63936bce0ed9c67b287266ec504925c18a7af30
Author: fmorg-git <[email protected]>
AuthorDate: Thu Feb 26 23:53:22 2026 -0800
HDDS-14716. [STS] Use MalformedPolicyDocument error code for IAM Session
Policy validation errors (#9823)
---
.../hadoop/ozone/om/exceptions/OMException.java | 1 +
.../security/acl/iam/IamSessionPolicyResolver.java | 22 ++--
.../acl/iam/TestIamSessionPolicyResolver.java | 29 ++---
.../src/main/proto/OmClientProtocol.proto | 1 +
.../apache/hadoop/ozone/s3sts/S3STSEndpoint.java | 10 +-
.../hadoop/ozone/s3sts/TestS3STSEndpoint.java | 124 ++++++++++++++-------
6 files changed, 120 insertions(+), 67 deletions(-)
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
index 70acadefed8..fcd1e7807f1 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/exceptions/OMException.java
@@ -277,5 +277,6 @@ public enum ResultCodes {
TOO_MANY_SNAPSHOTS,
REVOKED_TOKEN,
+ MALFORMED_POLICY_DOCUMENT,
}
}
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/iam/IamSessionPolicyResolver.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/iam/IamSessionPolicyResolver.java
index 0da9781e8af..b8b032f1b35 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/iam/IamSessionPolicyResolver.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/security/acl/iam/IamSessionPolicyResolver.java
@@ -19,7 +19,7 @@
import static java.util.Collections.singleton;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INTERNAL_ERROR;
-import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_REQUEST;
+import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.MALFORMED_POLICY_DOCUMENT;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.NOT_SUPPORTED_OPERATION;
import static
org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.CREATE;
import static
org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.DELETE;
@@ -181,7 +181,7 @@ private static void validateInputParameters(String
policyJson, String volumeName
if (policyJson.length() > MAX_JSON_LENGTH) {
throw new OMException(
ERROR_PREFIX + "Invalid policy JSON - exceeds maximum length of " +
MAX_JSON_LENGTH + " characters",
- INVALID_REQUEST);
+ MALFORMED_POLICY_DOCUMENT);
}
}
@@ -194,12 +194,12 @@ private static Set<JsonNode>
parseJsonAndRetrieveStatements(String policyJson) t
root = MAPPER.readTree(policyJson);
} catch (Exception e) {
throw new OMException(
- ERROR_PREFIX + "Invalid policy JSON (most likely JSON structure is
incorrect)", e, INVALID_REQUEST);
+ ERROR_PREFIX + "Invalid policy JSON (most likely JSON structure is
incorrect)", e, MALFORMED_POLICY_DOCUMENT);
}
final JsonNode statementsNode = root.path("Statement");
if (statementsNode.isMissingNode()) {
- throw new OMException(ERROR_PREFIX + "Invalid policy JSON - missing
Statement", INVALID_REQUEST);
+ throw new OMException(ERROR_PREFIX + "Invalid policy JSON - missing
Statement", MALFORMED_POLICY_DOCUMENT);
}
final Set<JsonNode> statements = new HashSet<>();
@@ -227,10 +227,10 @@ private static void
validateEffectInJsonStatement(JsonNode statement) throws OME
}
throw new OMException(
- ERROR_PREFIX + "Invalid Effect in JSON policy (must be a String) - "
+ effectNode, INVALID_REQUEST);
+ ERROR_PREFIX + "Invalid Effect in JSON policy (must be a String) - "
+ effectNode, MALFORMED_POLICY_DOCUMENT);
}
- throw new OMException(ERROR_PREFIX + "Effect is missing from JSON policy",
INVALID_REQUEST);
+ throw new OMException(ERROR_PREFIX + "Effect is missing from JSON policy",
MALFORMED_POLICY_DOCUMENT);
}
/**
@@ -276,7 +276,7 @@ private static Set<String>
parsePrefixesFromConditions(JsonNode stmt) throws OME
if (!cond.isObject()) {
throw new OMException(
ERROR_PREFIX + "Invalid Condition (must have operator StringEquals
or StringLike " +
- "and key name s3:prefix) - " + cond, INVALID_REQUEST);
+ "and key name s3:prefix) - " + cond, MALFORMED_POLICY_DOCUMENT);
}
final String operator = cond.fieldNames().next();
@@ -287,12 +287,12 @@ private static Set<String>
parsePrefixesFromConditions(JsonNode stmt) throws OME
final JsonNode operatorValue = cond.get(operator);
if ("null".equals(operatorValue.asText())) {
throw new OMException(
- ERROR_PREFIX + "Missing Condition operator value for " + operator,
INVALID_REQUEST);
+ ERROR_PREFIX + "Missing Condition operator value for " + operator,
MALFORMED_POLICY_DOCUMENT);
}
if (!operatorValue.isObject()) {
throw new OMException(
- ERROR_PREFIX + "Invalid Condition operator value structure - " +
operatorValue, INVALID_REQUEST);
+ ERROR_PREFIX + "Invalid Condition operator value structure - " +
operatorValue, MALFORMED_POLICY_DOCUMENT);
}
final String keyName = operatorValue.fieldNames().hasNext() ?
operatorValue.fieldNames().next() : null;
@@ -382,7 +382,7 @@ static Set<ResourceSpec>
validateAndCategorizeResources(AuthorizerType authorize
Set<String> resources) throws OMException {
final Set<ResourceSpec> resourceSpecs = new HashSet<>();
if (resources.isEmpty()) {
- throw new OMException(ERROR_PREFIX + "No Resource(s) found in policy",
INVALID_REQUEST);
+ throw new OMException(ERROR_PREFIX + "No Resource(s) found in policy",
MALFORMED_POLICY_DOCUMENT);
}
for (String resource : resources) {
if ("*".equals(resource)) {
@@ -397,7 +397,7 @@ static Set<ResourceSpec>
validateAndCategorizeResources(AuthorizerType authorize
final String suffix = resource.substring(AWS_S3_ARN_PREFIX.length());
if (suffix.isEmpty()) {
- throw new OMException(ERROR_PREFIX + "Invalid Resource Arn - " +
resource, INVALID_REQUEST);
+ throw new OMException(ERROR_PREFIX + "Invalid Resource Arn - " +
resource, MALFORMED_POLICY_DOCUMENT);
}
ResourceSpec spec = parseResourceSpec(suffix);
diff --git
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/security/acl/iam/TestIamSessionPolicyResolver.java
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/security/acl/iam/TestIamSessionPolicyResolver.java
index 4ca478156a3..41d2fc338f3 100644
---
a/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/security/acl/iam/TestIamSessionPolicyResolver.java
+++
b/hadoop-ozone/common/src/test/java/org/apache/hadoop/ozone/security/acl/iam/TestIamSessionPolicyResolver.java
@@ -18,7 +18,7 @@
package org.apache.hadoop.ozone.security.acl.iam;
import static java.util.Collections.emptySet;
-import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_REQUEST;
+import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.MALFORMED_POLICY_DOCUMENT;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.NOT_SUPPORTED_OPERATION;
import static
org.apache.hadoop.ozone.security.acl.AssumeRoleRequest.OzoneGrant;
import static org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType;
@@ -119,7 +119,7 @@ public void testInvalidJsonWithoutStatementThrows() {
"}";
expectResolveThrowsForBothAuthorizers(
- json, "IAM session policy: Invalid policy JSON - missing Statement",
INVALID_REQUEST);
+ json, "IAM session policy: Invalid policy JSON - missing Statement",
MALFORMED_POLICY_DOCUMENT);
}
@Test
@@ -134,7 +134,7 @@ public void testInvalidEffectThrows() {
expectResolveThrowsForBothAuthorizers(
json, "IAM session policy: Invalid Effect in JSON policy (must be a
String) - [\"Allow\"]",
- INVALID_REQUEST);
+ MALFORMED_POLICY_DOCUMENT);
}
@Test
@@ -147,7 +147,7 @@ public void testMissingEffectInStatementThrows() {
"}";
expectResolveThrowsForBothAuthorizers(
- json, "IAM session policy: Effect is missing from JSON policy",
INVALID_REQUEST);
+ json, "IAM session policy: Effect is missing from JSON policy",
MALFORMED_POLICY_DOCUMENT);
}
@Test
@@ -193,7 +193,7 @@ public void testInvalidConditionThrows() {
expectResolveThrowsForBothAuthorizers(
json, "IAM session policy: Invalid Condition (must have operator
StringEquals or StringLike and key name " +
- "s3:prefix) - [\"RandomCondition\"]", INVALID_REQUEST);
+ "s3:prefix) - [\"RandomCondition\"]", MALFORMED_POLICY_DOCUMENT);
}
@Test
@@ -209,7 +209,7 @@ public void
testInvalidConditionAttributeMissingStringEqualsThrows() {
expectResolveThrowsForBothAuthorizers(
json, "IAM session policy: Missing Condition operator value for
StringEquals",
- INVALID_REQUEST);
+ MALFORMED_POLICY_DOCUMENT);
}
@Test
@@ -225,7 +225,7 @@ public void testInvalidConditionAttributeStructureThrows() {
expectResolveThrowsForBothAuthorizers(
json, "IAM session policy: Invalid Condition operator value structure
- [{\"s3:prefix\":\"folder/\"}]",
- INVALID_REQUEST);
+ MALFORMED_POLICY_DOCUMENT);
}
@Test
@@ -234,7 +234,7 @@ public void testInvalidJsonThrows() {
expectResolveThrowsForBothAuthorizers(
invalidJson, "IAM session policy: Invalid policy JSON (most likely
JSON structure is incorrect)",
- INVALID_REQUEST);
+ MALFORMED_POLICY_DOCUMENT);
}
@Test
@@ -242,7 +242,8 @@ public void testJsonExceedsMaxLengthThrows() {
final String json = createJsonStringLargerThan2048Characters();
expectResolveThrowsForBothAuthorizers(
- json, "IAM session policy: Invalid policy JSON - exceeds maximum
length of 2048 characters", INVALID_REQUEST);
+ json, "IAM session policy: Invalid policy JSON - exceeds maximum
length of 2048 characters",
+ MALFORMED_POLICY_DOCUMENT);
}
@Test
@@ -681,20 +682,20 @@ public void
testValidateAndCategorizeResourcesWithInvalidArnThrows() {
public void testValidateAndCategorizeResourcesWithArnWithNoBucketThrows() {
expectOMExceptionWithCode(
() -> validateAndCategorizeResources(NATIVE,
Collections.singleton("arn:aws:s3:::")),
- "IAM session policy: Invalid Resource Arn - arn:aws:s3:::",
INVALID_REQUEST);
+ "IAM session policy: Invalid Resource Arn - arn:aws:s3:::",
MALFORMED_POLICY_DOCUMENT);
expectOMExceptionWithCode(
() -> validateAndCategorizeResources(RANGER,
Collections.singleton("arn:aws:s3:::")),
- "IAM session policy: Invalid Resource Arn - arn:aws:s3:::",
INVALID_REQUEST);
+ "IAM session policy: Invalid Resource Arn - arn:aws:s3:::",
MALFORMED_POLICY_DOCUMENT);
}
@Test
public void testValidateAndCategorizeResourcesWithNoResourcesThrows() {
expectOMExceptionWithCode(
() -> validateAndCategorizeResources(NATIVE, emptySet()), "IAM session
policy: No Resource(s) found in policy",
- INVALID_REQUEST);
+ MALFORMED_POLICY_DOCUMENT);
expectOMExceptionWithCode(
() -> validateAndCategorizeResources(RANGER, emptySet()), "IAM session
policy: No Resource(s) found in policy",
- INVALID_REQUEST);
+ MALFORMED_POLICY_DOCUMENT);
}
@Test
@@ -1925,7 +1926,7 @@ public void testInvalidResourceArnThrows() {
"}";
expectResolveThrowsForBothAuthorizers(
- json, "IAM session policy: Invalid Resource Arn - arn:aws:s3:::",
INVALID_REQUEST);
+ json, "IAM session policy: Invalid Resource Arn - arn:aws:s3:::",
MALFORMED_POLICY_DOCUMENT);
}
private static void expectIllegalArgumentException(Runnable runnable, String
expectedMessage) {
diff --git
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 173b444e6f1..1102d44966d 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -578,6 +578,7 @@ enum Status {
TOO_MANY_SNAPSHOTS = 98;
REVOKED_TOKEN = 99;
+ MALFORMED_POLICY_DOCUMENT = 100;
}
/**
diff --git
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpoint.java
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpoint.java
index e2dee7dc6cf..e0be5c5183d 100644
---
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpoint.java
+++
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpoint.java
@@ -88,6 +88,7 @@ public class S3STSEndpoint extends S3STSEndpointBase {
private static final String ACCESS_DENIED = "AccessDenied";
private static final String INVALID_CLIENT_TOKEN_ID = "InvalidClientTokenId";
private static final String UNSUPPORTED_OPERATION = "UnsupportedOperation";
+ private static final String MALFORMED_POLICY_DOCUMENT =
"MalformedPolicyDocument";
@Inject
private RequestIdentifier requestIdentifier;
@@ -284,12 +285,13 @@ private Response handleAssumeRole(String roleArn, String
roleSessionName, Intege
}
if (omException.getResult() ==
OMException.ResultCodes.NOT_SUPPORTED_OPERATION ||
omException.getResult() ==
OMException.ResultCodes.FEATURE_NOT_ENABLED) {
- throw new OSTSException(
- UNSUPPORTED_OPERATION, omException.getMessage(),
NOT_IMPLEMENTED.getStatusCode());
+ throw new OSTSException(UNSUPPORTED_OPERATION,
omException.getMessage(), NOT_IMPLEMENTED.getStatusCode());
}
if (omException.getResult() ==
OMException.ResultCodes.INVALID_REQUEST) {
- throw new OSTSException(
- VALIDATION_ERROR, omException.getMessage(),
BAD_REQUEST.getStatusCode());
+ throw new OSTSException(VALIDATION_ERROR, omException.getMessage(),
BAD_REQUEST.getStatusCode());
+ }
+ if (omException.getResult() ==
OMException.ResultCodes.MALFORMED_POLICY_DOCUMENT) {
+ throw new OSTSException(MALFORMED_POLICY_DOCUMENT,
omException.getMessage(), BAD_REQUEST.getStatusCode());
}
}
throw new OSTSException(
diff --git
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3sts/TestS3STSEndpoint.java
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3sts/TestS3STSEndpoint.java
index d0eaca9a5dc..059f54e0993 100644
---
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3sts/TestS3STSEndpoint.java
+++
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3sts/TestS3STSEndpoint.java
@@ -73,6 +73,7 @@ public class TestS3STSEndpoint {
private static final String ROLE_USER_ARN =
"arn:aws:sts::123456789012:assumed-role/test-role/" + ROLE_SESSION_NAME;
private static final String STS_NS =
"https://sts.amazonaws.com/doc/2011-06-15/";
private static final String AWS_FAULT_NS =
"http://webservices.amazon.com/AWSFault/2005-15-09";
+ private static final String REQUEST_ID = "test-request-id";
@BeforeEach
public void setup() throws Exception {
@@ -105,7 +106,7 @@ public void setup() throws Exception {
auditLogger = mock(AuditLogger.class);
endpoint.setAuditLogger(auditLogger);
- when(requestIdentifier.getRequestId()).thenReturn("test-request-id");
+ when(requestIdentifier.getRequestId()).thenReturn(REQUEST_ID);
endpoint.setRequestIdentifier(requestIdentifier);
SignatureInfo signatureInfo = new
SignatureInfo.Builder(SignatureInfo.Version.V4)
@@ -212,8 +213,7 @@ public void testStsUnsupportedActionWithVersionSupplied()
throws Exception {
assertEquals(400, ex.getHttpCode());
verifyNoInteractions(auditLogger);
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), AWS_FAULT_NS, "Sender", "InvalidAction",
"Could not find operation UnsupportedAction for version 2011-06-15");
}
@@ -226,8 +226,7 @@ public void
testStsUnsupportedActionWithVersionNotSupplied() throws Exception {
assertEquals(400, ex.getHttpCode());
verifyNoInteractions(auditLogger);
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), AWS_FAULT_NS, "Sender", "InvalidAction",
"Could not find operation UnsupportedAction for version
NO_VERSION_SPECIFIED");
}
@@ -241,8 +240,7 @@ public void testStsAssumeRoleWithInvalidVersion() throws
Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), AWS_FAULT_NS, "Sender", "InvalidAction",
"Could not find operation AssumeRole for version 2000-01-01");
}
@@ -256,8 +254,7 @@ public void testStsInvalidDuration() throws Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "ValidationError",
"Invalid Value: DurationSeconds");
}
@@ -285,8 +282,7 @@ public void testStsPolicyTooLarge() throws Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "ValidationError",
"Value '" + tooLargePolicy + "' at 'policy' failed to satisfy
constraint: Member " +
"must have length less than or equal to 2048");
@@ -302,8 +298,7 @@ public void testStsInvalidRoleArn() throws Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "ValidationError",
"Invalid role ARN (does not start with arn:aws:iam::)");
}
@@ -317,8 +312,7 @@ public void testStsMissingRoleArn() throws Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "ValidationError", "Value
null at 'roleArn'");
}
@@ -333,8 +327,7 @@ public void testStsInvalidRoleArnMissingRoleName() throws
Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "ValidationError",
"Invalid role ARN: missing role name");
}
@@ -349,8 +342,7 @@ public void testStsInvalidRoleArnMissingAccountId() throws
Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "ValidationError",
"Invalid AWS account ID in ARN"
);
}
@@ -363,8 +355,7 @@ public void testStsWhenActionNotImplemented() throws
Exception {
assertEquals(501, ex.getHttpCode());
verifyNoInteractions(auditLogger);
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), AWS_FAULT_NS, "Sender", "InvalidAction",
"Operation GetSessionToken is not supported yet.");
}
@@ -378,8 +369,7 @@ public void testStsMissingRoleSessionName() throws
Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "ValidationError", "Value
null at 'roleSessionName'");
}
@@ -393,8 +383,7 @@ public void
testStsInvalidRoleSessionNameWithInvalidCharacter() throws Exception
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(
ex.toXml(), STS_NS, "Sender", "ValidationError", "1 validation error
detected: " +
"Invalid character '/' in RoleSessionName: it must be 2-64 characters
long and contain only alphanumeric " +
@@ -411,8 +400,7 @@ public void testStsInvalidRoleSessionNameTooShort() throws
Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(
ex.toXml(), STS_NS, "Sender", "ValidationError", "1 validation error
detected: Invalid RoleSessionName " +
"length 1: it must be 2-64 characters long and contain only
alphanumeric characters and +, =, ,, ., @, -");
@@ -429,8 +417,7 @@ public void testStsInvalidRoleArnResourceType() throws
Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "ValidationError",
"Invalid role ARN (unexpected field count)");
}
@@ -446,8 +433,7 @@ public void testStsInternalFailureWhenBackendThrows()
throws Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Receiver", "InternalFailure", "An
internal error has occurred.");
}
@@ -463,12 +449,76 @@ public void testStsAccessDenied() throws Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "AccessDenied",
"User is not authorized to perform: sts:AssumeRole on resource: " +
ROLE_ARN);
}
+ @Test
+ public void
testStsUnsupportedOperationWhenBackendThrowsNotSupportedOperation() throws
Exception {
+ when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any(),
anyString()))
+ .thenThrow(new OMException("Operation is not supported",
OMException.ResultCodes.NOT_SUPPORTED_OPERATION));
+
+ final OSTSException ex = assertThrows(OSTSException.class, () ->
+ endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600,
"2011-06-15", null));
+
+ assertEquals(501, ex.getHttpCode());
+ verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+ verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
+
+ ex.setRequestId(REQUEST_ID);
+ assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "UnsupportedOperation",
"Operation is not supported");
+ }
+
+ @Test
+ public void testStsUnsupportedOperationWhenBackendThrowsFeatureNotEnabled()
throws Exception {
+ when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any(),
anyString()))
+ .thenThrow(new OMException("Feature is not enabled",
OMException.ResultCodes.FEATURE_NOT_ENABLED));
+
+ final OSTSException ex = assertThrows(OSTSException.class, () ->
+ endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600,
"2011-06-15", null));
+
+ assertEquals(501, ex.getHttpCode());
+ verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+ verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
+
+ ex.setRequestId(REQUEST_ID);
+ assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "UnsupportedOperation",
"Feature is not enabled");
+ }
+
+ @Test
+ public void testStsValidationErrorWhenBackendThrowsInvalidRequest() throws
Exception {
+ when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any(),
anyString()))
+ .thenThrow(new OMException("Invalid request parameter",
OMException.ResultCodes.INVALID_REQUEST));
+
+ final OSTSException ex = assertThrows(OSTSException.class, () ->
+ endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600,
"2011-06-15", null));
+
+ assertEquals(400, ex.getHttpCode());
+ verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+ verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
+
+ ex.setRequestId(REQUEST_ID);
+ assertStsErrorXml(ex.toXml(), STS_NS, "Sender", "ValidationError",
"Invalid request parameter");
+ }
+
+ @Test
+ public void
testStsMalformedPolicyDocumentWhenBackendThrowsMalformedPolicyDocument() throws
Exception {
+ when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any(),
anyString()))
+ .thenThrow(new OMException("Malformed session policy",
OMException.ResultCodes.MALFORMED_POLICY_DOCUMENT));
+
+ final OSTSException ex = assertThrows(OSTSException.class, () ->
+ endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600,
"2011-06-15", null));
+
+ assertEquals(400, ex.getHttpCode());
+ verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+ verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
+
+ ex.setRequestId(REQUEST_ID);
+ assertStsErrorXml(
+ ex.toXml(), STS_NS, "Sender", "MalformedPolicyDocument", "Malformed
session policy");
+ }
+
@Test
public void testStsIOExceptionWrappedAsInternalFailure() throws Exception {
when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any(),
anyString()))
@@ -481,8 +531,7 @@ public void testStsIOExceptionWrappedAsInternalFailure()
throws Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
assertStsErrorXml(ex.toXml(), STS_NS, "Receiver", "InternalFailure", "An
internal error has occurred.");
}
@@ -500,8 +549,7 @@ public void testStsMultipleValidationErrors() throws
Exception {
verify(auditLogger).logWriteFailure(any(AuditMessage.class));
verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
- final String requestId = "test-request-id";
- ex.setRequestId(requestId);
+ ex.setRequestId(REQUEST_ID);
final String xml = ex.toXml();
// The order of individual validation errors is not guaranteed because
it's a HashSet, so check
@@ -540,6 +588,6 @@ private static void assertStsErrorXml(String xml, String
expectedNamespace, Stri
assertTrue(message.contains(expectedMessageContains), "Expected message to
contain: " + expectedMessageContains);
final String requestId =
doc.getElementsByTagName("RequestId").item(0).getTextContent();
- assertEquals("test-request-id", requestId);
+ assertEquals(REQUEST_ID, requestId);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]