Skip to content

Commit a779e59

Browse files
authored
feat: support sigv4aSigningRegionSet config setting (#1043)
1 parent 94a9e06 commit a779e59

File tree

8 files changed

+98
-0
lines changed

8 files changed

+98
-0
lines changed

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/core/RuntimeTypes.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ object RuntimeTypes {
299299
val Credentials = symbol("Credentials")
300300
val CredentialsProvider = symbol("CredentialsProvider")
301301
val CredentialsProviderConfig = symbol("CredentialsProviderConfig")
302+
val SigV4aClientConfig = symbol("SigV4aClientConfig")
302303
}
303304
}
304305

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/lang/KotlinTypes.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ object KotlinTypes {
6161
dependency(KotlinDependency.KOTLIN_STDLIB)
6262
}
6363

64+
private fun setType(
65+
setType: Symbol,
66+
target: Symbol,
67+
isNullable: Boolean = false,
68+
default: String? = null,
69+
): Symbol = buildSymbol {
70+
name = "${setType.fullName}<${target.fullName}>"
71+
nullable = isNullable
72+
defaultValue = default
73+
reference(setType)
74+
reference(target)
75+
dependency(KotlinDependency.KOTLIN_STDLIB)
76+
}
77+
6478
/**
6579
* Convenience function to get a `List<target>` as a symbol
6680
*/
@@ -78,6 +92,15 @@ object KotlinTypes {
7892
isNullable: Boolean = false,
7993
default: String? = null,
8094
): Symbol = listType(MutableList, target, isNullable, default)
95+
96+
/**
97+
* Convenience function to get a `Set<target>` as a symbol
98+
*/
99+
fun set(
100+
target: Symbol,
101+
isNullable: Boolean = false,
102+
default: String? = null,
103+
): Symbol = setType(Set, target, isNullable, default)
81104
}
82105

83106
object Jvm : RuntimeTypePackage(KotlinDependency.KOTLIN_STDLIB, "jvm") {

codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/auth/SigV4AsymmetricAuthSchemeIntegration.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@ import software.amazon.smithy.codegen.core.Symbol
1010
import software.amazon.smithy.codegen.core.SymbolReference
1111
import software.amazon.smithy.kotlin.codegen.KotlinSettings
1212
import software.amazon.smithy.kotlin.codegen.core.*
13+
import software.amazon.smithy.kotlin.codegen.integration.AppendingSectionWriter
1314
import software.amazon.smithy.kotlin.codegen.integration.AuthSchemeHandler
1415
import software.amazon.smithy.kotlin.codegen.integration.KotlinIntegration
16+
import software.amazon.smithy.kotlin.codegen.integration.SectionWriterBinding
17+
import software.amazon.smithy.kotlin.codegen.lang.KotlinTypes
18+
import software.amazon.smithy.kotlin.codegen.model.asNullable
1519
import software.amazon.smithy.kotlin.codegen.model.buildSymbol
1620
import software.amazon.smithy.kotlin.codegen.model.hasTrait
1721
import software.amazon.smithy.kotlin.codegen.model.knowledge.AwsSignatureVersion4Asymmetric
1822
import software.amazon.smithy.kotlin.codegen.rendering.protocol.*
23+
import software.amazon.smithy.kotlin.codegen.rendering.util.ConfigProperty
1924
import software.amazon.smithy.model.Model
2025
import software.amazon.smithy.model.knowledge.ServiceIndex
2126
import software.amazon.smithy.model.shapes.OperationShape
@@ -34,6 +39,33 @@ class SigV4AsymmetricAuthSchemeIntegration : KotlinIntegration {
3439

3540
override fun authSchemes(ctx: ProtocolGenerator.GenerationContext): List<AuthSchemeHandler> =
3641
listOf(SigV4AsymmetricAuthSchemeHandler())
42+
43+
override fun additionalServiceConfigProps(ctx: CodegenContext): List<ConfigProperty> =
44+
listOf(
45+
ConfigProperty {
46+
name = "sigV4aSigningRegionSet"
47+
symbol = KotlinTypes.Collections.set(KotlinTypes.String).asNullable()
48+
baseClass = RuntimeTypes.Auth.Credentials.AwsCredentials.SigV4aClientConfig
49+
useNestedBuilderBaseClass()
50+
documentation = """
51+
The set of regions to use when signing a request with SigV4a. If not provided this will automatically be set by the SDK.
52+
""".trimIndent()
53+
},
54+
)
55+
56+
override val sectionWriters: List<SectionWriterBinding>
57+
get() = listOf(
58+
SectionWriterBinding(HttpProtocolClientGenerator.MergeServiceDefaults, renderMergeServiceDefaults),
59+
)
60+
}
61+
62+
private val renderMergeServiceDefaults = AppendingSectionWriter { writer ->
63+
writer.putIfAbsent(
64+
RuntimeTypes.Auth.Signing.AwsSigningCommon.AwsSigningAttributes,
65+
"ConfigSigningRegionSet",
66+
"config.sigV4aSigningRegionSet",
67+
true,
68+
)
3769
}
3870

3971
private class SigV4AsymmetricAuthSchemeHandler : AuthSchemeHandler {

runtime/auth/aws-credentials/api/aws-credentials.api

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,12 @@ public final class aws/smithy/kotlin/runtime/auth/awscredentials/CredentialsProv
6161
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Throwable;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
6262
}
6363

64+
public abstract interface class aws/smithy/kotlin/runtime/auth/awscredentials/SigV4aClientConfig {
65+
public abstract fun getSigV4aSigningRegionSet ()Ljava/util/Set;
66+
}
67+
68+
public abstract interface class aws/smithy/kotlin/runtime/auth/awscredentials/SigV4aClientConfig$Builder {
69+
public abstract fun getSigV4aSigningRegionSet ()Ljava/util/Set;
70+
public abstract fun setSigV4aSigningRegionSet (Ljava/util/Set;)V
71+
}
72+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package aws.smithy.kotlin.runtime.auth.awscredentials
6+
7+
/**
8+
* The configuration properties for a client that supports SigV4a
9+
*/
10+
public interface SigV4aClientConfig {
11+
/**
12+
* The set of regions to use when signing a request with SigV4a.
13+
*/
14+
public val sigV4aSigningRegionSet: Set<String>?
15+
16+
public interface Builder {
17+
/**
18+
* The set of regions to use when signing a request with SigV4a.
19+
*/
20+
public var sigV4aSigningRegionSet: Set<String>?
21+
}
22+
}

runtime/auth/aws-signing-common/api/aws-signing-common.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public final class aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAlgorithm
5151

5252
public final class aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAttributes {
5353
public static final field INSTANCE Laws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAttributes;
54+
public final fun getConfigSigningRegionSet ()Laws/smithy/kotlin/runtime/collections/AttributeKey;
5455
public final fun getCredentialsProvider ()Laws/smithy/kotlin/runtime/collections/AttributeKey;
5556
public final fun getEnableAwsChunked ()Laws/smithy/kotlin/runtime/collections/AttributeKey;
5657
public final fun getHashSpecification ()Laws/smithy/kotlin/runtime/collections/AttributeKey;

runtime/auth/aws-signing-common/common/src/aws/smithy/kotlin/runtime/auth/awssigning/AwsSigningAttributes.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ public object AwsSigningAttributes {
2828
*/
2929
public val SigningRegionSet: AttributeKey<Set<String>> = AttributeKey("aws.smithy.kotlin.signing#AwsSigningRegionSet")
3030

31+
/**
32+
* The user provided AWS region-set used for computing the signature. Overrides [SigningRegionSet].
33+
*/
34+
public val ConfigSigningRegionSet: AttributeKey<Set<String>> = AttributeKey("aws.smithy.kotlin.signing#ConfigSigningRegionSet")
35+
3136
/**
3237
* The signature version 4 service signing name to use in the credential scope when signing requests.
3338
* See: https://docs.aws.amazon.com/general/latest/gr/sigv4_elements.html

runtime/auth/http-auth-aws/common/src/aws/smithy/kotlin/runtime/http/auth/AwsHttpSigner.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ public class AwsHttpSigner(private val config: Config) : HttpSigner {
121121
val contextSignedBodyHeader = attributes.getOrNull(AwsSigningAttributes.SignedBodyHeader)
122122
val contextSigningRegion = attributes[AwsSigningAttributes.SigningRegion]
123123
val contextSigningRegionSet = attributes.getOrNull(AwsSigningAttributes.SigningRegionSet)
124+
val configSigningRegionSet = attributes.getOrNull(AwsSigningAttributes.ConfigSigningRegionSet)
124125
val contextUseDoubleUriEncode = attributes.getOrNull(AwsSigningAttributes.UseDoubleUriEncode)
125126
val contextNormalizeUriPath = attributes.getOrNull(AwsSigningAttributes.NormalizeUriPath)
126127
val contextSigningServiceName = attributes.getOrNull(AwsSigningAttributes.SigningService)
@@ -135,6 +136,10 @@ public class AwsHttpSigner(private val config: Config) : HttpSigner {
135136
algorithm = config.algorithm
136137

137138
region = when {
139+
// signing region set from client config overrides all other sources like endpoints because it's designed as an
140+
// escape hatch for customers to control/limit which regions a request will be valid for (e.g. since some services
141+
// use '*')
142+
algorithm == AwsSigningAlgorithm.SIGV4_ASYMMETRIC && !configSigningRegionSet.isNullOrEmpty() -> configSigningRegionSet.joinToString(",")
138143
algorithm == AwsSigningAlgorithm.SIGV4_ASYMMETRIC && !contextSigningRegionSet.isNullOrEmpty() -> contextSigningRegionSet.joinToString(",")
139144
else -> contextSigningRegion
140145
}

0 commit comments

Comments
 (0)