Skip to content

Commit

Permalink
feat(credential-providers): make credential providers aware of caller…
Browse files Browse the repository at this point in the history
… client region (#6726)

* feat(credential-providers): make credential providers aware of contextual client region

* chore: update lockfile

* test(credential-provider-node): additional integ tests for cognito

* feat(credential-providers): fix tests, add chaining support

* feat(credential-providers): rename contextClientConfig to callerClientConfig

* Update packages/core/src/submodules/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4Config.ts

Co-authored-by: Trivikram Kamat <[email protected]>

* test: unit test fixes

* feat(credential-providers): rename types

---------

Co-authored-by: Trivikram Kamat <[email protected]>
  • Loading branch information
kuhe and trivikr authored Dec 13, 2024
1 parent 041a906 commit a65995f
Show file tree
Hide file tree
Showing 22 changed files with 666 additions and 82 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"copy-models": "node ./scripts/copy-models",
"extract:docs": "node ./scripts/extract-docs/index.js",
"g:vitest": "cd $INIT_CWD && vitest",
"g:jest": "cd $INIT_CWD && jest",
"generate-clients": "node ./scripts/generate-clients",
"generate:clients:generic": "node ./scripts/generate-clients/generic",
"generate:defaults-mode-provider": "./scripts/generate-defaults-mode-provider/index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,29 +106,31 @@ export const resolveAwsSdkSigV4Config = <T>(
): T & AwsSdkSigV4AuthResolvedConfig => {
let isUserSupplied = false;
// Normalize credentials
let normalizedCreds: AwsCredentialIdentityProvider | undefined;
let credentialsProvider: AwsCredentialIdentityProvider | undefined;
if (config.credentials) {
isUserSupplied = true;
normalizedCreds = memoizeIdentityProvider(config.credentials, isIdentityExpired, doesIdentityRequireRefresh);
credentialsProvider = memoizeIdentityProvider(config.credentials, isIdentityExpired, doesIdentityRequireRefresh);
}
if (!normalizedCreds) {
if (!credentialsProvider) {
// credentialDefaultProvider should always be populated, but in case
// it isn't, set a default identity provider that throws an error
if (config.credentialDefaultProvider) {
normalizedCreds = normalizeProvider(
credentialsProvider = normalizeProvider(
config.credentialDefaultProvider(
Object.assign({}, config as any, {
parentClientConfig: config,
})
)
);
} else {
normalizedCreds = async () => {
credentialsProvider = async () => {
throw new Error("`credentials` is missing");
};
}
}

const boundCredentialsProvider = async () => credentialsProvider!({ callerClientConfig: config });

// Populate sigv4 arguments
const {
// Default for signingEscapePath
Expand Down Expand Up @@ -170,7 +172,7 @@ export const resolveAwsSdkSigV4Config = <T>(

const params: SignatureV4Init & SignatureV4CryptoInit = {
...config,
credentials: normalizedCreds!,
credentials: boundCredentialsProvider,
region: config.signingRegion,
service: config.signingName,
sha256,
Expand Down Expand Up @@ -206,7 +208,7 @@ export const resolveAwsSdkSigV4Config = <T>(

const params: SignatureV4Init & SignatureV4CryptoInit = {
...config,
credentials: normalizedCreds!,
credentials: boundCredentialsProvider,
region: config.signingRegion,
service: config.signingName,
sha256,
Expand All @@ -224,10 +226,10 @@ export const resolveAwsSdkSigV4Config = <T>(
signingEscapePath,
credentials: isUserSupplied
? async () =>
normalizedCreds!().then((creds: AttributedAwsCredentialIdentity) =>
boundCredentialsProvider!().then((creds: AttributedAwsCredentialIdentity) =>
setCredentialFeature(creds, "CREDENTIALS_CODE", "e")
)
: normalizedCreds!,
: boundCredentialsProvider!,
signer,
};
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { CredentialProviderOptions } from "@aws-sdk/types";
import type { AwsIdentityProperties, CredentialProviderOptions, RuntimeConfigIdentityProvider } from "@aws-sdk/types";
import { CredentialsProviderError } from "@smithy/property-provider";
import { AwsCredentialIdentity, Logger, Provider } from "@smithy/types";
import type { AwsCredentialIdentity, Logger } from "@smithy/types";

import { CognitoProviderParameters } from "./CognitoProviderParameters";
import { resolveLogins } from "./resolveLogins";
Expand All @@ -18,7 +18,7 @@ export interface CognitoIdentityCredentials extends AwsCredentialIdentity {
/**
* @internal
*/
export type CognitoIdentityCredentialProvider = Provider<CognitoIdentityCredentials>;
export type CognitoIdentityCredentialProvider = RuntimeConfigIdentityProvider<CognitoIdentityCredentials>;

/**
* @internal
Expand All @@ -29,7 +29,7 @@ export type CognitoIdentityCredentialProvider = Provider<CognitoIdentityCredenti
* Results from this function call are not cached internally.
*/
export function fromCognitoIdentity(parameters: FromCognitoIdentityParameters): CognitoIdentityCredentialProvider {
return async (): Promise<CognitoIdentityCredentials> => {
return async (awsIdentityProperties?: AwsIdentityProperties): Promise<CognitoIdentityCredentials> => {
parameters.logger?.debug("@aws-sdk/credential-provider-cognito-identity - fromCognitoIdentity");
const { GetCredentialsForIdentityCommand, CognitoIdentityClient } = await import("./loadCognitoIdentity");

Expand All @@ -44,7 +44,10 @@ export function fromCognitoIdentity(parameters: FromCognitoIdentityParameters):
parameters.client ??
new CognitoIdentityClient(
Object.assign({}, parameters.clientConfig ?? {}, {
region: parameters.clientConfig?.region ?? parameters.parentClientConfig?.region,
region:
parameters.clientConfig?.region ??
parameters.parentClientConfig?.region ??
awsIdentityProperties?.callerClientConfig?.region,
})
)
).send(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { CredentialProviderOptions } from "@aws-sdk/types";
import type { AwsIdentityProperties, CredentialProviderOptions } from "@aws-sdk/types";
import { CredentialsProviderError } from "@smithy/property-provider";
import { Logger } from "@smithy/types";

Expand Down Expand Up @@ -35,12 +35,15 @@ export function fromCognitoIdentityPool({
? `aws:cognito-identity-credentials:${identityPoolId}:${userIdentifier}`
: undefined;

let provider: CognitoIdentityCredentialProvider = async () => {
let provider: CognitoIdentityCredentialProvider = async (awsIdentityProperties?: AwsIdentityProperties) => {
const { GetIdCommand, CognitoIdentityClient } = await import("./loadCognitoIdentity");
const _client =
client ??
new CognitoIdentityClient(
Object.assign({}, clientConfig ?? {}, { region: clientConfig?.region ?? parentClientConfig?.region })
Object.assign({}, clientConfig ?? {}, {
region:
clientConfig?.region ?? parentClientConfig?.region ?? awsIdentityProperties?.callerClientConfig?.region,
})
);

let identityId: string | undefined = (cacheKey && (await cache.getItem(cacheKey))) as string | undefined;
Expand All @@ -65,11 +68,11 @@ export function fromCognitoIdentityPool({
identityId,
});

return provider();
return provider(awsIdentityProperties);
};

return () =>
provider().catch(async (err) => {
return (awsIdentityProperties?: AwsIdentityProperties) =>
provider(awsIdentityProperties).catch(async (err) => {
if (cacheKey) {
Promise.resolve(cache.removeItem(cacheKey)).catch(() => {});
}
Expand Down
4 changes: 3 additions & 1 deletion packages/credential-provider-ini/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"build:types:downlevel": "downlevel-dts dist-types dist-types/ts3.4",
"clean": "rimraf ./dist-* && rimraf *.tsbuildinfo",
"test": "yarn g:vitest run",
"test:watch": "yarn g:vitest watch"
"test:watch": "yarn g:vitest watch",
"test:integration": "yarn g:vitest run -c vitest.config.integ.ts",
"test:integration:watch": "yarn g:vitest watch -c vitest.config.integ.ts"
},
"keywords": [
"aws",
Expand Down
Loading

0 comments on commit a65995f

Please sign in to comment.