feat: special character check (#797)

* feat: add config option for special character handling

* chore: update dist files
This commit is contained in:
Tom Keller
2023-08-24 13:58:54 -07:00
committed by GitHub
parent fbbf385657
commit a96263310b
4 changed files with 47 additions and 29 deletions
Generated Vendored
+6 -3
View File
@@ -20748,18 +20748,21 @@ function reset() {
exports.reset = reset; exports.reset = reset;
function verifyKeys(creds) { function verifyKeys(creds) {
if (!creds) { if (!creds) {
return; return false;
} }
if (creds.AccessKeyId) { if (creds.AccessKeyId) {
if (SPECIAL_CHARS_REGEX.test(creds.AccessKeyId)) { if (SPECIAL_CHARS_REGEX.test(creds.AccessKeyId)) {
throw new Error('AccessKeyId contains special characters.'); core.debug('AccessKeyId contains special characters.');
return false;
} }
} }
if (creds.SecretAccessKey) { if (creds.SecretAccessKey) {
if (SPECIAL_CHARS_REGEX.test(creds.SecretAccessKey)) { if (SPECIAL_CHARS_REGEX.test(creds.SecretAccessKey)) {
throw new Error('SecretAccessKey contains special characters.'); core.debug('SecretAccessKey contains special characters.');
return false;
} }
} }
return true;
} }
exports.verifyKeys = verifyKeys; exports.verifyKeys = verifyKeys;
// Retries the promise with exponential backoff if the error isRetryable up to maxRetries time. // Retries the promise with exponential backoff if the error isRetryable up to maxRetries time.
+1 -1
View File
@@ -9,7 +9,7 @@ export declare function defaultSleep(ms: number): Promise<unknown>;
declare let sleep: typeof defaultSleep; declare let sleep: typeof defaultSleep;
export declare function withsleep(s: typeof sleep): void; export declare function withsleep(s: typeof sleep): void;
export declare function reset(): void; export declare function reset(): void;
export declare function verifyKeys(creds: Partial<Credentials> | undefined): void; export declare function verifyKeys(creds: Partial<Credentials> | undefined): boolean;
export declare function retryAndBackoff<T>(fn: () => Promise<T>, isRetryable: boolean, maxRetries?: number, retries?: number, base?: number): Promise<T>; export declare function retryAndBackoff<T>(fn: () => Promise<T>, isRetryable: boolean, maxRetries?: number, retries?: number, base?: number): Promise<T>;
export declare function errorMessage(error: unknown): string; export declare function errorMessage(error: unknown): string;
export declare function isDefined<T>(i: T | undefined | null): i is T; export declare function isDefined<T>(i: T | undefined | null): i is T;
Generated Vendored
+39 -24
View File
@@ -113,7 +113,6 @@ async function assumeRoleWithOIDC(params, client, webIdentityToken) {
...params, ...params,
WebIdentityToken: webIdentityToken, WebIdentityToken: webIdentityToken,
})); }));
(0, helpers_1.verifyKeys)(creds.Credentials);
return creds; return creds;
} }
catch (error) { catch (error) {
@@ -136,7 +135,6 @@ async function assumeRoleWithWebIdentityTokenFile(params, client, webIdentityTok
...params, ...params,
WebIdentityToken: webIdentityToken, WebIdentityToken: webIdentityToken,
})); }));
(0, helpers_1.verifyKeys)(creds.Credentials);
return creds; return creds;
} }
catch (error) { catch (error) {
@@ -147,7 +145,6 @@ async function assumeRoleWithCredentials(params, client) {
core.info('Assuming role with user credentials'); core.info('Assuming role with user credentials');
try { try {
const creds = await client.send(new client_sts_1.AssumeRoleCommand({ ...params })); const creds = await client.send(new client_sts_1.AssumeRoleCommand({ ...params }));
(0, helpers_1.verifyKeys)(creds.Credentials);
return creds; return creds;
} }
catch (error) { catch (error) {
@@ -337,18 +334,21 @@ function reset() {
exports.reset = reset; exports.reset = reset;
function verifyKeys(creds) { function verifyKeys(creds) {
if (!creds) { if (!creds) {
return; return false;
} }
if (creds.AccessKeyId) { if (creds.AccessKeyId) {
if (SPECIAL_CHARS_REGEX.test(creds.AccessKeyId)) { if (SPECIAL_CHARS_REGEX.test(creds.AccessKeyId)) {
throw new Error('AccessKeyId contains special characters.'); core.debug('AccessKeyId contains special characters.');
return false;
} }
} }
if (creds.SecretAccessKey) { if (creds.SecretAccessKey) {
if (SPECIAL_CHARS_REGEX.test(creds.SecretAccessKey)) { if (SPECIAL_CHARS_REGEX.test(creds.SecretAccessKey)) {
throw new Error('SecretAccessKey contains special characters.'); core.debug('SecretAccessKey contains special characters.');
return false;
} }
} }
return true;
} }
exports.verifyKeys = verifyKeys; exports.verifyKeys = verifyKeys;
// Retries the promise with exponential backoff if the error isRetryable up to maxRetries time. // Retries the promise with exponential backoff if the error isRetryable up to maxRetries time.
@@ -450,10 +450,19 @@ async function run() {
const unsetCurrentCredentialsInput = core.getInput('unset-current-credentials', { required: false }) || 'false'; const unsetCurrentCredentialsInput = core.getInput('unset-current-credentials', { required: false }) || 'false';
const unsetCurrentCredentials = unsetCurrentCredentialsInput.toLowerCase() === 'true'; const unsetCurrentCredentials = unsetCurrentCredentialsInput.toLowerCase() === 'true';
const disableRetryInput = core.getInput('disable-retry', { required: false }) || 'false'; const disableRetryInput = core.getInput('disable-retry', { required: false }) || 'false';
const disableRetry = disableRetryInput.toLowerCase() === 'true'; let disableRetry = disableRetryInput.toLowerCase() === 'true';
const specialCharacterWorkaroundInput = core.getInput('special-characters-workaround', { required: false }) || 'false';
const specialCharacterWorkaround = specialCharacterWorkaroundInput.toLowerCase() === 'true';
let maxRetries = parseInt(core.getInput('retry-max-attempts', { required: false })) || 12; let maxRetries = parseInt(core.getInput('retry-max-attempts', { required: false })) || 12;
if (maxRetries < 1) { switch (true) {
maxRetries = 1; case specialCharacterWorkaround:
// 😳
disableRetry = false;
maxRetries = 12;
break;
case maxRetries < 1:
maxRetries = 1;
break;
} }
for (const managedSessionPolicy of managedSessionPoliciesInput) { for (const managedSessionPolicy of managedSessionPoliciesInput) {
managedSessionPolicies.push({ arn: managedSessionPolicy }); managedSessionPolicies.push({ arn: managedSessionPolicy });
@@ -522,21 +531,26 @@ async function run() {
} }
// Get role credentials if configured to do so // Get role credentials if configured to do so
if (roleToAssume) { if (roleToAssume) {
const roleCredentials = await (0, helpers_1.retryAndBackoff)(async () => { let roleCredentials;
return (0, assumeRole_1.assumeRole)({ do {
credentialsClient, // eslint-disable-next-line no-await-in-loop
sourceAccountId, roleCredentials = await (0, helpers_1.retryAndBackoff)(async () => {
roleToAssume, return (0, assumeRole_1.assumeRole)({
roleExternalId, credentialsClient,
roleDuration, sourceAccountId,
roleSessionName, roleToAssume,
roleSkipSessionTagging, roleExternalId,
webIdentityTokenFile, roleDuration,
webIdentityToken, roleSessionName,
inlineSessionPolicy, roleSkipSessionTagging,
managedSessionPolicies, webIdentityTokenFile,
}); webIdentityToken,
}, !disableRetry, maxRetries); inlineSessionPolicy,
managedSessionPolicies,
});
}, !disableRetry, maxRetries);
// eslint-disable-next-line no-unmodified-loop-condition
} while (specialCharacterWorkaround && !(0, helpers_1.verifyKeys)(roleCredentials.Credentials));
core.info(`Authenticated as assumedRoleId ${roleCredentials.AssumedRoleUser.AssumedRoleId}`); core.info(`Authenticated as assumedRoleId ${roleCredentials.AssumedRoleUser.AssumedRoleId}`);
(0, helpers_1.exportCredentials)(roleCredentials.Credentials, outputCredentials); (0, helpers_1.exportCredentials)(roleCredentials.Credentials, outputCredentials);
// We need to validate the credentials in 2 of our use-cases // We need to validate the credentials in 2 of our use-cases
@@ -562,6 +576,7 @@ async function run() {
} }
exports.run = run; exports.run = run;
/* c8 ignore start */ /* c8 ignore start */
/* istanbul ignore next */
if (require.main === require.cache[eval('__filename')]) { if (require.main === require.cache[eval('__filename')]) {
(async () => { (async () => {
await run(); await run();
+1 -1
View File
@@ -53,8 +53,8 @@ export async function run() {
switch (true) { switch (true) {
case specialCharacterWorkaround: case specialCharacterWorkaround:
// 😳 // 😳
maxRetries = Number.MAX_SAFE_INTEGER;
disableRetry = false; disableRetry = false;
maxRetries = 12;
break; break;
case maxRetries < 1: case maxRetries < 1:
maxRetries = 1; maxRetries = 1;