81 lines
4.4 KiB
JavaScript
81 lines
4.4 KiB
JavaScript
import { setCredentialFeature } from "@aws-sdk/core/client";
|
|
import { CredentialsProviderError } from "@smithy/property-provider";
|
|
import { getProfileName } from "@smithy/shared-ini-file-loader";
|
|
import { resolveCredentialSource } from "./resolveCredentialSource";
|
|
import { resolveProfileData } from "./resolveProfileData";
|
|
export const isAssumeRoleProfile = (arg, { profile = "default", logger } = {}) => {
|
|
return (Boolean(arg) &&
|
|
typeof arg === "object" &&
|
|
typeof arg.role_arn === "string" &&
|
|
["undefined", "string"].indexOf(typeof arg.role_session_name) > -1 &&
|
|
["undefined", "string"].indexOf(typeof arg.external_id) > -1 &&
|
|
["undefined", "string"].indexOf(typeof arg.mfa_serial) > -1 &&
|
|
(isAssumeRoleWithSourceProfile(arg, { profile, logger }) || isCredentialSourceProfile(arg, { profile, logger })));
|
|
};
|
|
const isAssumeRoleWithSourceProfile = (arg, { profile, logger }) => {
|
|
const withSourceProfile = typeof arg.source_profile === "string" && typeof arg.credential_source === "undefined";
|
|
if (withSourceProfile) {
|
|
logger?.debug?.(` ${profile} isAssumeRoleWithSourceProfile source_profile=${arg.source_profile}`);
|
|
}
|
|
return withSourceProfile;
|
|
};
|
|
const isCredentialSourceProfile = (arg, { profile, logger }) => {
|
|
const withProviderProfile = typeof arg.credential_source === "string" && typeof arg.source_profile === "undefined";
|
|
if (withProviderProfile) {
|
|
logger?.debug?.(` ${profile} isCredentialSourceProfile credential_source=${arg.credential_source}`);
|
|
}
|
|
return withProviderProfile;
|
|
};
|
|
export const resolveAssumeRoleCredentials = async (profileName, profiles, options, visitedProfiles = {}) => {
|
|
options.logger?.debug("@aws-sdk/credential-provider-ini - resolveAssumeRoleCredentials (STS)");
|
|
const profileData = profiles[profileName];
|
|
const { source_profile, region } = profileData;
|
|
if (!options.roleAssumer) {
|
|
const { getDefaultRoleAssumer } = await import("@aws-sdk/nested-clients/sts");
|
|
options.roleAssumer = getDefaultRoleAssumer({
|
|
...options.clientConfig,
|
|
credentialProviderLogger: options.logger,
|
|
parentClientConfig: {
|
|
...options?.parentClientConfig,
|
|
region: region ?? options?.parentClientConfig?.region,
|
|
},
|
|
}, options.clientPlugins);
|
|
}
|
|
if (source_profile && source_profile in visitedProfiles) {
|
|
throw new CredentialsProviderError(`Detected a cycle attempting to resolve credentials for profile` +
|
|
` ${getProfileName(options)}. Profiles visited: ` +
|
|
Object.keys(visitedProfiles).join(", "), { logger: options.logger });
|
|
}
|
|
options.logger?.debug(`@aws-sdk/credential-provider-ini - finding credential resolver using ${source_profile ? `source_profile=[${source_profile}]` : `profile=[${profileName}]`}`);
|
|
const sourceCredsProvider = source_profile
|
|
? resolveProfileData(source_profile, profiles, options, {
|
|
...visitedProfiles,
|
|
[source_profile]: true,
|
|
}, isCredentialSourceWithoutRoleArn(profiles[source_profile] ?? {}))
|
|
: (await resolveCredentialSource(profileData.credential_source, profileName, options.logger)(options))();
|
|
if (isCredentialSourceWithoutRoleArn(profileData)) {
|
|
return sourceCredsProvider.then((creds) => setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
|
|
}
|
|
else {
|
|
const params = {
|
|
RoleArn: profileData.role_arn,
|
|
RoleSessionName: profileData.role_session_name || `aws-sdk-js-${Date.now()}`,
|
|
ExternalId: profileData.external_id,
|
|
DurationSeconds: parseInt(profileData.duration_seconds || "3600", 10),
|
|
};
|
|
const { mfa_serial } = profileData;
|
|
if (mfa_serial) {
|
|
if (!options.mfaCodeProvider) {
|
|
throw new CredentialsProviderError(`Profile ${profileName} requires multi-factor authentication, but no MFA code callback was provided.`, { logger: options.logger, tryNextLink: false });
|
|
}
|
|
params.SerialNumber = mfa_serial;
|
|
params.TokenCode = await options.mfaCodeProvider(mfa_serial);
|
|
}
|
|
const sourceCreds = await sourceCredsProvider;
|
|
return options.roleAssumer(sourceCreds, params).then((creds) => setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
|
|
}
|
|
};
|
|
const isCredentialSourceWithoutRoleArn = (section) => {
|
|
return !section.role_arn && !!section.credential_source;
|
|
};
|