From 76e7d6a1def130de0abd1047706e745d791ee474 Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Fri, 11 Feb 2022 14:46:44 -0800 Subject: [PATCH 1/3] Add default RegionScope for SigV4a signers This commit adds support for setting the default RegionScope used by the Sigv4a signer implementations. If the region scope to use is not supplied to the signing methods, the signers will default to this scope first and then the normal signing region. --- .../feature-AWSSDKforJavav2-7723452.json | 6 + .../authcrt/signer/AwsCrtS3V4aSigner.java | 17 +++ .../authcrt/signer/AwsCrtV4aSigner.java | 17 +++ .../internal/DefaultAwsCrtS3V4aSigner.java | 62 +++++++++- .../internal/DefaultAwsCrtV4aSigner.java | 61 +++++++++- .../internal/SigningConfigProvider.java | 2 +- .../AwsCrtS3V4aSignerSigningScopeTest.java | 70 +++++++++++ .../AwsCrtV4aSignerSigningScopeTest.java | 48 ++++++++ .../signer/internal/BaseSigningScopeTest.java | 112 ++++++++++++++++++ .../signer/internal/SigningScopeTest.java | 98 --------------- .../signer/AwsSignerExecutionAttribute.java | 2 +- .../{internal/util => }/RegionScope.java | 6 +- .../regions/internal/RegionScopeTest.java | 2 +- .../handlers/EndpointAddressInterceptor.java | 2 +- 14 files changed, 389 insertions(+), 116 deletions(-) create mode 100644 .changes/next-release/feature-AWSSDKforJavav2-7723452.json create mode 100644 core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/AwsCrtS3V4aSignerSigningScopeTest.java create mode 100644 core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/AwsCrtV4aSignerSigningScopeTest.java create mode 100644 core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/BaseSigningScopeTest.java delete mode 100644 core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/SigningScopeTest.java rename core/regions/src/main/java/software/amazon/awssdk/regions/{internal/util => }/RegionScope.java (97%) diff --git a/.changes/next-release/feature-AWSSDKforJavav2-7723452.json b/.changes/next-release/feature-AWSSDKforJavav2-7723452.json new file mode 100644 index 000000000000..f6163da47fa7 --- /dev/null +++ b/.changes/next-release/feature-AWSSDKforJavav2-7723452.json @@ -0,0 +1,6 @@ +{ + "category": "AWS SDK for Java v2", + "contributor": "", + "type": "feature", + "description": "Add support for setting the default `RegionScope` used by the Sigv4a signer implementations. If the region scope to use is not supplied to the signing methods, the signers will default to this scope first and then the normal signing region." +} diff --git a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/AwsCrtS3V4aSigner.java b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/AwsCrtS3V4aSigner.java index fb00fdebe921..c6ee258c064e 100644 --- a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/AwsCrtS3V4aSigner.java +++ b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/AwsCrtS3V4aSigner.java @@ -21,6 +21,7 @@ import software.amazon.awssdk.authcrt.signer.internal.DefaultAwsCrtS3V4aSigner; import software.amazon.awssdk.core.signer.Presigner; import software.amazon.awssdk.core.signer.Signer; +import software.amazon.awssdk.regions.RegionScope; /** * Enables signing and presigning for S3 using Sigv4a (Asymmetric Sigv4) through an external API call to the AWS CRT @@ -49,4 +50,20 @@ public interface AwsCrtS3V4aSigner extends Signer, Presigner { static AwsCrtS3V4aSigner create() { return DefaultAwsCrtS3V4aSigner.create(); } + + static Builder builder() { + return DefaultAwsCrtS3V4aSigner.builder(); + } + + interface Builder { + /** + * The region scope that this signer will default to if not provided explicitly when the signer is invoked. + * + * @param defaultRegionScope The default region scope. + * @return This builder for method chaining. + */ + Builder defaultRegionScope(RegionScope defaultRegionScope); + + AwsCrtS3V4aSigner build(); + } } diff --git a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/AwsCrtV4aSigner.java b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/AwsCrtV4aSigner.java index a61b30a289e5..692ecec5047f 100644 --- a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/AwsCrtV4aSigner.java +++ b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/AwsCrtV4aSigner.java @@ -21,6 +21,7 @@ import software.amazon.awssdk.authcrt.signer.internal.DefaultAwsCrtV4aSigner; import software.amazon.awssdk.core.signer.Presigner; import software.amazon.awssdk.core.signer.Signer; +import software.amazon.awssdk.regions.RegionScope; /** * Enables signing and presigning using Sigv4a (Asymmetric Sigv4) through an external API call to the AWS CRT @@ -39,4 +40,20 @@ public interface AwsCrtV4aSigner extends Signer, Presigner { static AwsCrtV4aSigner create() { return DefaultAwsCrtV4aSigner.create(); } + + static Builder builder() { + return DefaultAwsCrtV4aSigner.builder(); + } + + interface Builder { + /** + * The region scope that this signer will default to if not provided explicitly when the signer is invoked. + * + * @param defaultRegionScope The default region scope. + * @return This builder for method chaining. + */ + Builder defaultRegionScope(RegionScope defaultRegionScope); + + AwsCrtV4aSigner build(); + } } diff --git a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/DefaultAwsCrtS3V4aSigner.java b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/DefaultAwsCrtS3V4aSigner.java index f7bb8a92cb26..940f1a60cb24 100644 --- a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/DefaultAwsCrtS3V4aSigner.java +++ b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/DefaultAwsCrtS3V4aSigner.java @@ -31,20 +31,36 @@ import software.amazon.awssdk.crt.auth.signing.AwsSigningConfig; import software.amazon.awssdk.http.ContentStreamProvider; import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.regions.RegionScope; @SdkInternalApi public final class DefaultAwsCrtS3V4aSigner implements AwsCrtS3V4aSigner { private final AwsCrt4aSigningAdapter signerAdapter; private final SigningConfigProvider configProvider; + private final RegionScope defaultRegionScope; DefaultAwsCrtS3V4aSigner(AwsCrt4aSigningAdapter signerAdapter, SigningConfigProvider signingConfigProvider) { + this(signerAdapter, signingConfigProvider, null); + } + + DefaultAwsCrtS3V4aSigner(AwsCrt4aSigningAdapter signerAdapter, SigningConfigProvider signingConfigProvider, + RegionScope defaultRegionScope) { this.signerAdapter = signerAdapter; this.configProvider = signingConfigProvider; + this.defaultRegionScope = defaultRegionScope; + } + + private DefaultAwsCrtS3V4aSigner(BuilderImpl builder) { + this(new AwsCrt4aSigningAdapter(), new SigningConfigProvider(), builder.defaultRegionScope); } public static AwsCrtS3V4aSigner create() { - return new DefaultAwsCrtS3V4aSigner(new AwsCrt4aSigningAdapter(), new SigningConfigProvider()); + return builder().build(); + } + + public static Builder builder() { + return new BuilderImpl(); } @Override @@ -52,13 +68,14 @@ public SdkHttpFullRequest sign(SdkHttpFullRequest request, ExecutionAttributes e if (credentialsAreAnonymous(executionAttributes)) { return request; } - AwsSigningConfig requestSigningConfig = configProvider.createS3CrtSigningConfig(executionAttributes); - if (shouldSignPayload(request, executionAttributes)) { + ExecutionAttributes defaultsApplied = applyDefaults(executionAttributes); + AwsSigningConfig requestSigningConfig = configProvider.createS3CrtSigningConfig(defaultsApplied); + if (shouldSignPayload(request, defaultsApplied)) { requestSigningConfig.setSignedBodyValue(AwsSigningConfig.AwsSignedBodyValue.STREAMING_AWS4_ECDSA_P256_SHA256_PAYLOAD); SdkHttpFullRequest.Builder mutableRequest = request.toBuilder(); setHeaderContentLength(mutableRequest); SdkSigningResult signingResult = signerAdapter.sign(mutableRequest.build(), requestSigningConfig); - AwsSigningConfig chunkConfig = configProvider.createChunkedSigningConfig(executionAttributes); + AwsSigningConfig chunkConfig = configProvider.createChunkedSigningConfig(defaultsApplied); return enablePayloadSigning(signingResult, chunkConfig); } else { requestSigningConfig.setSignedBodyValue(AwsSigningConfig.AwsSignedBodyValue.UNSIGNED_PAYLOAD); @@ -71,7 +88,8 @@ public SdkHttpFullRequest presign(SdkHttpFullRequest request, ExecutionAttribute if (credentialsAreAnonymous(executionAttributes)) { return request; } - return signerAdapter.signRequest(request, configProvider.createS3CrtPresigningConfig(executionAttributes)); + ExecutionAttributes defaultsApplied = applyDefaults(executionAttributes); + return signerAdapter.signRequest(request, configProvider.createS3CrtPresigningConfig(defaultsApplied)); } private boolean credentialsAreAnonymous(ExecutionAttributes executionAttributes) { @@ -121,4 +139,38 @@ private boolean booleanValue(Boolean attribute) { return Boolean.TRUE.equals(attribute); } + /** + * Applies preconfigured defaults for values that are not present in {@code executionAttributes}. + */ + private ExecutionAttributes applyDefaults(ExecutionAttributes executionAttributes) { + return applyDefaultRegionScope(executionAttributes); + } + + private ExecutionAttributes applyDefaultRegionScope(ExecutionAttributes executionAttributes) { + if (executionAttributes.getAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE) != null) { + return executionAttributes; + } + + if (defaultRegionScope == null) { + return executionAttributes; + } + + return executionAttributes.copy() + .putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE, defaultRegionScope); + } + + private static class BuilderImpl implements Builder { + private RegionScope defaultRegionScope; + + @Override + public Builder defaultRegionScope(RegionScope defaultRegionScope) { + this.defaultRegionScope = defaultRegionScope; + return this; + } + + @Override + public AwsCrtS3V4aSigner build() { + return new DefaultAwsCrtS3V4aSigner(this); + } + } } diff --git a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/DefaultAwsCrtV4aSigner.java b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/DefaultAwsCrtV4aSigner.java index a179b89b8977..aa56814fa703 100644 --- a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/DefaultAwsCrtV4aSigner.java +++ b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/DefaultAwsCrtV4aSigner.java @@ -21,20 +21,32 @@ import software.amazon.awssdk.authcrt.signer.AwsCrtV4aSigner; import software.amazon.awssdk.core.interceptor.ExecutionAttributes; import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.regions.RegionScope; @SdkInternalApi public final class DefaultAwsCrtV4aSigner implements AwsCrtV4aSigner { private final AwsCrt4aSigningAdapter signer; private final SigningConfigProvider configProvider; + private final RegionScope defaultRegionScope; - private DefaultAwsCrtV4aSigner() { - signer = new AwsCrt4aSigningAdapter(); - configProvider = new SigningConfigProvider(); + private DefaultAwsCrtV4aSigner(BuilderImpl builder) { + this(new AwsCrt4aSigningAdapter(), new SigningConfigProvider(), builder.defaultRegionScope); + } + + DefaultAwsCrtV4aSigner(AwsCrt4aSigningAdapter signer, SigningConfigProvider configProvider, + RegionScope defaultRegionScope) { + this.signer = signer; + this.configProvider = configProvider; + this.defaultRegionScope = defaultRegionScope; } public static AwsCrtV4aSigner create() { - return new DefaultAwsCrtV4aSigner(); + return builder().build(); + } + + public static Builder builder() { + return new BuilderImpl(); } @Override @@ -42,11 +54,48 @@ public SdkHttpFullRequest sign(SdkHttpFullRequest request, ExecutionAttributes e if (CredentialUtils.isAnonymous(executionAttributes.getAttribute(AwsSignerExecutionAttribute.AWS_CREDENTIALS))) { return request; } - return signer.signRequest(request, configProvider.createCrtSigningConfig(executionAttributes)); + ExecutionAttributes defaultsApplied = applyDefaults(executionAttributes); + return signer.signRequest(request, configProvider.createCrtSigningConfig(defaultsApplied)); } @Override public SdkHttpFullRequest presign(SdkHttpFullRequest request, ExecutionAttributes executionAttributes) { - return signer.signRequest(request, configProvider.createCrtPresigningConfig(executionAttributes)); + ExecutionAttributes defaultsApplied = applyDefaults(executionAttributes); + return signer.signRequest(request, configProvider.createCrtPresigningConfig(defaultsApplied)); + } + + /** + * Applies preconfigured defaults for values that are not present in {@code executionAttributes}. + */ + private ExecutionAttributes applyDefaults(ExecutionAttributes executionAttributes) { + return applyDefaultRegionScope(executionAttributes); + } + + private ExecutionAttributes applyDefaultRegionScope(ExecutionAttributes executionAttributes) { + if (executionAttributes.getAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE) != null) { + return executionAttributes; + } + + if (defaultRegionScope == null) { + return executionAttributes; + } + + return executionAttributes.copy() + .putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE, defaultRegionScope); + } + + private static class BuilderImpl implements Builder { + private RegionScope defaultRegionScope; + + @Override + public Builder defaultRegionScope(RegionScope defaultRegionScope) { + this.defaultRegionScope = defaultRegionScope; + return this; + } + + @Override + public AwsCrtV4aSigner build() { + return new DefaultAwsCrtV4aSigner(this); + } } } diff --git a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/SigningConfigProvider.java b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/SigningConfigProvider.java index f055140701b2..9f18c030dc03 100644 --- a/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/SigningConfigProvider.java +++ b/core/auth-crt/src/main/java/software/amazon/awssdk/authcrt/signer/internal/SigningConfigProvider.java @@ -26,7 +26,7 @@ import software.amazon.awssdk.auth.signer.internal.SignerConstant; import software.amazon.awssdk.core.interceptor.ExecutionAttributes; import software.amazon.awssdk.crt.auth.signing.AwsSigningConfig; -import software.amazon.awssdk.regions.internal.util.RegionScope; +import software.amazon.awssdk.regions.RegionScope; @SdkInternalApi public class SigningConfigProvider { diff --git a/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/AwsCrtS3V4aSignerSigningScopeTest.java b/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/AwsCrtS3V4aSignerSigningScopeTest.java new file mode 100644 index 000000000000..191c12bbcee4 --- /dev/null +++ b/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/AwsCrtS3V4aSignerSigningScopeTest.java @@ -0,0 +1,70 @@ +/* + * 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.authcrt.signer.internal; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute; +import software.amazon.awssdk.authcrt.signer.AwsCrtS3V4aSigner; +import software.amazon.awssdk.authcrt.signer.SignerTestUtils; +import software.amazon.awssdk.authcrt.signer.SigningTestCase; +import software.amazon.awssdk.core.interceptor.ExecutionAttributes; +import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.regions.RegionScope; + +public class AwsCrtS3V4aSignerSigningScopeTest extends BaseSigningScopeTest { + @Test + public void signing_chunkedEncoding_regionalScope_present_overrides() { + SigningTestCase testCase = SignerTestUtils.createBasicChunkedSigningTestCase(); + SdkHttpFullRequest signedRequest = signRequestWithScope(testCase, null, RegionScope.GLOBAL); + + String regionHeader = signedRequest.firstMatchingHeader("X-Amz-Region-Set").get(); + assertThat(regionHeader).isEqualTo(RegionScope.GLOBAL.id()); + } + + @Test + public void testS3Presigning() { + SigningTestCase testCase = SignerTestUtils.createBasicQuerySigningTestCase(); + + SdkHttpFullRequest signedRequest = presignRequestWithScope(testCase, null, RegionScope.GLOBAL); + + List regionHeader = signedRequest.rawQueryParameters().get("X-Amz-Region-Set"); + assertThat(regionHeader.get(0)).isEqualTo(RegionScope.GLOBAL.id()); + } + + + protected SdkHttpFullRequest signRequestWithScope(SigningTestCase testCase, RegionScope defaultRegionScope, + RegionScope regionScope) { + ExecutionAttributes executionAttributes = SignerTestUtils.buildBasicExecutionAttributes(testCase); + if (regionScope != null) { + executionAttributes.putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE, regionScope); + } + SdkHttpFullRequest request = testCase.requestBuilder.build(); + return AwsCrtS3V4aSigner.builder().defaultRegionScope(defaultRegionScope).build().sign(request, executionAttributes); + } + + protected SdkHttpFullRequest presignRequestWithScope(SigningTestCase testCase, RegionScope defaultRegionScope, + RegionScope regionScope) { + ExecutionAttributes executionAttributes = SignerTestUtils.buildBasicExecutionAttributes(testCase); + if (regionScope != null) { + executionAttributes.putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE, regionScope); + } + SdkHttpFullRequest request = testCase.requestBuilder.build(); + return AwsCrtS3V4aSigner.builder().defaultRegionScope(defaultRegionScope).build().presign(request, executionAttributes); + } +} diff --git a/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/AwsCrtV4aSignerSigningScopeTest.java b/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/AwsCrtV4aSignerSigningScopeTest.java new file mode 100644 index 000000000000..c6e02efe94a9 --- /dev/null +++ b/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/AwsCrtV4aSignerSigningScopeTest.java @@ -0,0 +1,48 @@ +/* + * 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.authcrt.signer.internal; + +import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute; +import software.amazon.awssdk.authcrt.signer.AwsCrtV4aSigner; +import software.amazon.awssdk.authcrt.signer.SignerTestUtils; +import software.amazon.awssdk.authcrt.signer.SigningTestCase; +import software.amazon.awssdk.core.interceptor.ExecutionAttributes; +import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.regions.RegionScope; + +public class AwsCrtV4aSignerSigningScopeTest extends BaseSigningScopeTest { + @Override + protected SdkHttpFullRequest signRequestWithScope(SigningTestCase testCase, RegionScope defaultRegionScope, + RegionScope regionScope) { + ExecutionAttributes executionAttributes = SignerTestUtils.buildBasicExecutionAttributes(testCase); + if (regionScope != null) { + executionAttributes.putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE, regionScope); + } + SdkHttpFullRequest request = testCase.requestBuilder.build(); + return AwsCrtV4aSigner.builder().defaultRegionScope(defaultRegionScope).build().sign(request, executionAttributes); + } + + @Override + protected SdkHttpFullRequest presignRequestWithScope(SigningTestCase testCase, RegionScope defaultRegionScope, + RegionScope regionScope) { + ExecutionAttributes executionAttributes = SignerTestUtils.buildBasicExecutionAttributes(testCase); + if (regionScope != null) { + executionAttributes.putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE, regionScope); + } + SdkHttpFullRequest request = testCase.requestBuilder.build(); + return AwsCrtV4aSigner.builder().defaultRegionScope(defaultRegionScope).build().presign(request, executionAttributes); + } +} diff --git a/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/BaseSigningScopeTest.java b/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/BaseSigningScopeTest.java new file mode 100644 index 000000000000..033cbbad48d7 --- /dev/null +++ b/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/BaseSigningScopeTest.java @@ -0,0 +1,112 @@ +/* + * 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.authcrt.signer.internal; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.authcrt.signer.SignerTestUtils; +import software.amazon.awssdk.authcrt.signer.SigningTestCase; +import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.regions.RegionScope; + +/** + * Functional tests for signing scope handling. These tests call the CRT native signer code. + */ +public abstract class BaseSigningScopeTest { + @Test + public void signing_withDefaultRegionScopeOnly_usesDefaultRegionScope() { + SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); + SdkHttpFullRequest signedRequest = signRequestWithScope(testCase, RegionScope.GLOBAL, null); + + String regionHeader = signedRequest.firstMatchingHeader("X-Amz-Region-Set").get(); + assertThat(regionHeader).isEqualTo(RegionScope.GLOBAL.id()); + } + + @Test + public void presigning_withDefaultRegionScopeOnly_usesDefaultRegionScope() { + SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); + SdkHttpFullRequest signedRequest = presignRequestWithScope(testCase, RegionScope.GLOBAL, null); + + assertThat(signedRequest.rawQueryParameters().get("X-Amz-Region-Set")).containsExactly(RegionScope.GLOBAL.id()); + } + + @Test + public void signing_withDefaultScopeAndExplicitScope_usesExplicitScope() { + SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); + + String expectdScope = "us-west-2"; + SdkHttpFullRequest signedRequest = signRequestWithScope(testCase, RegionScope.GLOBAL, RegionScope.of(expectdScope)); + + String regionHeader = signedRequest.firstMatchingHeader("X-Amz-Region-Set").get(); + assertThat(regionHeader).isEqualTo(expectdScope); + } + + @Test + public void presigning_withDefaultScopeAndExplicitScope_usesExplicitScope() { + SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); + + String expectdScope = "us-west-2"; + SdkHttpFullRequest signedRequest = presignRequestWithScope(testCase, RegionScope.GLOBAL, RegionScope.of(expectdScope)); + + assertThat(signedRequest.rawQueryParameters().get("X-Amz-Region-Set")).containsExactly(expectdScope); + } + + @Test + public void signing_withSigningRegionAndRegionScope_usesRegionScope() { + SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); + SdkHttpFullRequest signedRequest = signRequestWithScope(testCase, null, RegionScope.GLOBAL); + + String regionHeader = signedRequest.firstMatchingHeader("X-Amz-Region-Set").get(); + assertThat(regionHeader).isEqualTo(RegionScope.GLOBAL.id()); + } + + @Test + public void presigning_withSigningRegionAndRegionScope_usesRegionScope() { + SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); + SdkHttpFullRequest signedRequest = presignRequestWithScope(testCase, null, RegionScope.GLOBAL); + + assertThat(signedRequest.rawQueryParameters().get("X-Amz-Region-Set")).containsExactly(RegionScope.GLOBAL.id()); + } + + @Test + public void signing_withSigningRegionOnly_usesSigningRegion() { + SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); + + SdkHttpFullRequest signedRequest = signRequestWithScope(testCase, null, null); + + String regionHeader = signedRequest.firstMatchingHeader("X-Amz-Region-Set").get(); + assertThat(regionHeader).isEqualTo(Region.AWS_GLOBAL.id()); + } + + @Test + public void presigning_withSigningRegionOnly_usesSigningRegion() { + SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); + + SdkHttpFullRequest signedRequest = presignRequestWithScope(testCase, null, null); + + assertThat(signedRequest.rawQueryParameters().get("X-Amz-Region-Set")).containsExactly(Region.AWS_GLOBAL.id()); + } + + protected abstract SdkHttpFullRequest signRequestWithScope(SigningTestCase testCase, + RegionScope defaultRegionScope, + RegionScope regionScope); + + protected abstract SdkHttpFullRequest presignRequestWithScope(SigningTestCase testCase, + RegionScope defaultRegionScope, + RegionScope regionScope); +} diff --git a/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/SigningScopeTest.java b/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/SigningScopeTest.java deleted file mode 100644 index 45a52a493240..000000000000 --- a/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/SigningScopeTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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.authcrt.signer.internal; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertTrue; - -import java.util.List; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; -import software.amazon.awssdk.auth.signer.AwsSignerExecutionAttribute; -import software.amazon.awssdk.authcrt.signer.AwsCrtS3V4aSigner; -import software.amazon.awssdk.authcrt.signer.AwsCrtV4aSigner; -import software.amazon.awssdk.authcrt.signer.SignerTestUtils; -import software.amazon.awssdk.authcrt.signer.SigningTestCase; -import software.amazon.awssdk.core.interceptor.ExecutionAttributes; -import software.amazon.awssdk.http.SdkHttpFullRequest; -import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.regions.internal.util.RegionScope; - -/** - * Functional tests for the S3 specific Sigv4a signer. These tests call the CRT native signer code. - */ -@RunWith(MockitoJUnitRunner.class) -public class SigningScopeTest { - - @Test - public void signing_withSigningRegionAndRegionScope_usesRegionScope() { - SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); - SdkHttpFullRequest signedRequest = signRequestWithScope(testCase, RegionScope.GLOBAL.id()); - - String regionHeader = signedRequest.firstMatchingHeader("X-Amz-Region-Set").get(); - assertThat(regionHeader).isEqualTo(RegionScope.GLOBAL.id()); - } - - @Test - public void signing_withSigningRegionOnly_usesSigningRegion() { - SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); - ExecutionAttributes executionAttributes = SignerTestUtils.buildBasicExecutionAttributes(testCase); - SdkHttpFullRequest request = testCase.requestBuilder.build(); - SdkHttpFullRequest signedRequest = AwsCrtV4aSigner.create().sign(request, executionAttributes); - - String regionHeader = signedRequest.firstMatchingHeader("X-Amz-Region-Set").get(); - assertThat(regionHeader).isEqualTo(Region.AWS_GLOBAL.id()); - } - - @Test - public void signing_chunkedEncoding_regionalScope_present_overrides() { - SigningTestCase testCase = SignerTestUtils.createBasicChunkedSigningTestCase(); - SdkHttpFullRequest signedRequest = signRequestWithScope(testCase, RegionScope.GLOBAL.id()); - - String regionHeader = signedRequest.firstMatchingHeader("X-Amz-Region-Set").get(); - assertThat(regionHeader).isEqualTo(RegionScope.GLOBAL.id()); - } - - @Test - public void testS3Presigning() { - SigningTestCase testCase = SignerTestUtils.createBasicQuerySigningTestCase(); - - SdkHttpFullRequest signedRequest = presignRequestWithScope(testCase, RegionScope.GLOBAL.id()); - - List regionHeader = signedRequest.rawQueryParameters().get("X-Amz-Region-Set"); - assertThat(regionHeader.get(0)).isEqualTo(RegionScope.GLOBAL.id()); - } - - private SdkHttpFullRequest signRequestWithScope(SigningTestCase testCase, String regionScope) { - ExecutionAttributes executionAttributes = SignerTestUtils.buildBasicExecutionAttributes(testCase); - executionAttributes.putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE, - RegionScope.builder().regionScope(regionScope).build()); - - SdkHttpFullRequest request = testCase.requestBuilder.build(); - return AwsCrtS3V4aSigner.create().sign(request, executionAttributes); - } - - private SdkHttpFullRequest presignRequestWithScope(SigningTestCase testCase, String regionScope) { - ExecutionAttributes executionAttributes = SignerTestUtils.buildBasicExecutionAttributes(testCase); - executionAttributes.putAttribute(AwsSignerExecutionAttribute.SIGNING_REGION_SCOPE, - RegionScope.builder().regionScope(regionScope).build()); - SdkHttpFullRequest request = testCase.requestBuilder.build(); - return AwsCrtS3V4aSigner.create().presign(request, executionAttributes); - } - -} diff --git a/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java b/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java index 5981d1bb56fa..ec4afb2552e4 100644 --- a/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java +++ b/core/auth/src/main/java/software/amazon/awssdk/auth/signer/AwsSignerExecutionAttribute.java @@ -23,7 +23,7 @@ import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute; import software.amazon.awssdk.core.signer.Signer; import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.regions.internal.util.RegionScope; +import software.amazon.awssdk.regions.RegionScope; /** * AWS-specific signing attributes attached to the execution. This information is available to {@link ExecutionInterceptor}s and diff --git a/core/regions/src/main/java/software/amazon/awssdk/regions/internal/util/RegionScope.java b/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java similarity index 97% rename from core/regions/src/main/java/software/amazon/awssdk/regions/internal/util/RegionScope.java rename to core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java index 0becf7eb0606..8ac2a1a4f498 100644 --- a/core/regions/src/main/java/software/amazon/awssdk/regions/internal/util/RegionScope.java +++ b/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java @@ -13,13 +13,13 @@ * permissions and limitations under the License. */ -package software.amazon.awssdk.regions.internal.util; +package software.amazon.awssdk.regions; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.utils.Validate; import software.amazon.awssdk.utils.builder.CopyableBuilder; import software.amazon.awssdk.utils.builder.ToCopyableBuilder; @@ -45,7 +45,7 @@ *
  • 'eu-we*' - The wildcard must be its own segment
  • * */ -@SdkInternalApi +@SdkPublicApi public final class RegionScope implements ToCopyableBuilder { public static final RegionScope GLOBAL; diff --git a/core/regions/src/test/java/software/amazon/awssdk/regions/internal/RegionScopeTest.java b/core/regions/src/test/java/software/amazon/awssdk/regions/internal/RegionScopeTest.java index 6ce2646b15d6..e3105b5f56c2 100644 --- a/core/regions/src/test/java/software/amazon/awssdk/regions/internal/RegionScopeTest.java +++ b/core/regions/src/test/java/software/amazon/awssdk/regions/internal/RegionScopeTest.java @@ -22,7 +22,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import software.amazon.awssdk.regions.internal.util.RegionScope; +import software.amazon.awssdk.regions.RegionScope; @RunWith(Parameterized.class) public class RegionScopeTest { diff --git a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/handlers/EndpointAddressInterceptor.java b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/handlers/EndpointAddressInterceptor.java index 4433aaeda953..e67c67331ad6 100644 --- a/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/handlers/EndpointAddressInterceptor.java +++ b/services/s3/src/main/java/software/amazon/awssdk/services/s3/internal/handlers/EndpointAddressInterceptor.java @@ -25,7 +25,7 @@ import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute; import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute; import software.amazon.awssdk.http.SdkHttpRequest; -import software.amazon.awssdk.regions.internal.util.RegionScope; +import software.amazon.awssdk.regions.RegionScope; import software.amazon.awssdk.services.s3.S3Configuration; import software.amazon.awssdk.services.s3.internal.ConfiguredS3SdkHttpRequest; import software.amazon.awssdk.services.s3.internal.endpoints.S3EndpointResolverContext; From 159342ac6efe441b3a53ed2febcd08a4af5f70a1 Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Tue, 15 Feb 2022 11:27:15 -0800 Subject: [PATCH 2/3] Remove unnecessary builder --- .../amazon/awssdk/regions/RegionScope.java | 46 ++----------------- 1 file changed, 4 insertions(+), 42 deletions(-) diff --git a/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java b/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java index 8ac2a1a4f498..cf6fdd91c985 100644 --- a/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java +++ b/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java @@ -21,8 +21,6 @@ import java.util.regex.Pattern; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.utils.Validate; -import software.amazon.awssdk.utils.builder.CopyableBuilder; -import software.amazon.awssdk.utils.builder.ToCopyableBuilder; /** * This class represents the concept of a regional scope, in form of a string with possible wildcards. @@ -46,7 +44,7 @@ * */ @SdkPublicApi -public final class RegionScope implements ToCopyableBuilder { +public final class RegionScope { public static final RegionScope GLOBAL; @@ -60,21 +58,11 @@ public final class RegionScope implements ToCopyableBuilder { - private String regionScope; - - private Builder() { - } - - public void setRegionScope(String regionScope) { - regionScope(regionScope); - } - - public Builder regionScope(String regionScope) { - this.regionScope = regionScope; - return this; - } - - @Override - public RegionScope build() { - return new RegionScope(this); - } - } } From 837ac0a223990644d59b9af8d533138825adc9a6 Mon Sep 17 00:00:00 2001 From: Dongie Agnir Date: Tue, 15 Feb 2022 12:49:30 -0800 Subject: [PATCH 3/3] Change of() to create() --- .../awssdk/authcrt/signer/internal/BaseSigningScopeTest.java | 5 +++-- .../java/software/amazon/awssdk/regions/RegionScope.java | 4 ++-- .../amazon/awssdk/regions/internal/RegionScopeTest.java | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/BaseSigningScopeTest.java b/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/BaseSigningScopeTest.java index 033cbbad48d7..51ac8df6fb8e 100644 --- a/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/BaseSigningScopeTest.java +++ b/core/auth-crt/src/test/java/software/amazon/awssdk/authcrt/signer/internal/BaseSigningScopeTest.java @@ -50,7 +50,7 @@ public void signing_withDefaultScopeAndExplicitScope_usesExplicitScope() { SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); String expectdScope = "us-west-2"; - SdkHttpFullRequest signedRequest = signRequestWithScope(testCase, RegionScope.GLOBAL, RegionScope.of(expectdScope)); + SdkHttpFullRequest signedRequest = signRequestWithScope(testCase, RegionScope.GLOBAL, RegionScope.create(expectdScope)); String regionHeader = signedRequest.firstMatchingHeader("X-Amz-Region-Set").get(); assertThat(regionHeader).isEqualTo(expectdScope); @@ -61,7 +61,8 @@ public void presigning_withDefaultScopeAndExplicitScope_usesExplicitScope() { SigningTestCase testCase = SignerTestUtils.createBasicHeaderSigningTestCase(); String expectdScope = "us-west-2"; - SdkHttpFullRequest signedRequest = presignRequestWithScope(testCase, RegionScope.GLOBAL, RegionScope.of(expectdScope)); + SdkHttpFullRequest signedRequest = presignRequestWithScope(testCase, RegionScope.GLOBAL, + RegionScope.create(expectdScope)); assertThat(signedRequest.rawQueryParameters().get("X-Amz-Region-Set")).containsExactly(expectdScope); } diff --git a/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java b/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java index cf6fdd91c985..5f94b71d9a9a 100644 --- a/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java +++ b/core/regions/src/main/java/software/amazon/awssdk/regions/RegionScope.java @@ -53,7 +53,7 @@ public final class RegionScope { //Pattern must be compiled when static scope is created static { REGION_SCOPE_PATTERN = Pattern.compile("^([a-z0-9-])*([*]?)$"); - GLOBAL = RegionScope.of("*"); + GLOBAL = RegionScope.create("*"); } private final String regionScope; @@ -75,7 +75,7 @@ public String id() { * * @param value See class documentation {@link RegionScope} for allowed values. */ - public static RegionScope of(String value) { + public static RegionScope create(String value) { return new RegionScope(value); } diff --git a/core/regions/src/test/java/software/amazon/awssdk/regions/internal/RegionScopeTest.java b/core/regions/src/test/java/software/amazon/awssdk/regions/internal/RegionScopeTest.java index e3105b5f56c2..ca7ae2d8d635 100644 --- a/core/regions/src/test/java/software/amazon/awssdk/regions/internal/RegionScopeTest.java +++ b/core/regions/src/test/java/software/amazon/awssdk/regions/internal/RegionScopeTest.java @@ -36,7 +36,7 @@ public RegionScopeTest(TestCase testCase) { @Test public void validateRegionScope() { try { - RegionScope regionScope = RegionScope.of(testCase.regionScope); + RegionScope regionScope = RegionScope.create(testCase.regionScope); assertThat(regionScope.id()).isEqualTo(testCase.regionScope); } catch (RuntimeException e) { if (testCase.expectedException == null) {