From 2d01b33a883ffcb57c6bb259f63520bd112f757c Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Mon, 18 Dec 2023 16:52:28 -0500 Subject: [PATCH 1/4] feat(experimentalIdentityAndAuth): enable `experimentalIdentityAndAuth` for SQS --- codegen/sdk-codegen/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/codegen/sdk-codegen/build.gradle.kts b/codegen/sdk-codegen/build.gradle.kts index b5bd26917125e..83b4a08bbd392 100644 --- a/codegen/sdk-codegen/build.gradle.kts +++ b/codegen/sdk-codegen/build.gradle.kts @@ -106,6 +106,7 @@ tasks.register("generate-smithy-build") { val experimentalIdentityAndAuthServices = setOf( ShapeId.from("com.amazonaws.codecatalyst#CodeCatalyst"), ShapeId.from("com.amazonaws.sts#AWSSecurityTokenServiceV20110615"), + ShapeId.from("com.amazonaws.sqs#AmazonSQS"), ) val projectionContents = Node.objectNodeBuilder() .withMember("imports", Node.fromStrings("${models.getAbsolutePath()}${File.separator}${file.name}")) From 5a0f39f6d5d97e7f83c632eb3e12be9694672bc1 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Mon, 18 Dec 2023 16:56:56 -0500 Subject: [PATCH 2/4] chore(codegen): generate client-sqs --- clients/client-sqs/package.json | 3 +- clients/client-sqs/src/SQSClient.ts | 67 ++++++--- .../auth/httpAuthExtensionConfiguration.ts | 72 +++++++++ .../src/auth/httpAuthSchemeProvider.ts | 137 ++++++++++++++++++ .../client-sqs/src/extensionConfiguration.ts | 5 +- .../client-sqs/src/runtimeConfig.shared.ts | 11 ++ clients/client-sqs/src/runtimeExtensions.ts | 3 + 7 files changed, 274 insertions(+), 24 deletions(-) create mode 100644 clients/client-sqs/src/auth/httpAuthExtensionConfiguration.ts create mode 100644 clients/client-sqs/src/auth/httpAuthSchemeProvider.ts diff --git a/clients/client-sqs/package.json b/clients/client-sqs/package.json index 5a0035b61f818..158df26afc0a4 100644 --- a/clients/client-sqs/package.json +++ b/clients/client-sqs/package.json @@ -27,7 +27,6 @@ "@aws-sdk/middleware-logger": "*", "@aws-sdk/middleware-recursion-detection": "*", "@aws-sdk/middleware-sdk-sqs": "*", - "@aws-sdk/middleware-signing": "*", "@aws-sdk/middleware-user-agent": "*", "@aws-sdk/region-config-resolver": "*", "@aws-sdk/types": "*", @@ -35,6 +34,7 @@ "@aws-sdk/util-user-agent-browser": "*", "@aws-sdk/util-user-agent-node": "*", "@smithy/config-resolver": "^2.0.21", + "@smithy/core": "^1.2.0", "@smithy/fetch-http-handler": "^2.3.1", "@smithy/hash-node": "^2.0.17", "@smithy/invalid-dependency": "^2.0.15", @@ -56,6 +56,7 @@ "@smithy/util-defaults-mode-browser": "^2.0.22", "@smithy/util-defaults-mode-node": "^2.0.29", "@smithy/util-endpoints": "^1.0.7", + "@smithy/util-middleware": "^2.0.8", "@smithy/util-retry": "^2.0.8", "@smithy/util-utf8": "^2.0.2", "tslib": "^2.5.0" diff --git a/clients/client-sqs/src/SQSClient.ts b/clients/client-sqs/src/SQSClient.ts index 457f3d4a2decd..47bee3ab529ba 100644 --- a/clients/client-sqs/src/SQSClient.ts +++ b/clients/client-sqs/src/SQSClient.ts @@ -7,20 +7,18 @@ import { } from "@aws-sdk/middleware-host-header"; import { getLoggerPlugin } from "@aws-sdk/middleware-logger"; import { getRecursionDetectionPlugin } from "@aws-sdk/middleware-recursion-detection"; -import { - AwsAuthInputConfig, - AwsAuthResolvedConfig, - getAwsAuthPlugin, - resolveAwsAuthConfig, -} from "@aws-sdk/middleware-signing"; import { getUserAgentPlugin, resolveUserAgentConfig, UserAgentInputConfig, UserAgentResolvedConfig, } from "@aws-sdk/middleware-user-agent"; -import { Credentials as __Credentials } from "@aws-sdk/types"; import { RegionInputConfig, RegionResolvedConfig, resolveRegionConfig } from "@smithy/config-resolver"; +import { + DefaultIdentityProviderConfig, + getHttpAuthSchemeEndpointRuleSetPlugin, + getHttpSigningPlugin, +} from "@smithy/core"; import { getContentLengthPlugin } from "@smithy/middleware-content-length"; import { EndpointInputConfig, EndpointResolvedConfig, resolveEndpointConfig } from "@smithy/middleware-endpoint"; import { getRetryPlugin, resolveRetryConfig, RetryInputConfig, RetryResolvedConfig } from "@smithy/middleware-retry"; @@ -32,6 +30,7 @@ import { SmithyResolvedConfiguration as __SmithyResolvedConfiguration, } from "@smithy/smithy-client"; import { + AwsCredentialIdentityProvider, BodyLengthCalculator as __BodyLengthCalculator, CheckOptionalClientConfig as __CheckOptionalClientConfig, Checksum as __Checksum, @@ -50,6 +49,12 @@ import { UserAgent as __UserAgent, } from "@smithy/types"; +import { + defaultSQSHttpAuthSchemeParametersProvider, + HttpAuthSchemeInputConfig, + HttpAuthSchemeResolvedConfig, + resolveHttpAuthSchemeConfig, +} from "./auth/httpAuthSchemeProvider"; import { AddPermissionCommandInput, AddPermissionCommandOutput } from "./commands/AddPermissionCommand"; import { CancelMessageMoveTaskCommandInput, @@ -245,28 +250,29 @@ export interface ClientDefaults extends Partial<__SmithyResolvedConfiguration<__ useFipsEndpoint?: boolean | __Provider; /** - * The AWS region to which this client will send requests + * A constructor for a class implementing the {@link __Checksum} interface + * that computes MD5 hashes. + * @internal */ - region?: string | __Provider; + md5?: __ChecksumConstructor | __HashConstructor; /** - * Default credentials provider; Not available in browser runtime. + * The provider populating default tracking information to be sent with `user-agent`, `x-amz-user-agent` header * @internal */ - credentialDefaultProvider?: (input: any) => __Provider<__Credentials>; + defaultUserAgentProvider?: Provider<__UserAgent>; /** - * A constructor for a class implementing the {@link __Checksum} interface - * that computes MD5 hashes. - * @internal + * The AWS region to which this client will send requests */ - md5?: __ChecksumConstructor | __HashConstructor; + region?: string | __Provider; /** - * The provider populating default tracking information to be sent with `user-agent`, `x-amz-user-agent` header + * Default credentials provider; Not available in browser runtime. + * @deprecated * @internal */ - defaultUserAgentProvider?: Provider<__UserAgent>; + credentialDefaultProvider?: (input: any) => AwsCredentialIdentityProvider; /** * Value for how many times a request will be made at most in case of retry. @@ -305,8 +311,8 @@ export type SQSClientConfigType = Partial<__SmithyConfiguration<__HttpHandlerOpt EndpointInputConfig & RetryInputConfig & HostHeaderInputConfig & - AwsAuthInputConfig & UserAgentInputConfig & + HttpAuthSchemeInputConfig & ClientInputEndpointParameters; /** * @public @@ -325,8 +331,8 @@ export type SQSClientResolvedConfigType = __SmithyResolvedConfiguration<__HttpHa EndpointResolvedConfig & RetryResolvedConfig & HostHeaderResolvedConfig & - AwsAuthResolvedConfig & UserAgentResolvedConfig & + HttpAuthSchemeResolvedConfig & ClientResolvedEndpointParameters; /** * @public @@ -422,6 +428,17 @@ export class SQSClient extends __Client< */ readonly config: SQSClientResolvedConfig; + private getDefaultHttpAuthSchemeParametersProvider() { + return defaultSQSHttpAuthSchemeParametersProvider; + } + + private getIdentityProviderConfigProvider() { + return async (config: SQSClientResolvedConfig) => + new DefaultIdentityProviderConfig({ + "aws.auth#sigv4": config.credentials, + }); + } + constructor(...[configuration]: __CheckOptionalClientConfig) { const _config_0 = __getRuntimeConfig(configuration || {}); const _config_1 = resolveClientEndpointParameters(_config_0); @@ -429,8 +446,8 @@ export class SQSClient extends __Client< const _config_3 = resolveEndpointConfig(_config_2); const _config_4 = resolveRetryConfig(_config_3); const _config_5 = resolveHostHeaderConfig(_config_4); - const _config_6 = resolveAwsAuthConfig(_config_5); - const _config_7 = resolveUserAgentConfig(_config_6); + const _config_6 = resolveUserAgentConfig(_config_5); + const _config_7 = resolveHttpAuthSchemeConfig(_config_6); const _config_8 = resolveRuntimeExtensions(_config_7, configuration?.extensions || []); super(_config_8); this.config = _config_8; @@ -439,8 +456,14 @@ export class SQSClient extends __Client< this.middlewareStack.use(getHostHeaderPlugin(this.config)); this.middlewareStack.use(getLoggerPlugin(this.config)); this.middlewareStack.use(getRecursionDetectionPlugin(this.config)); - this.middlewareStack.use(getAwsAuthPlugin(this.config)); this.middlewareStack.use(getUserAgentPlugin(this.config)); + this.middlewareStack.use( + getHttpAuthSchemeEndpointRuleSetPlugin(this.config, { + httpAuthSchemeParametersProvider: this.getDefaultHttpAuthSchemeParametersProvider(), + identityProviderConfigProvider: this.getIdentityProviderConfigProvider(), + }) + ); + this.middlewareStack.use(getHttpSigningPlugin(this.config)); } /** diff --git a/clients/client-sqs/src/auth/httpAuthExtensionConfiguration.ts b/clients/client-sqs/src/auth/httpAuthExtensionConfiguration.ts new file mode 100644 index 0000000000000..8360edba2d330 --- /dev/null +++ b/clients/client-sqs/src/auth/httpAuthExtensionConfiguration.ts @@ -0,0 +1,72 @@ +// smithy-typescript generated code +import { AwsCredentialIdentity, AwsCredentialIdentityProvider, HttpAuthScheme } from "@smithy/types"; + +import { SQSHttpAuthSchemeProvider } from "./httpAuthSchemeProvider"; + +/** + * @internal + */ +export interface HttpAuthExtensionConfiguration { + setHttpAuthScheme(httpAuthScheme: HttpAuthScheme): void; + httpAuthSchemes(): HttpAuthScheme[]; + setHttpAuthSchemeProvider(httpAuthSchemeProvider: SQSHttpAuthSchemeProvider): void; + httpAuthSchemeProvider(): SQSHttpAuthSchemeProvider; + setCredentials(credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider): void; + credentials(): AwsCredentialIdentity | AwsCredentialIdentityProvider | undefined; +} + +/** + * @internal + */ +export type HttpAuthRuntimeConfig = Partial<{ + httpAuthSchemes: HttpAuthScheme[]; + httpAuthSchemeProvider: SQSHttpAuthSchemeProvider; + credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider; +}>; + +/** + * @internal + */ +export const getHttpAuthExtensionConfiguration = ( + runtimeConfig: HttpAuthRuntimeConfig +): HttpAuthExtensionConfiguration => { + const _httpAuthSchemes = runtimeConfig.httpAuthSchemes!; + let _httpAuthSchemeProvider = runtimeConfig.httpAuthSchemeProvider!; + let _credentials = runtimeConfig.credentials; + return { + setHttpAuthScheme(httpAuthScheme: HttpAuthScheme): void { + const index = _httpAuthSchemes.findIndex((scheme) => scheme.schemeId === httpAuthScheme.schemeId); + if (index === -1) { + _httpAuthSchemes.push(httpAuthScheme); + } else { + _httpAuthSchemes.splice(index, 1, httpAuthScheme); + } + }, + httpAuthSchemes(): HttpAuthScheme[] { + return _httpAuthSchemes; + }, + setHttpAuthSchemeProvider(httpAuthSchemeProvider: SQSHttpAuthSchemeProvider): void { + _httpAuthSchemeProvider = httpAuthSchemeProvider; + }, + httpAuthSchemeProvider(): SQSHttpAuthSchemeProvider { + return _httpAuthSchemeProvider; + }, + setCredentials(credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider): void { + _credentials = credentials; + }, + credentials(): AwsCredentialIdentity | AwsCredentialIdentityProvider | undefined { + return _credentials; + }, + }; +}; + +/** + * @internal + */ +export const resolveHttpAuthRuntimeConfig = (config: HttpAuthExtensionConfiguration): HttpAuthRuntimeConfig => { + return { + httpAuthSchemes: config.httpAuthSchemes(), + httpAuthSchemeProvider: config.httpAuthSchemeProvider(), + credentials: config.credentials(), + }; +}; diff --git a/clients/client-sqs/src/auth/httpAuthSchemeProvider.ts b/clients/client-sqs/src/auth/httpAuthSchemeProvider.ts new file mode 100644 index 0000000000000..204eb1d9ca95b --- /dev/null +++ b/clients/client-sqs/src/auth/httpAuthSchemeProvider.ts @@ -0,0 +1,137 @@ +// smithy-typescript generated code +import { + AWSSDKSigV4AuthInputConfig, + AWSSDKSigV4AuthResolvedConfig, + AWSSDKSigV4PreviouslyResolved, + resolveAWSSDKSigV4Config, +} from "@aws-sdk/core"; +import { + HandlerExecutionContext, + HttpAuthOption, + HttpAuthScheme, + HttpAuthSchemeParameters, + HttpAuthSchemeParametersProvider, + HttpAuthSchemeProvider, +} from "@smithy/types"; +import { getSmithyContext, normalizeProvider } from "@smithy/util-middleware"; + +import { SQSClientConfig, SQSClientResolvedConfig } from "../SQSClient"; + +/** + * @internal + */ +export interface SQSHttpAuthSchemeParameters extends HttpAuthSchemeParameters { + region?: string; +} + +/** + * @internal + */ +export interface SQSHttpAuthSchemeParametersProvider + extends HttpAuthSchemeParametersProvider< + SQSClientResolvedConfig, + HandlerExecutionContext, + SQSHttpAuthSchemeParameters, + object + > {} + +/** + * @internal + */ +export const defaultSQSHttpAuthSchemeParametersProvider = async ( + config: SQSClientResolvedConfig, + context: HandlerExecutionContext, + input: object +): Promise => { + return { + operation: getSmithyContext(context).operation as string, + region: + (await normalizeProvider(config.region)()) || + (() => { + throw new Error("expected `region` to be configured for `aws.auth#sigv4`"); + })(), + }; +}; + +function createAwsAuthSigv4HttpAuthOption(authParameters: SQSHttpAuthSchemeParameters): HttpAuthOption { + return { + schemeId: "aws.auth#sigv4", + signingProperties: { + name: "sqs", + region: authParameters.region, + }, + propertiesExtractor: (config: SQSClientConfig, context) => ({ + /** + * @internal + */ + signingProperties: { + config, + context, + }, + }), + }; +} + +/** + * @internal + */ +export interface SQSHttpAuthSchemeProvider extends HttpAuthSchemeProvider {} + +/** + * @internal + */ +export const defaultSQSHttpAuthSchemeProvider: SQSHttpAuthSchemeProvider = (authParameters) => { + const options: HttpAuthOption[] = []; + switch (authParameters.operation) { + default: { + options.push(createAwsAuthSigv4HttpAuthOption(authParameters)); + } + } + return options; +}; + +/** + * @internal + */ +export interface HttpAuthSchemeInputConfig extends AWSSDKSigV4AuthInputConfig { + /** + * experimentalIdentityAndAuth: Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. + * @internal + */ + httpAuthSchemes?: HttpAuthScheme[]; + + /** + * experimentalIdentityAndAuth: Configuration of an HttpAuthSchemeProvider for a client which resolves which HttpAuthScheme to use. + * @internal + */ + httpAuthSchemeProvider?: SQSHttpAuthSchemeProvider; +} + +/** + * @internal + */ +export interface HttpAuthSchemeResolvedConfig extends AWSSDKSigV4AuthResolvedConfig { + /** + * experimentalIdentityAndAuth: Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. + * @internal + */ + readonly httpAuthSchemes: HttpAuthScheme[]; + + /** + * experimentalIdentityAndAuth: Configuration of an HttpAuthSchemeProvider for a client which resolves which HttpAuthScheme to use. + * @internal + */ + readonly httpAuthSchemeProvider: SQSHttpAuthSchemeProvider; +} + +/** + * @internal + */ +export const resolveHttpAuthSchemeConfig = ( + config: T & HttpAuthSchemeInputConfig & AWSSDKSigV4PreviouslyResolved +): T & HttpAuthSchemeResolvedConfig => { + const config_0 = resolveAWSSDKSigV4Config(config); + return { + ...config_0, + } as T & HttpAuthSchemeResolvedConfig; +}; diff --git a/clients/client-sqs/src/extensionConfiguration.ts b/clients/client-sqs/src/extensionConfiguration.ts index fdbe05b79c977..34ce9f7c61af9 100644 --- a/clients/client-sqs/src/extensionConfiguration.ts +++ b/clients/client-sqs/src/extensionConfiguration.ts @@ -3,10 +3,13 @@ import { AwsRegionExtensionConfiguration } from "@aws-sdk/types"; import { HttpHandlerExtensionConfiguration } from "@smithy/protocol-http"; import { DefaultExtensionConfiguration } from "@smithy/types"; +import { HttpAuthExtensionConfiguration } from "./auth/httpAuthExtensionConfiguration"; + /** * @internal */ export interface SQSExtensionConfiguration extends HttpHandlerExtensionConfiguration, DefaultExtensionConfiguration, - AwsRegionExtensionConfiguration {} + AwsRegionExtensionConfiguration, + HttpAuthExtensionConfiguration {} diff --git a/clients/client-sqs/src/runtimeConfig.shared.ts b/clients/client-sqs/src/runtimeConfig.shared.ts index 6027dab48422f..99614b59804a8 100644 --- a/clients/client-sqs/src/runtimeConfig.shared.ts +++ b/clients/client-sqs/src/runtimeConfig.shared.ts @@ -1,9 +1,12 @@ // smithy-typescript generated code +import { AWSSDKSigV4Signer } from "@aws-sdk/core"; import { NoOpLogger } from "@smithy/smithy-client"; +import { IdentityProviderConfig } from "@smithy/types"; import { parseUrl } from "@smithy/url-parser"; import { fromBase64, toBase64 } from "@smithy/util-base64"; import { fromUtf8, toUtf8 } from "@smithy/util-utf8"; +import { defaultSQSHttpAuthSchemeProvider } from "./auth/httpAuthSchemeProvider"; import { defaultEndpointResolver } from "./endpoint/endpointResolver"; import { SQSClientConfig } from "./SQSClient"; @@ -18,6 +21,14 @@ export const getRuntimeConfig = (config: SQSClientConfig) => { disableHostPrefix: config?.disableHostPrefix ?? false, endpointProvider: config?.endpointProvider ?? defaultEndpointResolver, extensions: config?.extensions ?? [], + httpAuthSchemeProvider: config?.httpAuthSchemeProvider ?? defaultSQSHttpAuthSchemeProvider, + httpAuthSchemes: config?.httpAuthSchemes ?? [ + { + schemeId: "aws.auth#sigv4", + identityProvider: (ipc: IdentityProviderConfig) => ipc.getIdentityProvider("aws.auth#sigv4"), + signer: new AWSSDKSigV4Signer(), + }, + ], logger: config?.logger ?? new NoOpLogger(), serviceId: config?.serviceId ?? "SQS", urlParser: config?.urlParser ?? parseUrl, diff --git a/clients/client-sqs/src/runtimeExtensions.ts b/clients/client-sqs/src/runtimeExtensions.ts index c9985abb9ac86..bbf0b23c837d0 100644 --- a/clients/client-sqs/src/runtimeExtensions.ts +++ b/clients/client-sqs/src/runtimeExtensions.ts @@ -6,6 +6,7 @@ import { import { getHttpHandlerExtensionConfiguration, resolveHttpHandlerRuntimeConfig } from "@smithy/protocol-http"; import { getDefaultExtensionConfiguration, resolveDefaultRuntimeConfig } from "@smithy/smithy-client"; +import { getHttpAuthExtensionConfiguration, resolveHttpAuthRuntimeConfig } from "./auth/httpAuthExtensionConfiguration"; import { SQSExtensionConfiguration } from "./extensionConfiguration"; /** @@ -32,6 +33,7 @@ export const resolveRuntimeExtensions = (runtimeConfig: any, extensions: Runtime ...asPartial(getAwsRegionExtensionConfiguration(runtimeConfig)), ...asPartial(getDefaultExtensionConfiguration(runtimeConfig)), ...asPartial(getHttpHandlerExtensionConfiguration(runtimeConfig)), + ...asPartial(getHttpAuthExtensionConfiguration(runtimeConfig)), }; extensions.forEach((extension) => extension.configure(extensionConfiguration)); @@ -41,5 +43,6 @@ export const resolveRuntimeExtensions = (runtimeConfig: any, extensions: Runtime ...resolveAwsRegionExtensionConfiguration(extensionConfiguration), ...resolveDefaultRuntimeConfig(extensionConfiguration), ...resolveHttpHandlerRuntimeConfig(extensionConfiguration), + ...resolveHttpAuthRuntimeConfig(extensionConfiguration), }; }; From d9e117dbbec93abbb0cada1a790a90ae0b290361 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Mon, 18 Dec 2023 16:54:41 -0500 Subject: [PATCH 3/4] feat(experimentalIdentityAndAuth): enable `experimentalIdentityAndAuth` for DynamoDB --- codegen/sdk-codegen/build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/codegen/sdk-codegen/build.gradle.kts b/codegen/sdk-codegen/build.gradle.kts index 83b4a08bbd392..2df015ca252ed 100644 --- a/codegen/sdk-codegen/build.gradle.kts +++ b/codegen/sdk-codegen/build.gradle.kts @@ -107,6 +107,7 @@ tasks.register("generate-smithy-build") { ShapeId.from("com.amazonaws.codecatalyst#CodeCatalyst"), ShapeId.from("com.amazonaws.sts#AWSSecurityTokenServiceV20110615"), ShapeId.from("com.amazonaws.sqs#AmazonSQS"), + ShapeId.from("com.amazonaws.dynamodb#DynamoDB_20120810"), ) val projectionContents = Node.objectNodeBuilder() .withMember("imports", Node.fromStrings("${models.getAbsolutePath()}${File.separator}${file.name}")) From 5b9a31f8d1cf0f220c1dc98f7d01ab81ac190ac9 Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Mon, 18 Dec 2023 16:56:49 -0500 Subject: [PATCH 4/4] chore(codegen): generate client-dynamodb --- clients/client-dynamodb/package.json | 3 +- clients/client-dynamodb/src/DynamoDBClient.ts | 73 ++++++---- .../auth/httpAuthExtensionConfiguration.ts | 72 +++++++++ .../src/auth/httpAuthSchemeProvider.ts | 137 ++++++++++++++++++ .../src/extensionConfiguration.ts | 5 +- .../src/runtimeConfig.shared.ts | 11 ++ .../client-dynamodb/src/runtimeExtensions.ts | 3 + 7 files changed, 277 insertions(+), 27 deletions(-) create mode 100644 clients/client-dynamodb/src/auth/httpAuthExtensionConfiguration.ts create mode 100644 clients/client-dynamodb/src/auth/httpAuthSchemeProvider.ts diff --git a/clients/client-dynamodb/package.json b/clients/client-dynamodb/package.json index 69bbe727ade9f..571573775eafe 100644 --- a/clients/client-dynamodb/package.json +++ b/clients/client-dynamodb/package.json @@ -27,7 +27,6 @@ "@aws-sdk/middleware-host-header": "*", "@aws-sdk/middleware-logger": "*", "@aws-sdk/middleware-recursion-detection": "*", - "@aws-sdk/middleware-signing": "*", "@aws-sdk/middleware-user-agent": "*", "@aws-sdk/region-config-resolver": "*", "@aws-sdk/types": "*", @@ -35,6 +34,7 @@ "@aws-sdk/util-user-agent-browser": "*", "@aws-sdk/util-user-agent-node": "*", "@smithy/config-resolver": "^2.0.21", + "@smithy/core": "^1.2.0", "@smithy/fetch-http-handler": "^2.3.1", "@smithy/hash-node": "^2.0.17", "@smithy/invalid-dependency": "^2.0.15", @@ -55,6 +55,7 @@ "@smithy/util-defaults-mode-browser": "^2.0.22", "@smithy/util-defaults-mode-node": "^2.0.29", "@smithy/util-endpoints": "^1.0.7", + "@smithy/util-middleware": "^2.0.8", "@smithy/util-retry": "^2.0.8", "@smithy/util-utf8": "^2.0.2", "@smithy/util-waiter": "^2.0.15", diff --git a/clients/client-dynamodb/src/DynamoDBClient.ts b/clients/client-dynamodb/src/DynamoDBClient.ts index f8084019806e0..96adb0c0e5f9e 100644 --- a/clients/client-dynamodb/src/DynamoDBClient.ts +++ b/clients/client-dynamodb/src/DynamoDBClient.ts @@ -12,20 +12,18 @@ import { } from "@aws-sdk/middleware-host-header"; import { getLoggerPlugin } from "@aws-sdk/middleware-logger"; import { getRecursionDetectionPlugin } from "@aws-sdk/middleware-recursion-detection"; -import { - AwsAuthInputConfig, - AwsAuthResolvedConfig, - getAwsAuthPlugin, - resolveAwsAuthConfig, -} from "@aws-sdk/middleware-signing"; import { getUserAgentPlugin, resolveUserAgentConfig, UserAgentInputConfig, UserAgentResolvedConfig, } from "@aws-sdk/middleware-user-agent"; -import { Credentials as __Credentials } from "@aws-sdk/types"; import { RegionInputConfig, RegionResolvedConfig, resolveRegionConfig } from "@smithy/config-resolver"; +import { + DefaultIdentityProviderConfig, + getHttpAuthSchemeEndpointRuleSetPlugin, + getHttpSigningPlugin, +} from "@smithy/core"; import { getContentLengthPlugin } from "@smithy/middleware-content-length"; import { EndpointInputConfig, EndpointResolvedConfig, resolveEndpointConfig } from "@smithy/middleware-endpoint"; import { getRetryPlugin, resolveRetryConfig, RetryInputConfig, RetryResolvedConfig } from "@smithy/middleware-retry"; @@ -37,6 +35,7 @@ import { SmithyResolvedConfiguration as __SmithyResolvedConfiguration, } from "@smithy/smithy-client"; import { + AwsCredentialIdentityProvider, BodyLengthCalculator as __BodyLengthCalculator, CheckOptionalClientConfig as __CheckOptionalClientConfig, ChecksumConstructor as __ChecksumConstructor, @@ -53,6 +52,12 @@ import { UserAgent as __UserAgent, } from "@smithy/types"; +import { + defaultDynamoDBHttpAuthSchemeParametersProvider, + HttpAuthSchemeInputConfig, + HttpAuthSchemeResolvedConfig, + resolveHttpAuthSchemeConfig, +} from "./auth/httpAuthSchemeProvider"; import { BatchExecuteStatementCommandInput, BatchExecuteStatementCommandOutput, @@ -375,28 +380,22 @@ export interface ClientDefaults extends Partial<__SmithyResolvedConfiguration<__ useFipsEndpoint?: boolean | __Provider; /** - * The AWS region to which this client will send requests - */ - region?: string | __Provider; - - /** - * Default credentials provider; Not available in browser runtime. + * The provider populating default tracking information to be sent with `user-agent`, `x-amz-user-agent` header * @internal */ - credentialDefaultProvider?: (input: any) => __Provider<__Credentials>; + defaultUserAgentProvider?: Provider<__UserAgent>; /** - * The provider populating default tracking information to be sent with `user-agent`, `x-amz-user-agent` header - * @internal + * The AWS region to which this client will send requests */ - defaultUserAgentProvider?: Provider<__UserAgent>; + region?: string | __Provider; /** - * The provider which populates default for endpointDiscoveryEnabled configuration, if it's - * not passed during client creation. + * Default credentials provider; Not available in browser runtime. + * @deprecated * @internal */ - endpointDiscoveryEnabledProvider?: __Provider; + credentialDefaultProvider?: (input: any) => AwsCredentialIdentityProvider; /** * Value for how many times a request will be made at most in case of retry. @@ -424,6 +423,13 @@ export interface ClientDefaults extends Partial<__SmithyResolvedConfiguration<__ * The {@link @smithy/smithy-client#DefaultsMode} that will be used to determine how certain default configuration options are resolved in the SDK. */ defaultsMode?: __DefaultsMode | __Provider<__DefaultsMode>; + + /** + * The provider which populates default for endpointDiscoveryEnabled configuration, if it's + * not passed during client creation. + * @internal + */ + endpointDiscoveryEnabledProvider?: __Provider; } /** @@ -435,8 +441,8 @@ export type DynamoDBClientConfigType = Partial<__SmithyConfiguration<__HttpHandl EndpointInputConfig & RetryInputConfig & HostHeaderInputConfig & - AwsAuthInputConfig & UserAgentInputConfig & + HttpAuthSchemeInputConfig & EndpointDiscoveryInputConfig & ClientInputEndpointParameters; /** @@ -456,8 +462,8 @@ export type DynamoDBClientResolvedConfigType = __SmithyResolvedConfiguration<__H EndpointResolvedConfig & RetryResolvedConfig & HostHeaderResolvedConfig & - AwsAuthResolvedConfig & UserAgentResolvedConfig & + HttpAuthSchemeResolvedConfig & EndpointDiscoveryResolvedConfig & ClientResolvedEndpointParameters; /** @@ -498,6 +504,17 @@ export class DynamoDBClient extends __Client< */ readonly config: DynamoDBClientResolvedConfig; + private getDefaultHttpAuthSchemeParametersProvider() { + return defaultDynamoDBHttpAuthSchemeParametersProvider; + } + + private getIdentityProviderConfigProvider() { + return async (config: DynamoDBClientResolvedConfig) => + new DefaultIdentityProviderConfig({ + "aws.auth#sigv4": config.credentials, + }); + } + constructor(...[configuration]: __CheckOptionalClientConfig) { const _config_0 = __getRuntimeConfig(configuration || {}); const _config_1 = resolveClientEndpointParameters(_config_0); @@ -505,8 +522,8 @@ export class DynamoDBClient extends __Client< const _config_3 = resolveEndpointConfig(_config_2); const _config_4 = resolveRetryConfig(_config_3); const _config_5 = resolveHostHeaderConfig(_config_4); - const _config_6 = resolveAwsAuthConfig(_config_5); - const _config_7 = resolveUserAgentConfig(_config_6); + const _config_6 = resolveUserAgentConfig(_config_5); + const _config_7 = resolveHttpAuthSchemeConfig(_config_6); const _config_8 = resolveEndpointDiscoveryConfig(_config_7, { endpointDiscoveryCommandCtor: DescribeEndpointsCommand, }); @@ -518,8 +535,14 @@ export class DynamoDBClient extends __Client< this.middlewareStack.use(getHostHeaderPlugin(this.config)); this.middlewareStack.use(getLoggerPlugin(this.config)); this.middlewareStack.use(getRecursionDetectionPlugin(this.config)); - this.middlewareStack.use(getAwsAuthPlugin(this.config)); this.middlewareStack.use(getUserAgentPlugin(this.config)); + this.middlewareStack.use( + getHttpAuthSchemeEndpointRuleSetPlugin(this.config, { + httpAuthSchemeParametersProvider: this.getDefaultHttpAuthSchemeParametersProvider(), + identityProviderConfigProvider: this.getIdentityProviderConfigProvider(), + }) + ); + this.middlewareStack.use(getHttpSigningPlugin(this.config)); } /** diff --git a/clients/client-dynamodb/src/auth/httpAuthExtensionConfiguration.ts b/clients/client-dynamodb/src/auth/httpAuthExtensionConfiguration.ts new file mode 100644 index 0000000000000..f60b6472b850c --- /dev/null +++ b/clients/client-dynamodb/src/auth/httpAuthExtensionConfiguration.ts @@ -0,0 +1,72 @@ +// smithy-typescript generated code +import { AwsCredentialIdentity, AwsCredentialIdentityProvider, HttpAuthScheme } from "@smithy/types"; + +import { DynamoDBHttpAuthSchemeProvider } from "./httpAuthSchemeProvider"; + +/** + * @internal + */ +export interface HttpAuthExtensionConfiguration { + setHttpAuthScheme(httpAuthScheme: HttpAuthScheme): void; + httpAuthSchemes(): HttpAuthScheme[]; + setHttpAuthSchemeProvider(httpAuthSchemeProvider: DynamoDBHttpAuthSchemeProvider): void; + httpAuthSchemeProvider(): DynamoDBHttpAuthSchemeProvider; + setCredentials(credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider): void; + credentials(): AwsCredentialIdentity | AwsCredentialIdentityProvider | undefined; +} + +/** + * @internal + */ +export type HttpAuthRuntimeConfig = Partial<{ + httpAuthSchemes: HttpAuthScheme[]; + httpAuthSchemeProvider: DynamoDBHttpAuthSchemeProvider; + credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider; +}>; + +/** + * @internal + */ +export const getHttpAuthExtensionConfiguration = ( + runtimeConfig: HttpAuthRuntimeConfig +): HttpAuthExtensionConfiguration => { + const _httpAuthSchemes = runtimeConfig.httpAuthSchemes!; + let _httpAuthSchemeProvider = runtimeConfig.httpAuthSchemeProvider!; + let _credentials = runtimeConfig.credentials; + return { + setHttpAuthScheme(httpAuthScheme: HttpAuthScheme): void { + const index = _httpAuthSchemes.findIndex((scheme) => scheme.schemeId === httpAuthScheme.schemeId); + if (index === -1) { + _httpAuthSchemes.push(httpAuthScheme); + } else { + _httpAuthSchemes.splice(index, 1, httpAuthScheme); + } + }, + httpAuthSchemes(): HttpAuthScheme[] { + return _httpAuthSchemes; + }, + setHttpAuthSchemeProvider(httpAuthSchemeProvider: DynamoDBHttpAuthSchemeProvider): void { + _httpAuthSchemeProvider = httpAuthSchemeProvider; + }, + httpAuthSchemeProvider(): DynamoDBHttpAuthSchemeProvider { + return _httpAuthSchemeProvider; + }, + setCredentials(credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider): void { + _credentials = credentials; + }, + credentials(): AwsCredentialIdentity | AwsCredentialIdentityProvider | undefined { + return _credentials; + }, + }; +}; + +/** + * @internal + */ +export const resolveHttpAuthRuntimeConfig = (config: HttpAuthExtensionConfiguration): HttpAuthRuntimeConfig => { + return { + httpAuthSchemes: config.httpAuthSchemes(), + httpAuthSchemeProvider: config.httpAuthSchemeProvider(), + credentials: config.credentials(), + }; +}; diff --git a/clients/client-dynamodb/src/auth/httpAuthSchemeProvider.ts b/clients/client-dynamodb/src/auth/httpAuthSchemeProvider.ts new file mode 100644 index 0000000000000..3ec914784a2c9 --- /dev/null +++ b/clients/client-dynamodb/src/auth/httpAuthSchemeProvider.ts @@ -0,0 +1,137 @@ +// smithy-typescript generated code +import { + AWSSDKSigV4AuthInputConfig, + AWSSDKSigV4AuthResolvedConfig, + AWSSDKSigV4PreviouslyResolved, + resolveAWSSDKSigV4Config, +} from "@aws-sdk/core"; +import { + HandlerExecutionContext, + HttpAuthOption, + HttpAuthScheme, + HttpAuthSchemeParameters, + HttpAuthSchemeParametersProvider, + HttpAuthSchemeProvider, +} from "@smithy/types"; +import { getSmithyContext, normalizeProvider } from "@smithy/util-middleware"; + +import { DynamoDBClientConfig, DynamoDBClientResolvedConfig } from "../DynamoDBClient"; + +/** + * @internal + */ +export interface DynamoDBHttpAuthSchemeParameters extends HttpAuthSchemeParameters { + region?: string; +} + +/** + * @internal + */ +export interface DynamoDBHttpAuthSchemeParametersProvider + extends HttpAuthSchemeParametersProvider< + DynamoDBClientResolvedConfig, + HandlerExecutionContext, + DynamoDBHttpAuthSchemeParameters, + object + > {} + +/** + * @internal + */ +export const defaultDynamoDBHttpAuthSchemeParametersProvider = async ( + config: DynamoDBClientResolvedConfig, + context: HandlerExecutionContext, + input: object +): Promise => { + return { + operation: getSmithyContext(context).operation as string, + region: + (await normalizeProvider(config.region)()) || + (() => { + throw new Error("expected `region` to be configured for `aws.auth#sigv4`"); + })(), + }; +}; + +function createAwsAuthSigv4HttpAuthOption(authParameters: DynamoDBHttpAuthSchemeParameters): HttpAuthOption { + return { + schemeId: "aws.auth#sigv4", + signingProperties: { + name: "dynamodb", + region: authParameters.region, + }, + propertiesExtractor: (config: DynamoDBClientConfig, context) => ({ + /** + * @internal + */ + signingProperties: { + config, + context, + }, + }), + }; +} + +/** + * @internal + */ +export interface DynamoDBHttpAuthSchemeProvider extends HttpAuthSchemeProvider {} + +/** + * @internal + */ +export const defaultDynamoDBHttpAuthSchemeProvider: DynamoDBHttpAuthSchemeProvider = (authParameters) => { + const options: HttpAuthOption[] = []; + switch (authParameters.operation) { + default: { + options.push(createAwsAuthSigv4HttpAuthOption(authParameters)); + } + } + return options; +}; + +/** + * @internal + */ +export interface HttpAuthSchemeInputConfig extends AWSSDKSigV4AuthInputConfig { + /** + * experimentalIdentityAndAuth: Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. + * @internal + */ + httpAuthSchemes?: HttpAuthScheme[]; + + /** + * experimentalIdentityAndAuth: Configuration of an HttpAuthSchemeProvider for a client which resolves which HttpAuthScheme to use. + * @internal + */ + httpAuthSchemeProvider?: DynamoDBHttpAuthSchemeProvider; +} + +/** + * @internal + */ +export interface HttpAuthSchemeResolvedConfig extends AWSSDKSigV4AuthResolvedConfig { + /** + * experimentalIdentityAndAuth: Configuration of HttpAuthSchemes for a client which provides default identity providers and signers per auth scheme. + * @internal + */ + readonly httpAuthSchemes: HttpAuthScheme[]; + + /** + * experimentalIdentityAndAuth: Configuration of an HttpAuthSchemeProvider for a client which resolves which HttpAuthScheme to use. + * @internal + */ + readonly httpAuthSchemeProvider: DynamoDBHttpAuthSchemeProvider; +} + +/** + * @internal + */ +export const resolveHttpAuthSchemeConfig = ( + config: T & HttpAuthSchemeInputConfig & AWSSDKSigV4PreviouslyResolved +): T & HttpAuthSchemeResolvedConfig => { + const config_0 = resolveAWSSDKSigV4Config(config); + return { + ...config_0, + } as T & HttpAuthSchemeResolvedConfig; +}; diff --git a/clients/client-dynamodb/src/extensionConfiguration.ts b/clients/client-dynamodb/src/extensionConfiguration.ts index e6b501516ed60..ad01832f2916d 100644 --- a/clients/client-dynamodb/src/extensionConfiguration.ts +++ b/clients/client-dynamodb/src/extensionConfiguration.ts @@ -3,10 +3,13 @@ import { AwsRegionExtensionConfiguration } from "@aws-sdk/types"; import { HttpHandlerExtensionConfiguration } from "@smithy/protocol-http"; import { DefaultExtensionConfiguration } from "@smithy/types"; +import { HttpAuthExtensionConfiguration } from "./auth/httpAuthExtensionConfiguration"; + /** * @internal */ export interface DynamoDBExtensionConfiguration extends HttpHandlerExtensionConfiguration, DefaultExtensionConfiguration, - AwsRegionExtensionConfiguration {} + AwsRegionExtensionConfiguration, + HttpAuthExtensionConfiguration {} diff --git a/clients/client-dynamodb/src/runtimeConfig.shared.ts b/clients/client-dynamodb/src/runtimeConfig.shared.ts index 060f66bf37c1c..2bcd9613e266d 100644 --- a/clients/client-dynamodb/src/runtimeConfig.shared.ts +++ b/clients/client-dynamodb/src/runtimeConfig.shared.ts @@ -1,9 +1,12 @@ // smithy-typescript generated code +import { AWSSDKSigV4Signer } from "@aws-sdk/core"; import { NoOpLogger } from "@smithy/smithy-client"; +import { IdentityProviderConfig } from "@smithy/types"; import { parseUrl } from "@smithy/url-parser"; import { fromBase64, toBase64 } from "@smithy/util-base64"; import { fromUtf8, toUtf8 } from "@smithy/util-utf8"; +import { defaultDynamoDBHttpAuthSchemeProvider } from "./auth/httpAuthSchemeProvider"; import { DynamoDBClientConfig } from "./DynamoDBClient"; import { defaultEndpointResolver } from "./endpoint/endpointResolver"; @@ -18,6 +21,14 @@ export const getRuntimeConfig = (config: DynamoDBClientConfig) => { disableHostPrefix: config?.disableHostPrefix ?? false, endpointProvider: config?.endpointProvider ?? defaultEndpointResolver, extensions: config?.extensions ?? [], + httpAuthSchemeProvider: config?.httpAuthSchemeProvider ?? defaultDynamoDBHttpAuthSchemeProvider, + httpAuthSchemes: config?.httpAuthSchemes ?? [ + { + schemeId: "aws.auth#sigv4", + identityProvider: (ipc: IdentityProviderConfig) => ipc.getIdentityProvider("aws.auth#sigv4"), + signer: new AWSSDKSigV4Signer(), + }, + ], logger: config?.logger ?? new NoOpLogger(), serviceId: config?.serviceId ?? "DynamoDB", urlParser: config?.urlParser ?? parseUrl, diff --git a/clients/client-dynamodb/src/runtimeExtensions.ts b/clients/client-dynamodb/src/runtimeExtensions.ts index b9bad65080762..d85cff2f84d50 100644 --- a/clients/client-dynamodb/src/runtimeExtensions.ts +++ b/clients/client-dynamodb/src/runtimeExtensions.ts @@ -6,6 +6,7 @@ import { import { getHttpHandlerExtensionConfiguration, resolveHttpHandlerRuntimeConfig } from "@smithy/protocol-http"; import { getDefaultExtensionConfiguration, resolveDefaultRuntimeConfig } from "@smithy/smithy-client"; +import { getHttpAuthExtensionConfiguration, resolveHttpAuthRuntimeConfig } from "./auth/httpAuthExtensionConfiguration"; import { DynamoDBExtensionConfiguration } from "./extensionConfiguration"; /** @@ -32,6 +33,7 @@ export const resolveRuntimeExtensions = (runtimeConfig: any, extensions: Runtime ...asPartial(getAwsRegionExtensionConfiguration(runtimeConfig)), ...asPartial(getDefaultExtensionConfiguration(runtimeConfig)), ...asPartial(getHttpHandlerExtensionConfiguration(runtimeConfig)), + ...asPartial(getHttpAuthExtensionConfiguration(runtimeConfig)), }; extensions.forEach((extension) => extension.configure(extensionConfiguration)); @@ -41,5 +43,6 @@ export const resolveRuntimeExtensions = (runtimeConfig: any, extensions: Runtime ...resolveAwsRegionExtensionConfiguration(extensionConfiguration), ...resolveDefaultRuntimeConfig(extensionConfiguration), ...resolveHttpHandlerRuntimeConfig(extensionConfiguration), + ...resolveHttpAuthRuntimeConfig(extensionConfiguration), }; };