From 5dbf48b07c3ed525db2d2da5898293c693f8df1d Mon Sep 17 00:00:00 2001 From: George Fu Date: Wed, 7 Aug 2024 16:51:14 +0000 Subject: [PATCH] feat(core/httpAuthSchemes): set configuration sources for sigv4a signingRegionSet --- .../src/auth/httpAuthSchemeProvider.ts | 13 ++-- .../src/runtimeConfig.ts | 3 +- .../src/auth/httpAuthSchemeProvider.ts | 13 ++-- .../client-eventbridge/src/runtimeConfig.ts | 3 +- .../src/auth/httpAuthSchemeProvider.ts | 13 ++-- clients/client-s3/src/runtimeConfig.ts | 3 +- .../typescript/codegen/AwsTraitsUtils.java | 8 ++- .../integration/AwsSdkCustomizeSigV4Auth.java | 43 +++++++++++- packages/core/package.json | 1 + .../httpAuthSchemes/aws_sdk/index.ts | 1 + .../aws_sdk/resolveAwsSdkSigV4AConfig.ts | 67 +++++++++++++++++++ 11 files changed, 150 insertions(+), 18 deletions(-) create mode 100644 packages/core/src/submodules/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4AConfig.ts diff --git a/clients/client-cloudfront-keyvaluestore/src/auth/httpAuthSchemeProvider.ts b/clients/client-cloudfront-keyvaluestore/src/auth/httpAuthSchemeProvider.ts index e7553783a0a6e..d7a607de4c957 100644 --- a/clients/client-cloudfront-keyvaluestore/src/auth/httpAuthSchemeProvider.ts +++ b/clients/client-cloudfront-keyvaluestore/src/auth/httpAuthSchemeProvider.ts @@ -1,8 +1,12 @@ // smithy-typescript generated code import { + AwsSdkSigV4AAuthInputConfig, + AwsSdkSigV4AAuthResolvedConfig, + AwsSdkSigV4APreviouslyResolved, AwsSdkSigV4AuthInputConfig, AwsSdkSigV4AuthResolvedConfig, AwsSdkSigV4PreviouslyResolved, + resolveAwsSdkSigV4AConfig, resolveAwsSdkSigV4Config, } from "@aws-sdk/core"; import { signatureV4CrtContainer } from "@aws-sdk/signature-v4-multi-region"; @@ -297,7 +301,7 @@ export const defaultCloudFrontKeyValueStoreHttpAuthSchemeProvider: CloudFrontKey /** * @internal */ -export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig { +export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig, AwsSdkSigV4AAuthInputConfig { /** * Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. * @internal @@ -314,7 +318,7 @@ export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig { /** * @internal */ -export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig { +export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig, AwsSdkSigV4AAuthResolvedConfig { /** * Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. * @internal @@ -332,10 +336,11 @@ export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedCon * @internal */ export const resolveHttpAuthSchemeConfig = ( - config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved + config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved & AwsSdkSigV4APreviouslyResolved ): T & HttpAuthSchemeResolvedConfig => { const config_0 = resolveAwsSdkSigV4Config(config); + const config_1 = resolveAwsSdkSigV4AConfig(config_0); return { - ...config_0, + ...config_1, } as T & HttpAuthSchemeResolvedConfig; }; diff --git a/clients/client-cloudfront-keyvaluestore/src/runtimeConfig.ts b/clients/client-cloudfront-keyvaluestore/src/runtimeConfig.ts index 55c9c128ec539..3334debf0a6a6 100644 --- a/clients/client-cloudfront-keyvaluestore/src/runtimeConfig.ts +++ b/clients/client-cloudfront-keyvaluestore/src/runtimeConfig.ts @@ -2,7 +2,7 @@ // @ts-ignore: package.json will be imported from dist folders import packageInfo from "../package.json"; // eslint-disable-line -import { emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core"; +import { NODE_SIGV4A_CONFIG_OPTIONS, emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core"; import { defaultProvider as credentialDefaultProvider } from "@aws-sdk/credential-provider-node"; import { defaultUserAgent } from "@aws-sdk/util-user-agent-node"; import { @@ -52,6 +52,7 @@ export const getRuntimeConfig = (config: CloudFrontKeyValueStoreClientConfig) => default: async () => (await defaultConfigProvider()).retryMode || DEFAULT_RETRY_MODE, }), sha256: config?.sha256 ?? Hash.bind(null, "sha256"), + sigv4aSigningRegionSet: config?.sigv4aSigningRegionSet ?? loadNodeConfig(NODE_SIGV4A_CONFIG_OPTIONS), streamCollector: config?.streamCollector ?? streamCollector, useDualstackEndpoint: config?.useDualstackEndpoint ?? loadNodeConfig(NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS), useFipsEndpoint: config?.useFipsEndpoint ?? loadNodeConfig(NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS), diff --git a/clients/client-eventbridge/src/auth/httpAuthSchemeProvider.ts b/clients/client-eventbridge/src/auth/httpAuthSchemeProvider.ts index 91efc11822087..2cd67398e03fe 100644 --- a/clients/client-eventbridge/src/auth/httpAuthSchemeProvider.ts +++ b/clients/client-eventbridge/src/auth/httpAuthSchemeProvider.ts @@ -1,8 +1,12 @@ // smithy-typescript generated code import { + AwsSdkSigV4AAuthInputConfig, + AwsSdkSigV4AAuthResolvedConfig, + AwsSdkSigV4APreviouslyResolved, AwsSdkSigV4AuthInputConfig, AwsSdkSigV4AuthResolvedConfig, AwsSdkSigV4PreviouslyResolved, + resolveAwsSdkSigV4AConfig, resolveAwsSdkSigV4Config, } from "@aws-sdk/core"; import { signatureV4CrtContainer } from "@aws-sdk/signature-v4-multi-region"; @@ -279,7 +283,7 @@ export const defaultEventBridgeHttpAuthSchemeProvider: EventBridgeHttpAuthScheme /** * @internal */ -export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig { +export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig, AwsSdkSigV4AAuthInputConfig { /** * Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. * @internal @@ -296,7 +300,7 @@ export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig { /** * @internal */ -export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig { +export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig, AwsSdkSigV4AAuthResolvedConfig { /** * Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. * @internal @@ -314,10 +318,11 @@ export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedCon * @internal */ export const resolveHttpAuthSchemeConfig = ( - config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved + config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved & AwsSdkSigV4APreviouslyResolved ): T & HttpAuthSchemeResolvedConfig => { const config_0 = resolveAwsSdkSigV4Config(config); + const config_1 = resolveAwsSdkSigV4AConfig(config_0); return { - ...config_0, + ...config_1, } as T & HttpAuthSchemeResolvedConfig; }; diff --git a/clients/client-eventbridge/src/runtimeConfig.ts b/clients/client-eventbridge/src/runtimeConfig.ts index cfc6e176da839..b93a5f10e715e 100644 --- a/clients/client-eventbridge/src/runtimeConfig.ts +++ b/clients/client-eventbridge/src/runtimeConfig.ts @@ -2,7 +2,7 @@ // @ts-ignore: package.json will be imported from dist folders import packageInfo from "../package.json"; // eslint-disable-line -import { emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core"; +import { NODE_SIGV4A_CONFIG_OPTIONS, emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core"; import { defaultProvider as credentialDefaultProvider } from "@aws-sdk/credential-provider-node"; import { defaultUserAgent } from "@aws-sdk/util-user-agent-node"; import { @@ -52,6 +52,7 @@ export const getRuntimeConfig = (config: EventBridgeClientConfig) => { default: async () => (await defaultConfigProvider()).retryMode || DEFAULT_RETRY_MODE, }), sha256: config?.sha256 ?? Hash.bind(null, "sha256"), + sigv4aSigningRegionSet: config?.sigv4aSigningRegionSet ?? loadNodeConfig(NODE_SIGV4A_CONFIG_OPTIONS), streamCollector: config?.streamCollector ?? streamCollector, useDualstackEndpoint: config?.useDualstackEndpoint ?? loadNodeConfig(NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS), useFipsEndpoint: config?.useFipsEndpoint ?? loadNodeConfig(NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS), diff --git a/clients/client-s3/src/auth/httpAuthSchemeProvider.ts b/clients/client-s3/src/auth/httpAuthSchemeProvider.ts index 8f4b81934a5c1..ea9fd5773dcd3 100644 --- a/clients/client-s3/src/auth/httpAuthSchemeProvider.ts +++ b/clients/client-s3/src/auth/httpAuthSchemeProvider.ts @@ -1,8 +1,12 @@ // smithy-typescript generated code import { + AwsSdkSigV4AAuthInputConfig, + AwsSdkSigV4AAuthResolvedConfig, + AwsSdkSigV4APreviouslyResolved, AwsSdkSigV4AuthInputConfig, AwsSdkSigV4AuthResolvedConfig, AwsSdkSigV4PreviouslyResolved, + resolveAwsSdkSigV4AConfig, resolveAwsSdkSigV4Config, } from "@aws-sdk/core"; import { signatureV4CrtContainer } from "@aws-sdk/signature-v4-multi-region"; @@ -281,7 +285,7 @@ export const defaultS3HttpAuthSchemeProvider: S3HttpAuthSchemeProvider = createE /** * @internal */ -export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig { +export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig, AwsSdkSigV4AAuthInputConfig { /** * Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. * @internal @@ -298,7 +302,7 @@ export interface HttpAuthSchemeInputConfig extends AwsSdkSigV4AuthInputConfig { /** * @internal */ -export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig { +export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedConfig, AwsSdkSigV4AAuthResolvedConfig { /** * Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. * @internal @@ -316,10 +320,11 @@ export interface HttpAuthSchemeResolvedConfig extends AwsSdkSigV4AuthResolvedCon * @internal */ export const resolveHttpAuthSchemeConfig = ( - config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved + config: T & HttpAuthSchemeInputConfig & AwsSdkSigV4PreviouslyResolved & AwsSdkSigV4APreviouslyResolved ): T & HttpAuthSchemeResolvedConfig => { const config_0 = resolveAwsSdkSigV4Config(config); + const config_1 = resolveAwsSdkSigV4AConfig(config_0); return { - ...config_0, + ...config_1, } as T & HttpAuthSchemeResolvedConfig; }; diff --git a/clients/client-s3/src/runtimeConfig.ts b/clients/client-s3/src/runtimeConfig.ts index a029bd3e80b08..89e08626ab8f1 100644 --- a/clients/client-s3/src/runtimeConfig.ts +++ b/clients/client-s3/src/runtimeConfig.ts @@ -2,7 +2,7 @@ // @ts-ignore: package.json will be imported from dist folders import packageInfo from "../package.json"; // eslint-disable-line -import { emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core"; +import { NODE_SIGV4A_CONFIG_OPTIONS, emitWarningIfUnsupportedVersion as awsCheckVersion } from "@aws-sdk/core"; import { defaultProvider as credentialDefaultProvider } from "@aws-sdk/credential-provider-node"; import { NODE_USE_ARN_REGION_CONFIG_OPTIONS } from "@aws-sdk/middleware-bucket-endpoint"; import { NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_OPTIONS } from "@aws-sdk/middleware-sdk-s3"; @@ -62,6 +62,7 @@ export const getRuntimeConfig = (config: S3ClientConfig) => { }), sha1: config?.sha1 ?? Hash.bind(null, "sha1"), sha256: config?.sha256 ?? Hash.bind(null, "sha256"), + sigv4aSigningRegionSet: config?.sigv4aSigningRegionSet ?? loadNodeConfig(NODE_SIGV4A_CONFIG_OPTIONS), streamCollector: config?.streamCollector ?? streamCollector, streamHasher: config?.streamHasher ?? streamHasher, useArnRegion: config?.useArnRegion ?? loadNodeConfig(NODE_USE_ARN_REGION_CONFIG_OPTIONS), diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AwsTraitsUtils.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AwsTraitsUtils.java index 7828466f1016f..f55183ac300a7 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AwsTraitsUtils.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AwsTraitsUtils.java @@ -60,12 +60,16 @@ public static boolean isSigV4Service(ServiceShape serviceShape) { } public static boolean isSigV4AsymmetricService(Model model, TypeScriptSettings settings) { - if (ENDPOINT_RULESET_HTTP_AUTH_SCHEME_SERVICES.contains(settings.getService())) { + return isSigV4AsymmetricService(model, settings.getService(model)); + } + + public static boolean isSigV4AsymmetricService(Model model, ServiceShape service) { + if (ENDPOINT_RULESET_HTTP_AUTH_SCHEME_SERVICES.contains(service.getId())) { return true; } return ServiceIndex.of(model) - .getEffectiveAuthSchemes(settings.getService(), ServiceIndex.AuthSchemeMode.NO_AUTH_AWARE) + .getEffectiveAuthSchemes(service, ServiceIndex.AuthSchemeMode.NO_AUTH_AWARE) .containsKey(SigV4ATrait.ID); } diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/auth/http/integration/AwsSdkCustomizeSigV4Auth.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/auth/http/integration/AwsSdkCustomizeSigV4Auth.java index 82d1ff08d5486..e2619fa15f31c 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/auth/http/integration/AwsSdkCustomizeSigV4Auth.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/auth/http/integration/AwsSdkCustomizeSigV4Auth.java @@ -13,6 +13,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeMap; import java.util.function.Consumer; import software.amazon.smithy.aws.traits.auth.SigV4ATrait; import software.amazon.smithy.aws.traits.auth.SigV4Trait; @@ -104,7 +105,8 @@ public Map> getRuntimeConfigWriters( } case NODE: if (isAwsService(service)) { - return MapUtils.of( + Map> map = new TreeMap>(); + map.put( "credentialDefaultProvider", writer -> { writer .addDependency(AwsDependency.CREDENTIAL_PROVIDER_NODE) @@ -114,6 +116,23 @@ public Map> getRuntimeConfigWriters( AwsCredentialProviderUtils.addAwsCredentialProviderDependencies(service, writer); } ); + if (isSigV4AsymmetricService(model, settings)) { + map.put( + "sigv4aSigningRegionSet", writer -> { + writer.addDependency(TypeScriptDependency.NODE_CONFIG_PROVIDER); + writer.addDependency(AwsDependency.AWS_SDK_CORE); + writer.addImport("loadConfig", "loadNodeConfig", + TypeScriptDependency.NODE_CONFIG_PROVIDER); + writer.addImport( + "NODE_SIGV4A_CONFIG_OPTIONS", + null, + AwsDependency.AWS_SDK_CORE + ); + writer.write("loadNodeConfig(NODE_SIGV4A_CONFIG_OPTIONS)"); + } + ); + } + return map; } default: return Collections.emptyMap(); @@ -180,6 +199,28 @@ public void customizeSupportedHttpAuthSchemes( .getHttpAuthScheme(SigV4Trait.ID) .toBuilder() .schemeId(SigV4ATrait.ID) + .addResolveConfigFunction(ResolveConfigFunction.builder() + .resolveConfigFunction(Symbol.builder() + .name("resolveAwsSdkSigV4AConfig") + .namespace(AwsDependency.AWS_SDK_CORE.getPackageName(), "/") + .addDependency(AwsDependency.AWS_SDK_CORE) + .build()) + .inputConfig(Symbol.builder() + .name("AwsSdkSigV4AAuthInputConfig") + .namespace(AwsDependency.AWS_SDK_CORE.getPackageName(), "/") + .addDependency(AwsDependency.AWS_SDK_CORE) + .build()) + .previouslyResolved(Symbol.builder() + .name("AwsSdkSigV4APreviouslyResolved") + .namespace(AwsDependency.AWS_SDK_CORE.getPackageName(), "/") + .addDependency(AwsDependency.AWS_SDK_CORE) + .build()) + .resolvedConfig(Symbol.builder() + .name("AwsSdkSigV4AAuthResolvedConfig") + .namespace(AwsDependency.AWS_SDK_CORE.getPackageName(), "/") + .addDependency(AwsDependency.AWS_SDK_CORE) + .build()) + .build()) .putDefaultSigner(LanguageTarget.SHARED, w -> w .addDependency(AwsDependency.AWS_SDK_CORE) .addImport("AwsSdkSigV4ASigner", null, AwsDependency.AWS_SDK_CORE) diff --git a/packages/core/package.json b/packages/core/package.json index 0d05e67e439cb..f27c52e92ea8a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -77,6 +77,7 @@ "dependencies": { "@smithy/core": "^2.3.2", "@smithy/node-config-provider": "^3.1.4", + "@smithy/property-provider": "^3.1.3", "@smithy/protocol-http": "^4.1.0", "@smithy/signature-v4": "^4.1.0", "@smithy/smithy-client": "^3.1.12", diff --git a/packages/core/src/submodules/httpAuthSchemes/aws_sdk/index.ts b/packages/core/src/submodules/httpAuthSchemes/aws_sdk/index.ts index 62172b7877856..fad9615bebf44 100644 --- a/packages/core/src/submodules/httpAuthSchemes/aws_sdk/index.ts +++ b/packages/core/src/submodules/httpAuthSchemes/aws_sdk/index.ts @@ -1,3 +1,4 @@ export { AwsSdkSigV4Signer, AWSSDKSigV4Signer, validateSigningProperties } from "./AwsSdkSigV4Signer"; export { AwsSdkSigV4ASigner } from "./AwsSdkSigV4ASigner"; +export * from "./resolveAwsSdkSigV4AConfig"; export * from "./resolveAwsSdkSigV4Config"; diff --git a/packages/core/src/submodules/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4AConfig.ts b/packages/core/src/submodules/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4AConfig.ts new file mode 100644 index 0000000000000..2666cdb7575a3 --- /dev/null +++ b/packages/core/src/submodules/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4AConfig.ts @@ -0,0 +1,67 @@ +import { normalizeProvider } from "@smithy/core"; +import { LoadedConfigSelectors } from "@smithy/node-config-provider"; +import { ProviderError } from "@smithy/property-provider"; +import { Profile, Provider } from "@smithy/types"; + +/** + * @public + */ +export interface AwsSdkSigV4AAuthInputConfig { + /** + * This option will override the AWS sigv4a + * signing regionSet from any other source. + * + * The lookup order is: + * 1. this value + * 2. configuration file value of sigv4a_signing_region_set. + * 3. environment value of AWS_SIGV4A_SIGNING_REGION_SET. + * 4. signingRegionSet given by endpoint resolution. + * 5. the singular region of the SDK client. + */ + sigv4aSigningRegionSet?: string[] | undefined | Provider; +} + +/** + * @internal + */ +export interface AwsSdkSigV4APreviouslyResolved {} + +/** + * @internal + */ +export interface AwsSdkSigV4AAuthResolvedConfig { + sigv4aSigningRegionSet: Provider; +} + +/** + * @internal + */ +export const resolveAwsSdkSigV4AConfig = ( + config: T & AwsSdkSigV4AAuthInputConfig & AwsSdkSigV4APreviouslyResolved +): T & AwsSdkSigV4AAuthResolvedConfig => { + config.sigv4aSigningRegionSet = normalizeProvider(config.sigv4aSigningRegionSet ?? []); + return config as T & AwsSdkSigV4AAuthResolvedConfig; +}; + +/** + * @internal + */ +export const NODE_SIGV4A_CONFIG_OPTIONS: LoadedConfigSelectors = { + environmentVariableSelector(env: Record): string[] | undefined { + if (env.AWS_SIGV4A_SIGNING_REGION_SET) { + return env.AWS_SIGV4A_SIGNING_REGION_SET.split(",").map((_) => _.trim()); + } + throw new ProviderError("AWS_SIGV4A_SIGNING_REGION_SET not set in env.", { + tryNextLink: true, + }); + }, + configFileSelector(profile: Profile): string[] | undefined { + if (profile.sigv4a_signing_region_set) { + return ((profile.sigv4a_signing_region_set as string) ?? "").split(",").map((_) => _.trim()); + } + throw new ProviderError("sigv4a_signing_region_set not set in profile.", { + tryNextLink: true, + }); + }, + default: [], +};