From 8b272e808f0b15adb22bdaab7291eb35e4b8df9c Mon Sep 17 00:00:00 2001 From: 0marperez Date: Fri, 5 Jan 2024 11:04:24 -0500 Subject: [PATCH 01/10] Change default auth scheme to SIGV4A for S3 --- .../s3/ClientConfigIntegration.kt | 17 +++++-- .../s3/ClientConfigIntegrationTest.kt | 47 +++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegrationTest.kt diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt index 5926c47e98e..3df67e293ea 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt @@ -6,6 +6,7 @@ package aws.sdk.kotlin.codegen.customization.s3 import software.amazon.smithy.kotlin.codegen.KotlinSettings import software.amazon.smithy.kotlin.codegen.core.CodegenContext +import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes import software.amazon.smithy.kotlin.codegen.integration.AppendingSectionWriter import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration import software.amazon.smithy.kotlin.codegen.integration.SectionWriterBinding @@ -14,13 +15,14 @@ import software.amazon.smithy.kotlin.codegen.model.buildSymbol import software.amazon.smithy.kotlin.codegen.model.expectShape import software.amazon.smithy.kotlin.codegen.rendering.ServiceClientGenerator import software.amazon.smithy.kotlin.codegen.rendering.util.ConfigProperty +import software.amazon.smithy.kotlin.codegen.rendering.util.RuntimeConfigProperty import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.transform.ModelTransformer import software.amazon.smithy.rulesengine.traits.ClientContextParamsTrait /** - * Integration to inject s3-related client config builtins for endpoint resolution in place of the corresponding client + * Integration to inject s3-related client config builtins for endpoint resolution & multi-region access points in place of the corresponding client * context params. */ class ClientConfigIntegration : KotlinIntegration { @@ -54,14 +56,22 @@ class ClientConfigIntegration : KotlinIntegration { """.trimIndent() } - // FIXME: default signer doesn't yet implement sigv4a, default to mrap OFF until it does + // FIXME: default signer doesn't yet implement sigv4a val DisableMrapProp: ConfigProperty = ConfigProperty { name = "disableMrap" - useSymbolWithNullableBuilder(KotlinTypes.Boolean, "true") + useSymbolWithNullableBuilder(KotlinTypes.Boolean, "false") documentation = """ Flag to disable [S3 multi-region access points](https://docs.aws.amazon.com/AmazonS3/latest/userguide/MultiRegionAccessPoints.html). """.trimIndent() } + + val AuthSchemes = RuntimeConfigProperty + .AuthSchemes + .toBuilder() + .apply { + symbol = KotlinTypes.Collections.list(RuntimeTypes.Auth.HttpAuth.AuthScheme, default = "listOf(${RuntimeTypes.Auth.HttpAuthAws.SigV4AsymmetricAuthScheme}(${RuntimeTypes.Auth.Signing.AwsSigningStandard.DefaultAwsSigner}))") + } + .build() } override fun preprocessModel(model: Model, settings: KotlinSettings): Model { @@ -87,6 +97,7 @@ class ClientConfigIntegration : KotlinIntegration { ForcePathStyleProp, UseArnRegionProp, DisableMrapProp, + AuthSchemes, ) override val sectionWriters: List diff --git a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegrationTest.kt b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegrationTest.kt new file mode 100644 index 00000000000..c3c619a43c2 --- /dev/null +++ b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegrationTest.kt @@ -0,0 +1,47 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.sdk.kotlin.codegen.customization.s3 + +import aws.sdk.kotlin.codegen.testutil.model +import software.amazon.smithy.kotlin.codegen.core.KotlinWriter +import software.amazon.smithy.kotlin.codegen.rendering.ServiceClientConfigGenerator +import software.amazon.smithy.kotlin.codegen.test.TestModelDefault +import software.amazon.smithy.kotlin.codegen.test.newTestContext +import software.amazon.smithy.kotlin.codegen.test.shouldContainOnlyOnceWithDiff +import software.amazon.smithy.kotlin.codegen.test.toRenderingContext +import kotlin.test.Test + +class ClientConfigIntegrationTest { + @Test + fun testRenderAuthSchemeProperty() { + val model = model("S3") + val ctx = model.newTestContext("S3") + val writer = KotlinWriter(TestModelDefault.NAMESPACE) + val serviceShape = model.serviceShapes.single() + val renderingCtx = ctx + .toRenderingContext(writer, serviceShape) + .copy(integrations = listOf(ClientConfigIntegration())) + + val generator = ServiceClientConfigGenerator(serviceShape, detectDefaultProps = false) + generator.render(renderingCtx, writer) + val contents = writer.toString() + + val expectedImmutableProp = """ + override val authSchemes: kotlin.collections.List = builder.authSchemes + """.trimIndent() + contents.shouldContainOnlyOnceWithDiff(expectedImmutableProp) + + val expectedBuilderProp = """ + /** + * Register new or override default [AuthScheme]s configured for this client. By default, the set + * of auth schemes configured comes from the service model. An auth scheme configured explicitly takes + * precedence over the defaults and can be used to customize identity resolution and signing for specific + * authentication schemes. + */ + override var authSchemes: kotlin.collections.List = listOf(aws.smithy.kotlin.runtime.http.auth.SigV4AsymmetricAuthScheme(aws.smithy.kotlin.runtime.auth.awssigning.DefaultAwsSigner)) + """.replaceIndent(" ") + contents.shouldContainOnlyOnceWithDiff(expectedBuilderProp) + } +} From 3e18f6920a07f46022d18a1c9c289a2171e5fbdb Mon Sep 17 00:00:00 2001 From: 0marperez Date: Fri, 12 Jan 2024 16:22:03 -0500 Subject: [PATCH 02/10] Pushing to help solve cloudfront issue --- .../UnsupportedSigningAlgorithmInterceptor.kt | 28 ++++++++ .../aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt | 1 + .../SigV4AsymmetricTraitCustomization.kt | 62 ++++++++++++++++++ .../s3/ClientConfigIntegration.kt | 11 ---- .../UnsupportedSigningAlgorithmIntegration.kt | 37 +++++++++++ ...tlin.codegen.integration.KotlinIntegration | 2 + .../SigV4AsymmetricTraitCustomizationTest.kt | 64 +++++++++++++++++++ .../s3/ClientConfigIntegrationTest.kt | 47 -------------- .../e2eTest/src/MultRegionAccessPointTest.kt | 42 ++++++++++++ 9 files changed, 236 insertions(+), 58 deletions(-) create mode 100644 aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt create mode 100644 codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt create mode 100644 codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt create mode 100644 codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt delete mode 100644 codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegrationTest.kt create mode 100644 services/s3/e2eTest/src/MultRegionAccessPointTest.kt diff --git a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt new file mode 100644 index 00000000000..f664e92a4fd --- /dev/null +++ b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt @@ -0,0 +1,28 @@ +package aws.sdk.kotlin.runtime.http.interceptors + +import aws.sdk.kotlin.runtime.InternalSdkApi +import aws.smithy.kotlin.runtime.auth.awssigning.UnsupportedSigningAlgorithm +import aws.smithy.kotlin.runtime.client.ResponseInterceptorContext +import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.http.response.HttpResponse + +// TODO: Remove me once sigV4a is supported by default AWS signer +/** + * Looks for an unsupported signing algorithm error caused by sigV4a. + * If so it sends users to a page in the AWS SDK for Kotlin documentation on how to fix it. + */ +@InternalSdkApi +public class UnsupportedSigningAlgorithmInterceptor : HttpInterceptor { + override suspend fun modifyBeforeCompletion(context: ResponseInterceptorContext): Result { + context.response.exceptionOrNull()?.let { + if (it is UnsupportedSigningAlgorithm && it.isSigV4a) { + throw UnsupportedSigningAlgorithm( + it.message + " Please follow the AWS SDK for Kotlin developer guide to set it up with the CRT signer. **LINK TO GUIDE**", + true, + ) + } + } + return super.modifyBeforeCompletion(context) + } +} \ No newline at end of file diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt index 438eef7a95e..e36fb00cd69 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/AwsRuntimeTypes.kt @@ -59,6 +59,7 @@ object AwsRuntimeTypes { object Http : RuntimeTypePackage(AwsKotlinDependency.AWS_HTTP) { object Interceptors : RuntimeTypePackage(AwsKotlinDependency.AWS_HTTP, "interceptors") { val AddUserAgentMetadataInterceptor = symbol("AddUserAgentMetadataInterceptor") + val UnsupportedSigningAlgorithmInterceptor = symbol("UnsupportedSigningAlgorithmInterceptor") } object Retries { diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt new file mode 100644 index 00000000000..eb0a95cb517 --- /dev/null +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt @@ -0,0 +1,62 @@ +package aws.sdk.kotlin.codegen.customization + +import aws.sdk.kotlin.codegen.sdkId +import software.amazon.smithy.aws.traits.ServiceTrait +import software.amazon.smithy.aws.traits.auth.SigV4ATrait +import software.amazon.smithy.aws.traits.auth.SigV4Trait +import software.amazon.smithy.kotlin.codegen.KotlinSettings +import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration +import software.amazon.smithy.kotlin.codegen.model.expectShape +import software.amazon.smithy.kotlin.codegen.model.getTrait +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.shapes.ServiceShape +import software.amazon.smithy.model.shapes.ShapeId +import software.amazon.smithy.model.traits.AuthTrait +import software.amazon.smithy.model.transform.ModelTransformer + +/** + * Adds the sigV4A trait to S3 and event bridge. These services don't model their sigV4A usage + */ +class SigV4AsymmetricTraitCustomization : KotlinIntegration { + override val order: Byte = -60 + + override fun enabledForService(model: Model, settings: KotlinSettings): Boolean { + val sdkId = model.expectShape(settings.service).sdkId.lowercase() + return sdkId == "s3" || sdkId == "eventbridge" //|| sdkId == "cloudfrontkeyvaluestore" + } + + override fun preprocessModel(model: Model, settings: KotlinSettings): Model { + return ModelTransformer.create().mapShapes(model) { shape -> + if (shape.isServiceShape) { + val authSchemes: MutableSet = + (shape as ServiceShape).getTrait()?.let { + val modeledAuthSchemes = it.valueSet + modeledAuthSchemes.add( SigV4ATrait.ID) + modeledAuthSchemes.add(SigV4Trait.ID) + modeledAuthSchemes + } ?: mutableSetOf(SigV4ATrait.ID, SigV4Trait.ID) + + // SigV4A trait name is based on these rules: https://smithy.io/2.0/aws/aws-auth.html?highlight=sigv4#aws-auth-sigv4a-trait + val sigV4ATraitNameProperty = + shape.getTrait()?.let { it.arnNamespace } + ?: shape.getTrait()?.let { it.name } + ?: throw Exception("Service (${shape.id}) is missing ARN namespace. Please report to AWS.") + + shape + .toBuilder() + .addTrait( + SigV4ATrait + .builder() + .name(sigV4ATraitNameProperty) + .build() + ) + .addTrait( + AuthTrait(authSchemes) + ) + .build() + } else { + shape + } + } + } +} \ No newline at end of file diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt index 3df67e293ea..1236814f06a 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt @@ -6,7 +6,6 @@ package aws.sdk.kotlin.codegen.customization.s3 import software.amazon.smithy.kotlin.codegen.KotlinSettings import software.amazon.smithy.kotlin.codegen.core.CodegenContext -import software.amazon.smithy.kotlin.codegen.core.RuntimeTypes import software.amazon.smithy.kotlin.codegen.integration.AppendingSectionWriter import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration import software.amazon.smithy.kotlin.codegen.integration.SectionWriterBinding @@ -15,7 +14,6 @@ import software.amazon.smithy.kotlin.codegen.model.buildSymbol import software.amazon.smithy.kotlin.codegen.model.expectShape import software.amazon.smithy.kotlin.codegen.rendering.ServiceClientGenerator import software.amazon.smithy.kotlin.codegen.rendering.util.ConfigProperty -import software.amazon.smithy.kotlin.codegen.rendering.util.RuntimeConfigProperty import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.ServiceShape import software.amazon.smithy.model.transform.ModelTransformer @@ -64,14 +62,6 @@ class ClientConfigIntegration : KotlinIntegration { Flag to disable [S3 multi-region access points](https://docs.aws.amazon.com/AmazonS3/latest/userguide/MultiRegionAccessPoints.html). """.trimIndent() } - - val AuthSchemes = RuntimeConfigProperty - .AuthSchemes - .toBuilder() - .apply { - symbol = KotlinTypes.Collections.list(RuntimeTypes.Auth.HttpAuth.AuthScheme, default = "listOf(${RuntimeTypes.Auth.HttpAuthAws.SigV4AsymmetricAuthScheme}(${RuntimeTypes.Auth.Signing.AwsSigningStandard.DefaultAwsSigner}))") - } - .build() } override fun preprocessModel(model: Model, settings: KotlinSettings): Model { @@ -97,7 +87,6 @@ class ClientConfigIntegration : KotlinIntegration { ForcePathStyleProp, UseArnRegionProp, DisableMrapProp, - AuthSchemes, ) override val sectionWriters: List diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt new file mode 100644 index 00000000000..714ad027151 --- /dev/null +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt @@ -0,0 +1,37 @@ +package aws.sdk.kotlin.codegen.customization.s3 + +import aws.sdk.kotlin.codegen.AwsRuntimeTypes +import software.amazon.smithy.kotlin.codegen.KotlinSettings +import software.amazon.smithy.kotlin.codegen.core.KotlinWriter +import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration +import software.amazon.smithy.kotlin.codegen.model.expectShape +import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolGenerator +import software.amazon.smithy.kotlin.codegen.rendering.protocol.ProtocolMiddleware +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.shapes.OperationShape +import software.amazon.smithy.model.shapes.ServiceShape + +/** + * Registers an interceptor for S3. + * See: [aws.sdk.kotlin.runtime.http.interceptors.UnsupportedSigningAlgorithmInterceptor] + */ +class UnsupportedSigningAlgorithmIntegration : KotlinIntegration { + override fun enabledForService(model: Model, settings: KotlinSettings): Boolean = + model.expectShape(settings.service).isS3 + + override fun customizeMiddleware( + ctx: ProtocolGenerator.GenerationContext, + resolved: List, + ): List = resolved + UnsupportedSigningAlgorithmMiddleware +} + +private val UnsupportedSigningAlgorithmMiddleware = object : ProtocolMiddleware { + override val name: String = "UnsupportedSigningAlgorithmMiddleware" + + override fun render(ctx: ProtocolGenerator.GenerationContext, op: OperationShape, writer: KotlinWriter) { + writer.write( + "op.interceptors.add(#T())", + AwsRuntimeTypes.Http.Interceptors.UnsupportedSigningAlgorithmInterceptor, + ) + } +} \ No newline at end of file diff --git a/codegen/aws-sdk-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration b/codegen/aws-sdk-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration index 9c1bcbd6748..f0f4c2e49d6 100644 --- a/codegen/aws-sdk-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration +++ b/codegen/aws-sdk-codegen/src/main/resources/META-INF/services/software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration @@ -36,3 +36,5 @@ aws.sdk.kotlin.codegen.customization.route53.TrimResourcePrefix aws.sdk.kotlin.codegen.customization.route53.ChangeResourceRecordSetsUnmarshallingIntegration aws.sdk.kotlin.codegen.customization.ec2.EC2MakePrimitivesOptional aws.sdk.kotlin.codegen.customization.RemoveDefaults +aws.sdk.kotlin.codegen.customization.s3.UnsupportedSigningAlgorithmIntegration +aws.sdk.kotlin.codegen.customization.SigV4AsymmetricTraitCustomization diff --git a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt new file mode 100644 index 00000000000..9ec42f01219 --- /dev/null +++ b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt @@ -0,0 +1,64 @@ +package aws.sdk.kotlin.codegen.customization + +import software.amazon.smithy.aws.traits.auth.SigV4ATrait +import software.amazon.smithy.aws.traits.auth.SigV4Trait +import software.amazon.smithy.kotlin.codegen.KotlinSettings +import software.amazon.smithy.kotlin.codegen.model.getTrait +import software.amazon.smithy.kotlin.codegen.test.toSmithyModel +import software.amazon.smithy.model.shapes.ShapeId +import software.amazon.smithy.model.traits.AuthTrait +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class SigV4AsymmetricTraitCustomizationTest { + private val testModel = """ + namespace smithy.example + + use aws.protocols#awsJson1_0 + use aws.auth#sigv4 + + @awsJson1_0 + @sigv4(name: "example-signing-name") + service Example { + version: "1.0.0", + operations: [GetFoo] + } + + operation GetFoo { + input: GetFooInput + } + + operation GetNotFoo { + input: GetFooInput + } + + structure GetFooInput { + payload: String + } + """.toSmithyModel() + + @Test + fun testCustomizationAppliedCorrectly() { + val customizedModel = SigV4AsymmetricTraitCustomization() + .preprocessModel( + testModel, + KotlinSettings( + ShapeId.from("smithy.example#Example"), + KotlinSettings.PackageSettings("example", "1.0.0"), + "example" + ) + ) + + assertTrue(customizedModel.appliedTraits.contains(SigV4ATrait.ID)) + assertTrue(customizedModel.appliedTraits.contains(AuthTrait.ID)) + + val service = customizedModel.getShape(customizedModel.serviceShapes.first().id).get() + val sigV4ATrait = service.getTrait() as SigV4ATrait + val authTrait = service.getTrait() as AuthTrait + + assertEquals("example-signing-name", sigV4ATrait.name) + assertTrue(authTrait.valueSet.contains(SigV4Trait.ID)) + assertTrue(authTrait.valueSet.contains(SigV4ATrait.ID)) + } +} \ No newline at end of file diff --git a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegrationTest.kt b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegrationTest.kt deleted file mode 100644 index c3c619a43c2..00000000000 --- a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegrationTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package aws.sdk.kotlin.codegen.customization.s3 - -import aws.sdk.kotlin.codegen.testutil.model -import software.amazon.smithy.kotlin.codegen.core.KotlinWriter -import software.amazon.smithy.kotlin.codegen.rendering.ServiceClientConfigGenerator -import software.amazon.smithy.kotlin.codegen.test.TestModelDefault -import software.amazon.smithy.kotlin.codegen.test.newTestContext -import software.amazon.smithy.kotlin.codegen.test.shouldContainOnlyOnceWithDiff -import software.amazon.smithy.kotlin.codegen.test.toRenderingContext -import kotlin.test.Test - -class ClientConfigIntegrationTest { - @Test - fun testRenderAuthSchemeProperty() { - val model = model("S3") - val ctx = model.newTestContext("S3") - val writer = KotlinWriter(TestModelDefault.NAMESPACE) - val serviceShape = model.serviceShapes.single() - val renderingCtx = ctx - .toRenderingContext(writer, serviceShape) - .copy(integrations = listOf(ClientConfigIntegration())) - - val generator = ServiceClientConfigGenerator(serviceShape, detectDefaultProps = false) - generator.render(renderingCtx, writer) - val contents = writer.toString() - - val expectedImmutableProp = """ - override val authSchemes: kotlin.collections.List = builder.authSchemes - """.trimIndent() - contents.shouldContainOnlyOnceWithDiff(expectedImmutableProp) - - val expectedBuilderProp = """ - /** - * Register new or override default [AuthScheme]s configured for this client. By default, the set - * of auth schemes configured comes from the service model. An auth scheme configured explicitly takes - * precedence over the defaults and can be used to customize identity resolution and signing for specific - * authentication schemes. - */ - override var authSchemes: kotlin.collections.List = listOf(aws.smithy.kotlin.runtime.http.auth.SigV4AsymmetricAuthScheme(aws.smithy.kotlin.runtime.auth.awssigning.DefaultAwsSigner)) - """.replaceIndent(" ") - contents.shouldContainOnlyOnceWithDiff(expectedBuilderProp) - } -} diff --git a/services/s3/e2eTest/src/MultRegionAccessPointTest.kt b/services/s3/e2eTest/src/MultRegionAccessPointTest.kt new file mode 100644 index 00000000000..cebcb1ff6be --- /dev/null +++ b/services/s3/e2eTest/src/MultRegionAccessPointTest.kt @@ -0,0 +1,42 @@ +package aws.sdk.kotlin.e2etest + +import aws.sdk.kotlin.runtime.auth.credentials.ProcessCredentialsProvider +import aws.sdk.kotlin.services.s3.S3Client +import aws.sdk.kotlin.services.s3.model.PutObjectRequest +import aws.smithy.kotlin.runtime.InternalApi +import aws.smithy.kotlin.runtime.auth.awssigning.UnsupportedSigningAlgorithm +import kotlinx.coroutines.test.runTest +import org.junit.jupiter.api.assertThrows +import kotlin.test.Test +import kotlin.test.assertEquals + +class MultRegionAccessPointTest { + @OptIn(InternalApi::class) + @Test + fun testUnsupportedSigningAlgorithm() = runTest { + val client = S3Client { + region = "us-east-1" + credentialsProvider = ProcessCredentialsProvider("isengardcli credentials --awscli aoperez@amazon.com --role Admin") + } + + + val exception = assertThrows { + client.putObject( + PutObjectRequest { + bucket = "..." + key = "thisIsATestForMrap" + } + ) + } + + assertEquals( + "SIGV4_ASYMMETRIC support is not yet implemented for the default signer. Please follow the AWS SDK for Kotlin developer guide to set it up with the CRT signer. **LINK TO GUIDE**", + exception.message + ) + } + + @Test + fun testMultiRegionAccessPointOperation() = runTest { + // TODO + } +} \ No newline at end of file From 1b5daa5f3cff6a55084ffdc869490e86ed1de4e6 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Fri, 12 Jan 2024 17:34:12 -0500 Subject: [PATCH 03/10] Fix sdk ID --- .../customization/SigV4AsymmetricTraitCustomization.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt index eb0a95cb517..8cf0df34db6 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt @@ -21,8 +21,8 @@ class SigV4AsymmetricTraitCustomization : KotlinIntegration { override val order: Byte = -60 override fun enabledForService(model: Model, settings: KotlinSettings): Boolean { - val sdkId = model.expectShape(settings.service).sdkId.lowercase() - return sdkId == "s3" || sdkId == "eventbridge" //|| sdkId == "cloudfrontkeyvaluestore" + val sdkId = model.expectShape(settings.service).sdkId.lowercase() // FIXME don't use sdkId + return sdkId == "s3" || sdkId == "eventbridge" || sdkId == "cloudfront keyvaluestore" } override fun preprocessModel(model: Model, settings: KotlinSettings): Model { From 1dbcf5a461a114f8d22a6b9f1cdddeb3421836e4 Mon Sep 17 00:00:00 2001 From: Matas Lauzadis Date: Tue, 16 Jan 2024 15:12:41 -0500 Subject: [PATCH 04/10] ktlint --- .../UnsupportedSigningAlgorithmInterceptor.kt | 6 +++- .../SigV4AsymmetricTraitCustomization.kt | 29 ++++++++++--------- .../UnsupportedSigningAlgorithmIntegration.kt | 6 +++- .../SigV4AsymmetricTraitCustomizationTest.kt | 10 +++++-- .../e2eTest/src/MultRegionAccessPointTest.kt | 11 ++++--- 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt index f664e92a4fd..4c32581a394 100644 --- a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt +++ b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt @@ -1,3 +1,7 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ package aws.sdk.kotlin.runtime.http.interceptors import aws.sdk.kotlin.runtime.InternalSdkApi @@ -25,4 +29,4 @@ public class UnsupportedSigningAlgorithmInterceptor : HttpInterceptor { } return super.modifyBeforeCompletion(context) } -} \ No newline at end of file +} diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt index 8cf0df34db6..2f64adf1e0f 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt @@ -1,3 +1,7 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ package aws.sdk.kotlin.codegen.customization import aws.sdk.kotlin.codegen.sdkId @@ -25,22 +29,22 @@ class SigV4AsymmetricTraitCustomization : KotlinIntegration { return sdkId == "s3" || sdkId == "eventbridge" || sdkId == "cloudfront keyvaluestore" } - override fun preprocessModel(model: Model, settings: KotlinSettings): Model { - return ModelTransformer.create().mapShapes(model) { shape -> + override fun preprocessModel(model: Model, settings: KotlinSettings): Model = ModelTransformer.create() + .mapShapes(model) { shape -> if (shape.isServiceShape) { val authSchemes: MutableSet = (shape as ServiceShape).getTrait()?.let { - val modeledAuthSchemes = it.valueSet - modeledAuthSchemes.add( SigV4ATrait.ID) - modeledAuthSchemes.add(SigV4Trait.ID) - modeledAuthSchemes - } ?: mutableSetOf(SigV4ATrait.ID, SigV4Trait.ID) + val modeledAuthSchemes = it.valueSet + modeledAuthSchemes.add(SigV4ATrait.ID) + modeledAuthSchemes.add(SigV4Trait.ID) + modeledAuthSchemes + } ?: mutableSetOf(SigV4ATrait.ID, SigV4Trait.ID) // SigV4A trait name is based on these rules: https://smithy.io/2.0/aws/aws-auth.html?highlight=sigv4#aws-auth-sigv4a-trait val sigV4ATraitNameProperty = shape.getTrait()?.let { it.arnNamespace } - ?: shape.getTrait()?.let { it.name } - ?: throw Exception("Service (${shape.id}) is missing ARN namespace. Please report to AWS.") + ?: shape.getTrait()?.let { it.name } + ?: throw Exception("Service (${shape.id}) is missing ARN namespace. Please report to AWS.") shape .toBuilder() @@ -48,15 +52,14 @@ class SigV4AsymmetricTraitCustomization : KotlinIntegration { SigV4ATrait .builder() .name(sigV4ATraitNameProperty) - .build() + .build(), ) .addTrait( - AuthTrait(authSchemes) + AuthTrait(authSchemes), ) .build() } else { shape } } - } -} \ No newline at end of file +} diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt index 714ad027151..c9832f9c30f 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt @@ -1,3 +1,7 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ package aws.sdk.kotlin.codegen.customization.s3 import aws.sdk.kotlin.codegen.AwsRuntimeTypes @@ -34,4 +38,4 @@ private val UnsupportedSigningAlgorithmMiddleware = object : ProtocolMiddleware AwsRuntimeTypes.Http.Interceptors.UnsupportedSigningAlgorithmInterceptor, ) } -} \ No newline at end of file +} diff --git a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt index 9ec42f01219..bdab616f362 100644 --- a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt +++ b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt @@ -1,3 +1,7 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ package aws.sdk.kotlin.codegen.customization import software.amazon.smithy.aws.traits.auth.SigV4ATrait @@ -46,8 +50,8 @@ class SigV4AsymmetricTraitCustomizationTest { KotlinSettings( ShapeId.from("smithy.example#Example"), KotlinSettings.PackageSettings("example", "1.0.0"), - "example" - ) + "example", + ), ) assertTrue(customizedModel.appliedTraits.contains(SigV4ATrait.ID)) @@ -61,4 +65,4 @@ class SigV4AsymmetricTraitCustomizationTest { assertTrue(authTrait.valueSet.contains(SigV4Trait.ID)) assertTrue(authTrait.valueSet.contains(SigV4ATrait.ID)) } -} \ No newline at end of file +} diff --git a/services/s3/e2eTest/src/MultRegionAccessPointTest.kt b/services/s3/e2eTest/src/MultRegionAccessPointTest.kt index cebcb1ff6be..bcc04831505 100644 --- a/services/s3/e2eTest/src/MultRegionAccessPointTest.kt +++ b/services/s3/e2eTest/src/MultRegionAccessPointTest.kt @@ -1,3 +1,7 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ package aws.sdk.kotlin.e2etest import aws.sdk.kotlin.runtime.auth.credentials.ProcessCredentialsProvider @@ -19,19 +23,18 @@ class MultRegionAccessPointTest { credentialsProvider = ProcessCredentialsProvider("isengardcli credentials --awscli aoperez@amazon.com --role Admin") } - val exception = assertThrows { client.putObject( PutObjectRequest { bucket = "..." key = "thisIsATestForMrap" - } + }, ) } assertEquals( "SIGV4_ASYMMETRIC support is not yet implemented for the default signer. Please follow the AWS SDK for Kotlin developer guide to set it up with the CRT signer. **LINK TO GUIDE**", - exception.message + exception.message, ) } @@ -39,4 +42,4 @@ class MultRegionAccessPointTest { fun testMultiRegionAccessPointOperation() = runTest { // TODO } -} \ No newline at end of file +} From 15d05ac1988328ce3de3bfde12b8557d03532f05 Mon Sep 17 00:00:00 2001 From: 0marperez Date: Tue, 16 Jan 2024 17:33:19 -0500 Subject: [PATCH 05/10] Fixed signing region bug --- .../UnsupportedSigningAlgorithmInterceptor.kt | 12 ++- .../SigV4AsymmetricTraitCustomization.kt | 73 ++++++++----------- .../UnsupportedSigningAlgorithmIntegration.kt | 9 ++- .../SigV4AsymmetricTraitCustomizationTest.kt | 25 +++++-- .../e2eTest/src/MultRegionAccessPointTest.kt | 42 ----------- 5 files changed, 63 insertions(+), 98 deletions(-) delete mode 100644 services/s3/e2eTest/src/MultRegionAccessPointTest.kt diff --git a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt index f664e92a4fd..4d0de0611e6 100644 --- a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt +++ b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt @@ -1,3 +1,7 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ package aws.sdk.kotlin.runtime.http.interceptors import aws.sdk.kotlin.runtime.InternalSdkApi @@ -7,10 +11,10 @@ import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor import aws.smithy.kotlin.runtime.http.request.HttpRequest import aws.smithy.kotlin.runtime.http.response.HttpResponse -// TODO: Remove me once sigV4a is supported by default AWS signer +// FIXME: Remove this once sigV4a is supported by default AWS signer /** * Looks for an unsupported signing algorithm error caused by sigV4a. - * If so it sends users to a page in the AWS SDK for Kotlin documentation on how to fix it. + * If so it sends users to a section in the AWS SDK for Kotlin documentation on how to fix it. */ @InternalSdkApi public class UnsupportedSigningAlgorithmInterceptor : HttpInterceptor { @@ -18,11 +22,11 @@ public class UnsupportedSigningAlgorithmInterceptor : HttpInterceptor { context.response.exceptionOrNull()?.let { if (it is UnsupportedSigningAlgorithm && it.isSigV4a) { throw UnsupportedSigningAlgorithm( - it.message + " Please follow the AWS SDK for Kotlin developer guide to set it up with the CRT signer. **LINK TO GUIDE**", + it.message!!, // TODO: Add a message and link pointing to AWS SDK for Kotlin developer guide true, ) } } return super.modifyBeforeCompletion(context) } -} \ No newline at end of file +} diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt index 8cf0df34db6..b1f94ee64ca 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt @@ -1,62 +1,51 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ package aws.sdk.kotlin.codegen.customization -import aws.sdk.kotlin.codegen.sdkId import software.amazon.smithy.aws.traits.ServiceTrait import software.amazon.smithy.aws.traits.auth.SigV4ATrait import software.amazon.smithy.aws.traits.auth.SigV4Trait import software.amazon.smithy.kotlin.codegen.KotlinSettings import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration -import software.amazon.smithy.kotlin.codegen.model.expectShape -import software.amazon.smithy.kotlin.codegen.model.getTrait +import software.amazon.smithy.kotlin.codegen.model.expectTrait import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.ServiceShape -import software.amazon.smithy.model.shapes.ShapeId import software.amazon.smithy.model.traits.AuthTrait import software.amazon.smithy.model.transform.ModelTransformer +// FIXME: Remove services from customization or customization entirely when/if services add sigV4a trait to models /** - * Adds the sigV4A trait to S3 and event bridge. These services don't model their sigV4A usage + * Adds the sigV4A trait to services that don't model their sigV4A usage + * NOTE: Won't add sigV4 trait (services that support sigV4A MUST support sigV4) */ class SigV4AsymmetricTraitCustomization : KotlinIntegration { override val order: Byte = -60 - override fun enabledForService(model: Model, settings: KotlinSettings): Boolean { - val sdkId = model.expectShape(settings.service).sdkId.lowercase() // FIXME don't use sdkId - return sdkId == "s3" || sdkId == "eventbridge" || sdkId == "cloudfront keyvaluestore" - } - - override fun preprocessModel(model: Model, settings: KotlinSettings): Model { - return ModelTransformer.create().mapShapes(model) { shape -> - if (shape.isServiceShape) { - val authSchemes: MutableSet = - (shape as ServiceShape).getTrait()?.let { - val modeledAuthSchemes = it.valueSet - modeledAuthSchemes.add( SigV4ATrait.ID) - modeledAuthSchemes.add(SigV4Trait.ID) - modeledAuthSchemes - } ?: mutableSetOf(SigV4ATrait.ID, SigV4Trait.ID) - - // SigV4A trait name is based on these rules: https://smithy.io/2.0/aws/aws-auth.html?highlight=sigv4#aws-auth-sigv4a-trait - val sigV4ATraitNameProperty = - shape.getTrait()?.let { it.arnNamespace } - ?: shape.getTrait()?.let { it.name } - ?: throw Exception("Service (${shape.id}) is missing ARN namespace. Please report to AWS.") + override fun enabledForService(model: Model, settings: KotlinSettings): Boolean = + when (settings.sdkId.lowercase()) { + "s3", "eventbridge", "cloudfront keyvaluestore" -> true + else -> false + } - shape - .toBuilder() - .addTrait( - SigV4ATrait - .builder() - .name(sigV4ATraitNameProperty) - .build() - ) - .addTrait( - AuthTrait(authSchemes) - ) - .build() - } else { - shape + override fun preprocessModel(model: Model, settings: KotlinSettings): Model = + ModelTransformer.create().mapShapes(model) { shape -> + when (shape.isServiceShape) { + true -> + (shape as ServiceShape) + .toBuilder() + .addTraits( + mutableSetOf( + SigV4ATrait + .builder() + .name(shape.expectTrait().arnNamespace) + .build(), + AuthTrait(mutableSetOf(SigV4ATrait.ID, SigV4Trait.ID)), + ), + ) + .build() + false -> shape } } - } -} \ No newline at end of file +} diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt index 714ad027151..24dc78e7e07 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/UnsupportedSigningAlgorithmIntegration.kt @@ -1,3 +1,7 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ package aws.sdk.kotlin.codegen.customization.s3 import aws.sdk.kotlin.codegen.AwsRuntimeTypes @@ -11,8 +15,9 @@ import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.ServiceShape +// FIXME: Remove this once sigV4a is supported by default AWS signer /** - * Registers an interceptor for S3. + * Registers an interceptor for S3 to deal with the default signer not supporting sigV4a * See: [aws.sdk.kotlin.runtime.http.interceptors.UnsupportedSigningAlgorithmInterceptor] */ class UnsupportedSigningAlgorithmIntegration : KotlinIntegration { @@ -34,4 +39,4 @@ private val UnsupportedSigningAlgorithmMiddleware = object : ProtocolMiddleware AwsRuntimeTypes.Http.Interceptors.UnsupportedSigningAlgorithmInterceptor, ) } -} \ No newline at end of file +} diff --git a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt index 9ec42f01219..870c0441934 100644 --- a/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt +++ b/codegen/aws-sdk-codegen/src/test/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomizationTest.kt @@ -1,9 +1,13 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ package aws.sdk.kotlin.codegen.customization import software.amazon.smithy.aws.traits.auth.SigV4ATrait import software.amazon.smithy.aws.traits.auth.SigV4Trait import software.amazon.smithy.kotlin.codegen.KotlinSettings -import software.amazon.smithy.kotlin.codegen.model.getTrait +import software.amazon.smithy.kotlin.codegen.model.expectTrait import software.amazon.smithy.kotlin.codegen.test.toSmithyModel import software.amazon.smithy.model.shapes.ShapeId import software.amazon.smithy.model.traits.AuthTrait @@ -17,9 +21,14 @@ class SigV4AsymmetricTraitCustomizationTest { use aws.protocols#awsJson1_0 use aws.auth#sigv4 + use aws.api#service @awsJson1_0 - @sigv4(name: "example-signing-name") + @sigv4(name: "exampleservice") + @service( + sdkId: "example" + arnNamespace: "exampleservice" + ) service Example { version: "1.0.0", operations: [GetFoo] @@ -46,19 +55,19 @@ class SigV4AsymmetricTraitCustomizationTest { KotlinSettings( ShapeId.from("smithy.example#Example"), KotlinSettings.PackageSettings("example", "1.0.0"), - "example" - ) + "example", + ), ) assertTrue(customizedModel.appliedTraits.contains(SigV4ATrait.ID)) assertTrue(customizedModel.appliedTraits.contains(AuthTrait.ID)) val service = customizedModel.getShape(customizedModel.serviceShapes.first().id).get() - val sigV4ATrait = service.getTrait() as SigV4ATrait - val authTrait = service.getTrait() as AuthTrait + val sigV4ATrait = service.expectTrait() + val authTrait = service.expectTrait() - assertEquals("example-signing-name", sigV4ATrait.name) assertTrue(authTrait.valueSet.contains(SigV4Trait.ID)) assertTrue(authTrait.valueSet.contains(SigV4ATrait.ID)) + assertEquals("exampleservice", sigV4ATrait.name) } -} \ No newline at end of file +} diff --git a/services/s3/e2eTest/src/MultRegionAccessPointTest.kt b/services/s3/e2eTest/src/MultRegionAccessPointTest.kt deleted file mode 100644 index cebcb1ff6be..00000000000 --- a/services/s3/e2eTest/src/MultRegionAccessPointTest.kt +++ /dev/null @@ -1,42 +0,0 @@ -package aws.sdk.kotlin.e2etest - -import aws.sdk.kotlin.runtime.auth.credentials.ProcessCredentialsProvider -import aws.sdk.kotlin.services.s3.S3Client -import aws.sdk.kotlin.services.s3.model.PutObjectRequest -import aws.smithy.kotlin.runtime.InternalApi -import aws.smithy.kotlin.runtime.auth.awssigning.UnsupportedSigningAlgorithm -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.assertThrows -import kotlin.test.Test -import kotlin.test.assertEquals - -class MultRegionAccessPointTest { - @OptIn(InternalApi::class) - @Test - fun testUnsupportedSigningAlgorithm() = runTest { - val client = S3Client { - region = "us-east-1" - credentialsProvider = ProcessCredentialsProvider("isengardcli credentials --awscli aoperez@amazon.com --role Admin") - } - - - val exception = assertThrows { - client.putObject( - PutObjectRequest { - bucket = "..." - key = "thisIsATestForMrap" - } - ) - } - - assertEquals( - "SIGV4_ASYMMETRIC support is not yet implemented for the default signer. Please follow the AWS SDK for Kotlin developer guide to set it up with the CRT signer. **LINK TO GUIDE**", - exception.message - ) - } - - @Test - fun testMultiRegionAccessPointOperation() = runTest { - // TODO - } -} \ No newline at end of file From 84ab837838d4082f915150e0fb6aa6492a7f21b2 Mon Sep 17 00:00:00 2001 From: 0marperez Date: Wed, 17 Jan 2024 10:51:01 -0500 Subject: [PATCH 06/10] Added tests for unsupported signing algorithm interceptor --- ...upportedSigningAlgorithmInterceptorTest.kt | 62 +++++++++++++++++++ .../s3/ClientConfigIntegration.kt | 1 - 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 aws-runtime/aws-http/common/test/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptorTest.kt diff --git a/aws-runtime/aws-http/common/test/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptorTest.kt b/aws-runtime/aws-http/common/test/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptorTest.kt new file mode 100644 index 00000000000..05025b42eca --- /dev/null +++ b/aws-runtime/aws-http/common/test/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptorTest.kt @@ -0,0 +1,62 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.sdk.kotlin.runtime.http.interceptors + +import aws.smithy.kotlin.runtime.auth.awssigning.UnsupportedSigningAlgorithm +import aws.smithy.kotlin.runtime.client.ResponseInterceptorContext +import aws.smithy.kotlin.runtime.client.SdkClientOption +import aws.smithy.kotlin.runtime.http.request.HttpRequest +import aws.smithy.kotlin.runtime.http.response.HttpResponse +import aws.smithy.kotlin.runtime.operation.ExecutionContext +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFails + +class UnsupportedSigningAlgorithmInterceptorTest { + @Test + fun testUnsupportedSigningAlgorithmSigV4a() = runTest { + val exception = assertFails { + UnsupportedSigningAlgorithmInterceptor() + .modifyBeforeCompletion( + context( + Result.failure( + UnsupportedSigningAlgorithm( + "SIGV4A support is not yet implemented for the default signer.", + true, + ), + ), + ), + ) + } + + assertEquals(UnsupportedSigningAlgorithm::class, exception::class) + assertEquals("SIGV4A support is not yet implemented for the default signer.", exception.message) + } + + @Test + fun testUnsupportedSigningAlgorithmNotSigV4aNoException() = runTest { + UnsupportedSigningAlgorithmInterceptor() + .modifyBeforeCompletion( + context( + Result.failure( + UnsupportedSigningAlgorithm( + "SIGV5 support is not yet implemented for the default signer.", + false, + ), + ), + ), + ) + } +} + +private fun context(response: Result) = + object : ResponseInterceptorContext { + override val executionContext = ExecutionContext.build { attributes[SdkClientOption.OperationName] = "test" } + override val request = Unit + override val response = response + override val protocolRequest = HttpRequest { } + override val protocolResponse = null + } diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt index 1236814f06a..d7bdb15dd05 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/s3/ClientConfigIntegration.kt @@ -54,7 +54,6 @@ class ClientConfigIntegration : KotlinIntegration { """.trimIndent() } - // FIXME: default signer doesn't yet implement sigv4a val DisableMrapProp: ConfigProperty = ConfigProperty { name = "disableMrap" useSymbolWithNullableBuilder(KotlinTypes.Boolean, "false") From fadf63dd60a7679ca7fc4c1edfa665fd4cba4aed Mon Sep 17 00:00:00 2001 From: 0marperez Date: Wed, 17 Jan 2024 13:59:03 -0500 Subject: [PATCH 07/10] Misc changes --- .../UnsupportedSigningAlgorithmInterceptor.kt | 10 ++-- ...upportedSigningAlgorithmInterceptorTest.kt | 47 ++++++++++++------- .../SigV4AsymmetricTraitCustomization.kt | 1 + 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt index 4d0de0611e6..15d8df40f73 100644 --- a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt +++ b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt @@ -5,7 +5,8 @@ package aws.sdk.kotlin.runtime.http.interceptors import aws.sdk.kotlin.runtime.InternalSdkApi -import aws.smithy.kotlin.runtime.auth.awssigning.UnsupportedSigningAlgorithm +import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigningAlgorithm +import aws.smithy.kotlin.runtime.auth.awssigning.UnsupportedSigningAlgorithmException import aws.smithy.kotlin.runtime.client.ResponseInterceptorContext import aws.smithy.kotlin.runtime.http.interceptors.HttpInterceptor import aws.smithy.kotlin.runtime.http.request.HttpRequest @@ -20,10 +21,9 @@ import aws.smithy.kotlin.runtime.http.response.HttpResponse public class UnsupportedSigningAlgorithmInterceptor : HttpInterceptor { override suspend fun modifyBeforeCompletion(context: ResponseInterceptorContext): Result { context.response.exceptionOrNull()?.let { - if (it is UnsupportedSigningAlgorithm && it.isSigV4a) { - throw UnsupportedSigningAlgorithm( - it.message!!, // TODO: Add a message and link pointing to AWS SDK for Kotlin developer guide - true, + if (it is UnsupportedSigningAlgorithmException && it.signingAlgorithm == AwsSigningAlgorithm.SIGV4_ASYMMETRIC) { + return Result.failure( + it, // TODO: Add a message and link pointing to AWS SDK for Kotlin developer guide ) } } diff --git a/aws-runtime/aws-http/common/test/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptorTest.kt b/aws-runtime/aws-http/common/test/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptorTest.kt index 05025b42eca..7a5020aab9f 100644 --- a/aws-runtime/aws-http/common/test/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptorTest.kt +++ b/aws-runtime/aws-http/common/test/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptorTest.kt @@ -4,7 +4,8 @@ */ package aws.sdk.kotlin.runtime.http.interceptors -import aws.smithy.kotlin.runtime.auth.awssigning.UnsupportedSigningAlgorithm +import aws.smithy.kotlin.runtime.auth.awssigning.AwsSigningAlgorithm +import aws.smithy.kotlin.runtime.auth.awssigning.UnsupportedSigningAlgorithmException import aws.smithy.kotlin.runtime.client.ResponseInterceptorContext import aws.smithy.kotlin.runtime.client.SdkClientOption import aws.smithy.kotlin.runtime.http.request.HttpRequest @@ -13,42 +14,54 @@ import aws.smithy.kotlin.runtime.operation.ExecutionContext import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertEquals -import kotlin.test.assertFails +import kotlin.test.assertIs +import kotlin.test.assertTrue class UnsupportedSigningAlgorithmInterceptorTest { @Test fun testUnsupportedSigningAlgorithmSigV4a() = runTest { - val exception = assertFails { + val result = UnsupportedSigningAlgorithmInterceptor() .modifyBeforeCompletion( context( Result.failure( - UnsupportedSigningAlgorithm( + UnsupportedSigningAlgorithmException( "SIGV4A support is not yet implemented for the default signer.", - true, + AwsSigningAlgorithm.SIGV4_ASYMMETRIC, ), ), ), ) - } - assertEquals(UnsupportedSigningAlgorithm::class, exception::class) + val exception = result.exceptionOrNull() + + assertTrue(result.isFailure) + assertIs(exception) + assertEquals(exception.signingAlgorithm, AwsSigningAlgorithm.SIGV4_ASYMMETRIC) assertEquals("SIGV4A support is not yet implemented for the default signer.", exception.message) } @Test - fun testUnsupportedSigningAlgorithmNotSigV4aNoException() = runTest { - UnsupportedSigningAlgorithmInterceptor() - .modifyBeforeCompletion( - context( - Result.failure( - UnsupportedSigningAlgorithm( - "SIGV5 support is not yet implemented for the default signer.", - false, + fun testUnsupportedSigningAlgorithmNotSigV4a() = runTest { + val result = + UnsupportedSigningAlgorithmInterceptor() + .modifyBeforeCompletion( + context( + Result.failure( + UnsupportedSigningAlgorithmException( + "SIGV4 support is not yet implemented for the default signer.", + AwsSigningAlgorithm.SIGV4, + ), ), ), - ), - ) + ) + + val exception = result.exceptionOrNull() + + assertTrue(result.isFailure) + assertIs(exception) + assertEquals(exception.signingAlgorithm, AwsSigningAlgorithm.SIGV4) + assertEquals("SIGV4 support is not yet implemented for the default signer.", exception.message) } } diff --git a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt index b1f94ee64ca..0fdabe539dd 100644 --- a/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt +++ b/codegen/aws-sdk-codegen/src/main/kotlin/aws/sdk/kotlin/codegen/customization/SigV4AsymmetricTraitCustomization.kt @@ -21,6 +21,7 @@ import software.amazon.smithy.model.transform.ModelTransformer * NOTE: Won't add sigV4 trait (services that support sigV4A MUST support sigV4) */ class SigV4AsymmetricTraitCustomization : KotlinIntegration { + // Needs to happen before the `SigV4AsymmetricAuthSchemeIntegration` & `SigV4AuthSchemeIntegration` (-50 & -50) override val order: Byte = -60 override fun enabledForService(model: Model, settings: KotlinSettings): Boolean = From 9f3ecc0b182e5e536b265c5b89b4ae3567c73141 Mon Sep 17 00:00:00 2001 From: 0marperez Date: Wed, 17 Jan 2024 14:48:05 -0500 Subject: [PATCH 08/10] Changed smithy version to snapshot --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c1f5fd87f66..fc2e2d1b38d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,8 +9,8 @@ coroutines-version = "1.7.3" atomicfu-version = "0.23.1" # smithy-kotlin codegen and runtime are versioned separately -smithy-kotlin-runtime-version = "1.0.9" -smithy-kotlin-codegen-version = "0.30.10" +smithy-kotlin-runtime-version = "1.0.10-SNAPSHOT" +smithy-kotlin-codegen-version = "0.30.11-SNAPSHOT" # codegen smithy-version = "1.42.0" From 7d27b8614e2335e1e5bb7ebf09702311c7279d34 Mon Sep 17 00:00:00 2001 From: 0marperez Date: Wed, 17 Jan 2024 15:27:07 -0500 Subject: [PATCH 09/10] Bump smithy versions --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fc2e2d1b38d..b4e2804ce73 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,8 +9,8 @@ coroutines-version = "1.7.3" atomicfu-version = "0.23.1" # smithy-kotlin codegen and runtime are versioned separately -smithy-kotlin-runtime-version = "1.0.10-SNAPSHOT" -smithy-kotlin-codegen-version = "0.30.11-SNAPSHOT" +smithy-kotlin-runtime-version = "1.0.10" +smithy-kotlin-codegen-version = "0.30.11" # codegen smithy-version = "1.42.0" From d1256c8fbb97cdcfd1c6dee754cd4b19c1af0d4d Mon Sep 17 00:00:00 2001 From: 0marperez Date: Wed, 17 Jan 2024 16:10:02 -0500 Subject: [PATCH 10/10] Making punctuation change to prompt github tests to run --- .../http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt index 15d8df40f73..953d4400722 100644 --- a/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt +++ b/aws-runtime/aws-http/common/src/aws/sdk/kotlin/runtime/http/interceptors/UnsupportedSigningAlgorithmInterceptor.kt @@ -23,7 +23,7 @@ public class UnsupportedSigningAlgorithmInterceptor : HttpInterceptor { context.response.exceptionOrNull()?.let { if (it is UnsupportedSigningAlgorithmException && it.signingAlgorithm == AwsSigningAlgorithm.SIGV4_ASYMMETRIC) { return Result.failure( - it, // TODO: Add a message and link pointing to AWS SDK for Kotlin developer guide + it, // TODO: Add a message and link pointing to AWS SDK for Kotlin developer guide. ) } }