From bc249c5bca662c582d48fac231e21df57affab3e Mon Sep 17 00:00:00 2001 From: John Viegas Date: Tue, 24 Dec 2024 11:49:05 -0800 Subject: [PATCH] Add support for Multi Auth Sihv4a for Service metadata --- .../codegen/model/service/AuthType.java | 3 + .../scheme/AuthSchemeCodegenMetadataExt.java | 22 +++ .../awssdk/codegen/poet/ClientTestModels.java | 15 ++ .../poet/auth/scheme/AuthSchemeSpecTest.java | 15 ++ ...4a-value-auth-scheme-default-provider.java | 47 ++++++ .../customization.config | 3 + .../ops-with-auth-sigv4a-value/service-2.json | 152 ++++++++++++++++++ 7 files changed, 257 insertions(+) create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/auth/scheme/ops-auth-sigv4a-value-auth-scheme-default-provider.java create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/ops-with-auth-sigv4a-value/customization.config create mode 100644 codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/ops-with-auth-sigv4a-value/service-2.json diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/AuthType.java b/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/AuthType.java index 452ee4b05648..4b96b3454c40 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/AuthType.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/model/service/AuthType.java @@ -24,6 +24,7 @@ public enum AuthType { CUSTOM("custom"), IAM("iam"), V4("v4"), + V4a("v4a"), V4_UNSIGNED_BODY("v4-unsigned-body"), S3("s3"), S3V4("s3v4"), @@ -49,6 +50,8 @@ public static AuthType fromValue(String value) { return NONE; case "aws.auth#sigv4": return V4; + case "aws.auth#sigv4a": + return V4a; default: String normalizedValue = StringUtils.lowerCase(value); return Arrays.stream(values()) diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeCodegenMetadataExt.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeCodegenMetadataExt.java index 2063aa506771..6fcd3193189d 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeCodegenMetadataExt.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeCodegenMetadataExt.java @@ -25,7 +25,9 @@ import software.amazon.awssdk.codegen.model.service.AuthType; import software.amazon.awssdk.codegen.poet.auth.scheme.AuthSchemeCodegenMetadata.SignerPropertyValueProvider; import software.amazon.awssdk.http.auth.aws.scheme.AwsV4AuthScheme; +import software.amazon.awssdk.http.auth.aws.scheme.AwsV4aAuthScheme; import software.amazon.awssdk.http.auth.aws.signer.AwsV4HttpSigner; +import software.amazon.awssdk.http.auth.aws.signer.AwsV4aHttpSigner; import software.amazon.awssdk.http.auth.scheme.BearerAuthScheme; import software.amazon.awssdk.http.auth.scheme.NoAuthAuthScheme; import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption; @@ -59,6 +61,24 @@ public final class AuthSchemeCodegenMetadataExt { .authSchemeClass(BearerAuthScheme.class) .build(); + static final AuthSchemeCodegenMetadata SIGV4A = + builder() + .schemeId(AwsV4aAuthScheme.SCHEME_ID) + .authSchemeClass(AwsV4aAuthScheme.class) + .addProperty(SignerPropertyValueProvider.builder() + .containingClass(AwsV4aHttpSigner.class) + .fieldName( + "SERVICE_SIGNING_NAME") + .valueEmitter((spec, utils) -> spec.add("$S", utils.signingName())) + .build()) + .addProperty(SignerPropertyValueProvider.builder() + .containingClass(AwsV4aHttpSigner.class) + .fieldName( + "REGION_SET") + .valueEmitter((spec, utils) -> spec.add("$L", "params.regionSet()")) + .build()) + .build(); + static final AuthSchemeCodegenMetadata NO_AUTH = builder() .schemeId(NoAuthAuthScheme.SCHEME_ID) .authSchemeClass(NoAuthAuthScheme.class) @@ -77,6 +97,8 @@ public static AuthSchemeCodegenMetadata fromAuthType(AuthType type) { return BEARER; case NONE: return NO_AUTH; + case V4a: + return SIGV4A; default: String authTypeName = type.value(); SigV4SignerDefaults defaults = AuthTypeToSigV4Default.authTypeToDefaults().get(authTypeName); diff --git a/codegen/src/test/java/software/amazon/awssdk/codegen/poet/ClientTestModels.java b/codegen/src/test/java/software/amazon/awssdk/codegen/poet/ClientTestModels.java index 9ab222d3b51e..c94e90937590 100644 --- a/codegen/src/test/java/software/amazon/awssdk/codegen/poet/ClientTestModels.java +++ b/codegen/src/test/java/software/amazon/awssdk/codegen/poet/ClientTestModels.java @@ -335,6 +335,21 @@ public static IntermediateModel serviceMiniS3() { return new IntermediateModelBuilder(models).build(); } + public static IntermediateModel opsWithSigv4a() { + File serviceModel = + new File(ClientTestModels.class.getResource("client/c2j/ops-with-auth-sigv4a-value/service-2.json").getFile()); + File customizationModel = + new File(ClientTestModels.class.getResource("client/c2j/ops-with-auth-sigv4a-value/customization.config") + .getFile()); + C2jModels models = C2jModels + .builder() + .serviceModel(getServiceModel(serviceModel)) + .customizationConfig(getCustomizationConfig(customizationModel)) + .build(); + + return new IntermediateModelBuilder(models).build(); + } + public static IntermediateModel xmlServiceModels() { File serviceModel = new File(ClientTestModels.class.getResource("client/c2j/xml/service-2.json").getFile()); File customizationModel = new File(ClientTestModels.class.getResource("client/c2j/xml/customization.config").getFile()); diff --git a/codegen/src/test/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeSpecTest.java b/codegen/src/test/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeSpecTest.java index 15b061f9a835..a4550d72c217 100644 --- a/codegen/src/test/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeSpecTest.java +++ b/codegen/src/test/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeSpecTest.java @@ -189,6 +189,13 @@ static List parameters() { .classSpecProvider(AuthSchemeInterceptorSpec::new) .caseName("query-endpoint-auth-params-without-allowlist") .outputFileSuffix("interceptor") + .build(), + // Service with auth trait with Sigv4a + TestCase.builder() + .modelProvider(ClientTestModels::opsWithSigv4a) + .classSpecProvider(ModelBasedAuthSchemeProviderSpec::new) + .caseName("ops-auth-sigv4a-value") + .outputFileSuffix("default-provider") .build() ); } @@ -199,6 +206,14 @@ static class TestCase { private final String outputFileSuffix; private final String caseName; + + @Override + public String toString() { + return "TestCase{" + + "caseName='" + caseName + '\'' + + '}'; + } + TestCase(Builder builder) { this.modelProvider = builder.modelProvider; this.classSpecProvider = builder.classSpecProvider; diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/auth/scheme/ops-auth-sigv4a-value-auth-scheme-default-provider.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/auth/scheme/ops-auth-sigv4a-value-auth-scheme-default-provider.java new file mode 100644 index 000000000000..8b66e935f3a9 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/auth/scheme/ops-auth-sigv4a-value-auth-scheme-default-provider.java @@ -0,0 +1,47 @@ +package software.amazon.awssdk.services.database.auth.scheme.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import software.amazon.awssdk.annotations.Generated; +import software.amazon.awssdk.annotations.SdkInternalApi; +import software.amazon.awssdk.http.auth.aws.signer.AwsV4HttpSigner; +import software.amazon.awssdk.http.auth.aws.signer.AwsV4aHttpSigner; +import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption; +import software.amazon.awssdk.services.database.auth.scheme.DatabaseAuthSchemeParams; +import software.amazon.awssdk.services.database.auth.scheme.DatabaseAuthSchemeProvider; + +@Generated("software.amazon.awssdk:codegen") +@SdkInternalApi +public final class DefaultDatabaseAuthSchemeProvider implements DatabaseAuthSchemeProvider { + private static final DefaultDatabaseAuthSchemeProvider DEFAULT = new DefaultDatabaseAuthSchemeProvider(); + + private DefaultDatabaseAuthSchemeProvider() { + } + + public static DefaultDatabaseAuthSchemeProvider create() { + return DEFAULT; + } + + @Override + public List resolveAuthScheme(DatabaseAuthSchemeParams params) { + List options = new ArrayList<>(); + switch (params.operation()) { + case "DeleteRow": + case "PutRow": + options.add(AuthSchemeOption.builder().schemeId("aws.auth#sigv4") + .putSignerProperty(AwsV4HttpSigner.SERVICE_SIGNING_NAME, "database-service") + .putSignerProperty(AwsV4HttpSigner.REGION_NAME, params.region().id()).build()); + break; + default: + options.add(AuthSchemeOption.builder().schemeId("aws.auth#sigv4a") + .putSignerProperty(AwsV4aHttpSigner.SERVICE_SIGNING_NAME, "database-service") + .putSignerProperty(AwsV4aHttpSigner.REGION_SET, params.regionSet()).build()); + options.add(AuthSchemeOption.builder().schemeId("aws.auth#sigv4") + .putSignerProperty(AwsV4HttpSigner.SERVICE_SIGNING_NAME, "database-service") + .putSignerProperty(AwsV4HttpSigner.REGION_NAME, params.region().id()).build()); + break; + } + return Collections.unmodifiableList(options); + } +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/ops-with-auth-sigv4a-value/customization.config b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/ops-with-auth-sigv4a-value/customization.config new file mode 100644 index 000000000000..e1d317b04292 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/ops-with-auth-sigv4a-value/customization.config @@ -0,0 +1,3 @@ +{ + "useMultiAuth": true +} diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/ops-with-auth-sigv4a-value/service-2.json b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/ops-with-auth-sigv4a-value/service-2.json new file mode 100644 index 000000000000..abbff04b72b6 --- /dev/null +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/ops-with-auth-sigv4a-value/service-2.json @@ -0,0 +1,152 @@ +{ + "version": "2.0", + "metadata": { + "apiVersion": "2023-06-08", + "endpointPrefix": "database-service-endpoint", + "globalEndpoint": "database-service.amazonaws.com", + "protocol": "rest-json", + "serviceAbbreviation": "Database Service", + "serviceFullName": "Some Service That Uses AWS Database Protocol", + "serviceId": "Database Service", + "signingName": "database-service", + "signatureVersion": "v4", + "auth": ["aws.auth#sigv4a", "aws.auth#sigv4"], + "uid": "database-service-2023-06-08", + "xmlNamespace": "https://database-service.amazonaws.com/doc/2023-06-08/" + }, + "operations": { + "GetRow": { + "name": "GetRow", + "http": { + "method": "GET", + "requestUri": "/get-row/" + }, + "input": { + "shape": "GetRowRequest" + }, + "output": { + "shape": "GetRowResponse" + }, + "errors": [ + { + "shape": "InvalidInputException" + } + ], + "documentation": "

Performs a get row operation no output

" + }, + "PutRow": { + "name": "PutRow", + "auth": ["v4"], + "http": { + "method": "PUT", + "requestUri": "/put-row/" + }, + "input": { + "shape": "PutRowRequest" + }, + "output": { + "shape": "PutRowResponse" + }, + "errors": [ + { + "shape": "InvalidInputException" + } + ], + "documentation": "

Performs a get row operation no output

" + }, + "DeleteRow": { + "name": "DeleteRow", + "auth": [ "v4"], + "http": { + "method": "DELETE", + "requestUri": "/delete-row/" + }, + "input": { + "shape": "DeleteRowRequest" + }, + "output": { + "shape": "DeleteRowResponse" + }, + "errors": [ + { + "shape": "InvalidInputException" + } + ], + "documentation": "

Performs a get row operation no output

" + } + }, + "shapes": { + "GetRowRequest": { + "type": "structure", + "members": { + "StringMember": { + "shape": "String", + "documentation": "

A string Memer

" + } + } + }, + "GetRowResponse": { + "type": "structure", + "members": { + "StringMember": { + "shape": "String", + "documentation": "

A string Memer

" + } + } + }, + "PutRowRequest": { + "type": "structure", + "members": { + "StringMember": { + "shape": "String", + "documentation": "

A string Memer

" + } + } + }, + "PutRowResponse": { + "type": "structure", + "members": { + "StringMember": { + "shape": "String", + "documentation": "

A string Memer

" + } + } + }, + "DeleteRowRequest": { + "type": "structure", + "members": { + "StringMember": { + "shape": "String", + "documentation": "

A string Memer

" + } + } + }, + "DeleteRowResponse": { + "type": "structure", + "members": { + "StringMember": { + "shape": "String", + "documentation": "

A string Memer

" + } + } + }, + "InvalidInputException": { + "type": "structure", + "members": { + "message": { + "shape": "invalidInputMessage" + } + }, + "documentation": "

The request was rejected because an invalid or out-of-range value was supplied for an input parameter.

", + "error": { + "code": "InvalidInput", + "httpStatusCode": 400, + "senderFault": true + }, + "exception": true + }, + "String":{"type":"string"}, + "invalidInputMessage":{"type":"string"} + }, + "documentation": "A Database Service with Fine granularity authorization schemes" +}