Skip to content

Commit 4b8a71c

Browse files
authored
fix: correct the addition of signing at the operation level (#271)
1 parent 4bb2bf8 commit 4b8a71c

File tree

6 files changed

+74
-28
lines changed

6 files changed

+74
-28
lines changed

codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSHttpProtocolCustomizations.kt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import software.amazon.smithy.aws.swift.codegen.middleware.AWSSigningMiddleware
44
import software.amazon.smithy.aws.swift.codegen.middleware.EndpointResolverMiddleware
55
import software.amazon.smithy.aws.swift.codegen.middleware.RetryMiddleware
66
import software.amazon.smithy.aws.swift.codegen.middleware.UserAgentMiddleware
7-
import software.amazon.smithy.aws.traits.auth.SigV4Trait
87
import software.amazon.smithy.model.node.Node
98
import software.amazon.smithy.model.shapes.OperationShape
109
import software.amazon.smithy.model.shapes.ServiceShape
@@ -13,14 +12,13 @@ import software.amazon.smithy.swift.codegen.integration.ClientProperty
1312
import software.amazon.smithy.swift.codegen.integration.DefaultHttpProtocolCustomizations
1413
import software.amazon.smithy.swift.codegen.integration.OperationMiddlewareRenderable
1514
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
16-
import software.amazon.smithy.swift.codegen.model.getTrait
1715

1816
abstract class AWSHttpProtocolCustomizations : DefaultHttpProtocolCustomizations() {
19-
override fun baseMiddlewares(ctx: ProtocolGenerator.GenerationContext): List<OperationMiddlewareRenderable> {
20-
val defaultMiddlewares = super.baseMiddlewares(ctx)
17+
override fun baseMiddlewares(ctx: ProtocolGenerator.GenerationContext, op: OperationShape): List<OperationMiddlewareRenderable> {
18+
val defaultMiddlewares = super.baseMiddlewares(ctx, op)
2119
val protocolMiddlewares = mutableListOf(EndpointResolverMiddleware(), RetryMiddleware())
2220

23-
if (ctx.service.needsSigning) {
21+
if (AWSSigningMiddleware.hasSigV4AuthScheme(ctx.model, ctx.service, op)) {
2422
protocolMiddlewares.add(AWSSigningMiddleware())
2523
}
2624

@@ -35,8 +33,8 @@ abstract class AWSHttpProtocolCustomizations : DefaultHttpProtocolCustomizations
3533
writer.write(" .withCredentialsProvider(value: config.credentialsProvider)")
3634
writer.write(" .withRegion(value: config.region)")
3735
writer.write(" .withHost(value: \"$endpointPrefix.\\(config.region).amazonaws.com\")")
38-
if (serviceShape.needsSigning) {
39-
val signingName = serviceShape.getTrait<SigV4Trait>()?.name
36+
if (AWSSigningMiddleware.hasSigV4AuthScheme(ctx.model, ctx.service, op)) {
37+
val signingName = AWSSigningMiddleware.signingServiceName(serviceShape)
4038
writer.write(" .withSigningName(value: \$S)", signingName)
4139
writer.write(" .withSigningRegion(value: config.signingRegion)")
4240
}

codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/AWSServiceUtils.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
package software.amazon.smithy.aws.swift.codegen
77

88
import software.amazon.smithy.aws.traits.ServiceTrait
9-
import software.amazon.smithy.aws.traits.auth.SigV4Trait
109
import software.amazon.smithy.model.shapes.ServiceShape
1110
import software.amazon.smithy.swift.codegen.model.expectTrait
12-
import software.amazon.smithy.swift.codegen.model.hasTrait
1311

1412
/**
1513
* Get the [sdkId](https://awslabs.github.io/smithy/1.0/spec/aws/aws-core.html#sdkid) from the (AWS) service shape
@@ -30,9 +28,3 @@ val ServiceShape.arnNamespace: String
3028
*/
3129
val ServiceShape.endpointPrefix: String
3230
get() = expectTrait<ServiceTrait>().endpointPrefix
33-
34-
/**
35-
* Determines if the service shape needs sigv4 signing
36-
*/
37-
val ServiceShape.needsSigning: Boolean
38-
get() = hasTrait<SigV4Trait>()

codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSHttpProtocolJson10Customizations.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ import software.amazon.smithy.aws.swift.codegen.AWSHttpProtocolCustomizations
44
import software.amazon.smithy.aws.swift.codegen.AWSSwiftDependency
55
import software.amazon.smithy.aws.swift.codegen.middleware.AWSXAmzTargetMiddleware
66
import software.amazon.smithy.codegen.core.Symbol
7+
import software.amazon.smithy.model.shapes.OperationShape
78
import software.amazon.smithy.protocoltests.traits.HttpRequestTestCase
89
import software.amazon.smithy.swift.codegen.SwiftWriter
910
import software.amazon.smithy.swift.codegen.integration.OperationMiddlewareRenderable
1011
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator.GenerationContext
1112

1213
class AWSHttpProtocolJson10Customizations : AWSHttpProtocolCustomizations() {
1314

14-
override fun baseMiddlewares(ctx: GenerationContext): List<OperationMiddlewareRenderable> {
15-
val defaultMiddlewares = super.baseMiddlewares(ctx)
15+
override fun baseMiddlewares(ctx: GenerationContext, op: OperationShape): List<OperationMiddlewareRenderable> {
16+
val defaultMiddlewares = super.baseMiddlewares(ctx, op)
1617
val protocolMiddlewares = listOf<OperationMiddlewareRenderable>(AWSXAmzTargetMiddleware())
1718
return defaultMiddlewares + protocolMiddlewares
1819
}

codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/awsjson/AWSHttpProtocolJson11Customizations.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ import software.amazon.smithy.aws.swift.codegen.AWSHttpProtocolCustomizations
44
import software.amazon.smithy.aws.swift.codegen.AWSSwiftDependency
55
import software.amazon.smithy.aws.swift.codegen.middleware.AWSXAmzTargetMiddleware
66
import software.amazon.smithy.codegen.core.Symbol
7+
import software.amazon.smithy.model.shapes.OperationShape
78
import software.amazon.smithy.protocoltests.traits.HttpRequestTestCase
89
import software.amazon.smithy.swift.codegen.SwiftWriter
910
import software.amazon.smithy.swift.codegen.integration.OperationMiddlewareRenderable
1011
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
1112

1213
class AWSHttpProtocolJson11Customizations : AWSHttpProtocolCustomizations() {
1314

14-
override fun baseMiddlewares(ctx: ProtocolGenerator.GenerationContext): List<OperationMiddlewareRenderable> {
15-
val defaultMiddlewares = super.baseMiddlewares(ctx)
15+
override fun baseMiddlewares(ctx: ProtocolGenerator.GenerationContext, op: OperationShape): List<OperationMiddlewareRenderable> {
16+
val defaultMiddlewares = super.baseMiddlewares(ctx, op)
1617
val protocolMiddlewares = listOf<OperationMiddlewareRenderable>(AWSXAmzTargetMiddleware())
1718
return defaultMiddlewares + protocolMiddlewares
1819
}

codegen/smithy-aws-swift-codegen/src/main/kotlin/software/amazon/smithy/aws/swift/codegen/middleware/AWSSigningMiddleware.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package software.amazon.smithy.aws.swift.codegen.middleware
22

3+
import software.amazon.smithy.aws.traits.auth.SigV4Trait
34
import software.amazon.smithy.aws.traits.auth.UnsignedPayloadTrait
5+
import software.amazon.smithy.model.Model
6+
import software.amazon.smithy.model.knowledge.ServiceIndex
47
import software.amazon.smithy.model.shapes.OperationShape
58
import software.amazon.smithy.model.shapes.ServiceShape
9+
import software.amazon.smithy.model.traits.OptionalAuthTrait
610
import software.amazon.smithy.swift.codegen.SwiftWriter
711
import software.amazon.smithy.swift.codegen.integration.MiddlewarePosition
812
import software.amazon.smithy.swift.codegen.integration.MiddlewareStep
913
import software.amazon.smithy.swift.codegen.integration.OperationMiddlewareRenderable
1014
import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator
15+
import software.amazon.smithy.swift.codegen.model.expectTrait
1116
import software.amazon.smithy.swift.codegen.model.hasTrait
1217

1318
open class AWSSigningMiddleware : OperationMiddlewareRenderable {
@@ -50,4 +55,30 @@ open class AWSSigningMiddleware : OperationMiddlewareRenderable {
5055
val hasUnsignedPayload = op.hasTrait<UnsignedPayloadTrait>()
5156
return "unsignedBody: $hasUnsignedPayload"
5257
}
58+
59+
companion object {
60+
/**
61+
* Get the SigV4Trait auth name to sign request for
62+
*
63+
* @param serviceShape service shape for the API
64+
* @return the service name to use in the credential scope to sign for
65+
*/
66+
fun signingServiceName(serviceShape: ServiceShape): String {
67+
val sigv4Trait = serviceShape.expectTrait<SigV4Trait>()
68+
return sigv4Trait.name
69+
}
70+
71+
/**
72+
* Returns if the SigV4Trait is an auth scheme for the service and operation.
73+
*
74+
* @param model model definition
75+
* @param service service shape for the API
76+
* @param operation operation shape
77+
* @return if SigV4Trait is an auth scheme for the operation and service.
78+
*/
79+
fun hasSigV4AuthScheme(model: Model, service: ServiceShape, operation: OperationShape): Boolean {
80+
val auth = ServiceIndex.of(model).getEffectiveAuthSchemes(service.id, operation.id)
81+
return auth.containsKey(SigV4Trait.ID) && !operation.hasTrait<OptionalAuthTrait>()
82+
}
83+
}
5384
}

codegen/smithy-aws-swift-codegen/src/test/kotlin/software/amazon/smithy/aws/swift/codegen/AWSSigningMiddlewareTests.kt

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package software.amazon.smithy.aws.swift.codegen
22

33
import io.kotest.matchers.string.shouldContainOnlyOnce
4+
import org.junit.jupiter.api.Assertions.assertFalse
5+
import org.junit.jupiter.api.Assertions.assertTrue
46
import org.junit.jupiter.api.Test
57
import software.amazon.smithy.aws.swift.codegen.middleware.AWSSigningMiddleware
68
import software.amazon.smithy.aws.swift.codegen.restjson.AWSRestJson1ProtocolGenerator
@@ -9,33 +11,54 @@ import software.amazon.smithy.aws.traits.auth.UnsignedPayloadTrait
911
import software.amazon.smithy.model.Model
1012
import software.amazon.smithy.model.shapes.OperationShape
1113
import software.amazon.smithy.model.shapes.ServiceShape
14+
import software.amazon.smithy.model.traits.AuthTrait
15+
import software.amazon.smithy.model.traits.HttpBasicAuthTrait
16+
import software.amazon.smithy.model.traits.OptionalAuthTrait
1217
import software.amazon.smithy.swift.codegen.SwiftWriter
1318

1419
class AWSSigningMiddlewareTests {
1520
@Test
16-
fun `needsSigningMiddleware does have SigV4Trait`() {
21+
fun `service has SigV4Trait and operation has auth trait`() {
22+
val sigV4Trait = SigV4Trait.builder().name("ExampleService").build()
23+
val authList = listOf(HttpBasicAuthTrait().toShapeId(), sigV4Trait.toShapeId())
24+
1725
val serviceShape = ServiceShape.builder()
1826
.id("com.test#Example")
1927
.version("1.0")
20-
.addTrait(SigV4Trait.builder().name("ExampleService").build())
28+
.addTrait(sigV4Trait)
29+
.build()
30+
val operationShape = OperationShape.builder()
31+
.id("com.test#ExampleOperation")
32+
.addTrait(UnsignedPayloadTrait())
33+
.addTrait(AuthTrait(authList))
34+
.build()
35+
val model = Model.builder()
36+
.addShape(serviceShape)
37+
.addShape(operationShape)
2138
.build()
2239

23-
val result = serviceShape.needsSigning
24-
25-
assert(result).equals(true)
40+
val hasAuthScheme = AWSSigningMiddleware.hasSigV4AuthScheme(model, serviceShape, operationShape)
41+
assertTrue(hasAuthScheme)
2642
}
2743

2844
@Test
29-
fun `needsSigningMiddleware does not have SigV4Trait`() {
45+
fun `service has SigV4trait but operation does not have auth`() {
3046
val serviceShape = ServiceShape.builder()
3147
.id("com.test#Example")
3248
.version("1.0")
3349
.addTrait(SigV4Trait.builder().name("ExampleService").build())
3450
.build()
51+
val operationShape = OperationShape.builder()
52+
.id("com.test#ExampleOperation")
53+
.addTrait(OptionalAuthTrait())
54+
.build()
55+
val model = Model.builder()
56+
.addShape(serviceShape)
57+
.addShape(operationShape)
58+
.build()
3559

36-
val result = serviceShape.needsSigning
37-
38-
assert(result).equals(false)
60+
val hasAuthScheme = AWSSigningMiddleware.hasSigV4AuthScheme(model, serviceShape, operationShape)
61+
assertFalse(hasAuthScheme)
3962
}
4063

4164
@Test

0 commit comments

Comments
 (0)