diff --git a/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx index 89b348d62b..8ac45ec8cc 100644 --- a/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx +++ b/awx/ui_next/src/components/LaunchPrompt/LaunchPrompt.jsx @@ -7,7 +7,6 @@ import ContentError from '../ContentError'; import ContentLoading from '../ContentLoading'; import { useDismissableError } from '../../util/useRequest'; import mergeExtraVars from '../../util/prompt/mergeExtraVars'; -import getCredentialPasswords from '../../util/prompt/getCredentialPasswords'; import getSurveyValues from '../../util/prompt/getSurveyValues'; import useLaunchSteps from './useLaunchSteps'; import AlertModal from '../AlertModal'; @@ -39,8 +38,7 @@ function PromptModalForm({ } }; const surveyValues = getSurveyValues(values); - const credentialPasswords = getCredentialPasswords(values); - setValue('credential_passwords', credentialPasswords); + setValue('credential_passwords', values.credential_passwords); setValue('inventory_id', values.inventory?.id); setValue( 'credentials', diff --git a/awx/ui_next/src/components/LaunchPrompt/steps/CredentialPasswordsStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/CredentialPasswordsStep.jsx index d9b4eb37d2..34824ddd03 100644 --- a/awx/ui_next/src/components/LaunchPrompt/steps/CredentialPasswordsStep.jsx +++ b/awx/ui_next/src/components/LaunchPrompt/steps/CredentialPasswordsStep.jsx @@ -89,7 +89,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) { )} @@ -97,7 +97,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) { )} @@ -105,7 +105,7 @@ function CredentialPasswordsStep({ launchConfig, i18n }) { )} @@ -118,7 +118,9 @@ function CredentialPasswordsStep({ launchConfig, i18n }) { ? i18n._(t`Vault password`) : i18n._(t`Vault password | ${credId}`) } - name={`credentialPasswordVault_${credId}`} + name={`credential_passwords['vault_password${ + credId !== '' ? `.${credId}` : '' + }']`} isRequired /> ))} diff --git a/awx/ui_next/src/components/LaunchPrompt/steps/useCredentialPasswordsStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/useCredentialPasswordsStep.jsx index 10b2193722..dfdf72c5a5 100644 --- a/awx/ui_next/src/components/LaunchPrompt/steps/useCredentialPasswordsStep.jsx +++ b/awx/ui_next/src/components/LaunchPrompt/steps/useCredentialPasswordsStep.jsx @@ -41,48 +41,26 @@ export default function useCredentialPasswordsStep( contentError: null, hasError, setTouched: setFieldTouched => { - Object.keys(values) - .filter(valueKey => valueKey.startsWith('credentialPassword')) - .forEach(credentialValueKey => - setFieldTouched(credentialValueKey, true, false) - ); + Object.keys(values.credential_passwords).forEach(credentialValueKey => + setFieldTouched( + `credential_passwords['${credentialValueKey}']`, + true, + false + ) + ); }, validate: () => { const setPasswordFieldError = fieldName => { setFieldError(fieldName, i18n._(t`This field may not be blank`)); }; - const { - credentialPasswordSsh, - credentialPasswordPrivilegeEscalation, - credentialPasswordPrivateKeyPassphrase, - } = values; - if ( !launchConfig.ask_credential_on_launch && launchConfig.passwords_needed_to_start ) { launchConfig.passwords_needed_to_start.forEach(password => { - if ( - password === 'ssh_password' && - isValueMissing(credentialPasswordSsh) - ) { - setPasswordFieldError('credentialPasswordSsh'); - } else if ( - password === 'become_password' && - isValueMissing(credentialPasswordPrivilegeEscalation) - ) { - setPasswordFieldError('credentialPasswordPrivilegeEscalation'); - } else if ( - password === 'ssh_key_unlock' && - isValueMissing(credentialPasswordPrivateKeyPassphrase) - ) { - setPasswordFieldError('credentialPasswordPrivateKeyPassphrase'); - } else if (password.startsWith('vault_password')) { - const vaultId = password.split(/\.(.+)/)[1] || ''; - if (isValueMissing(values[`credentialPasswordVault_${vaultId}`])) { - setPasswordFieldError(`credentialPasswordVault_${vaultId}`); - } + if (isValueMissing(values.credential_passwords[password])) { + setPasswordFieldError(`credential_passwords['${password}']`); } }); } else if (values.credentials) { @@ -93,74 +71,52 @@ export default function useCredentialPasswordsStep( ); if (launchConfigCredential?.passwords_needed.length > 0) { - if ( - launchConfigCredential.passwords_needed.includes( - 'ssh_password' - ) && - isValueMissing(credentialPasswordSsh) - ) { - setPasswordFieldError('credentialPasswordSsh'); - } - if ( - launchConfigCredential.passwords_needed.includes( - 'become_password' - ) && - isValueMissing(credentialPasswordPrivilegeEscalation) - ) { - setPasswordFieldError('credentialPasswordPrivilegeEscalation'); - } - if ( - launchConfigCredential.passwords_needed.includes( - 'ssh_key_unlock' - ) && - isValueMissing(credentialPasswordPrivateKeyPassphrase) - ) { - setPasswordFieldError('credentialPasswordPrivateKeyPassphrase'); - } - - launchConfigCredential.passwords_needed - .filter(passwordNeeded => - passwordNeeded.startsWith('vault_password') - ) - .map(vaultPassword => vaultPassword.split(/\.(.+)/)[1] || '') - .forEach(vaultId => { - if ( - isValueMissing(values[`credentialPasswordVault_${vaultId}`]) - ) { - setPasswordFieldError(`credentialPasswordVault_${vaultId}`); - } - }); + launchConfigCredential.passwords_needed.forEach(password => { + if (isValueMissing(values.credential_passwords[password])) { + setPasswordFieldError(`credential_passwords['${password}']`); + } + }); } } else { if ( credential?.inputs?.password === 'ASK' && - isValueMissing(credentialPasswordSsh) + isValueMissing(values.credential_passwords.ssh_password) ) { - setPasswordFieldError('credentialPasswordSsh'); + setPasswordFieldError('credential_passwords.ssh_password'); } if ( credential?.inputs?.become_password === 'ASK' && - isValueMissing(credentialPasswordPrivilegeEscalation) + isValueMissing(values.credential_passwords.become_password) ) { - setPasswordFieldError('credentialPasswordPrivilegeEscalation'); + setPasswordFieldError('credential_passwords.become_password'); } if ( credential?.inputs?.ssh_key_unlock === 'ASK' && - isValueMissing(credentialPasswordPrivateKeyPassphrase) + isValueMissing(values.credential_passwords.ssh_key_unlock) ) { - setPasswordFieldError('credentialPasswordPrivateKeyPassphrase'); + setPasswordFieldError('credential_passwords.ssh_key_unlock'); } if ( credential?.inputs?.vault_password === 'ASK' && isValueMissing( - values[`credentialPasswordVault_${credential.inputs.vault_id}`] + values.credential_passwords[ + `vault_password${ + credential.inputs.vault_id !== '' + ? `.${credential.inputs.vault_id}` + : '' + }` + ] ) ) { setPasswordFieldError( - `credentialPasswordVault_${credential.inputs.vault_id}` + `credential_passwords['vault_password${ + credential.inputs.vault_id !== '' + ? `.${credential.inputs.vault_id}` + : '' + }']` ); } } @@ -171,7 +127,9 @@ export default function useCredentialPasswordsStep( } function getInitialValues(launchConfig, selectedCredentials = []) { - const initialValues = {}; + const initialValues = { + credential_passwords: {}, + }; if (!launchConfig) { return initialValues; @@ -182,16 +140,7 @@ function getInitialValues(launchConfig, selectedCredentials = []) { launchConfig.passwords_needed_to_start ) { launchConfig.passwords_needed_to_start.forEach(password => { - if (password === 'ssh_password') { - initialValues.credentialPasswordSsh = ''; - } else if (password === 'become_password') { - initialValues.credentialPasswordPrivilegeEscalation = ''; - } else if (password === 'ssh_key_unlock') { - initialValues.credentialPasswordPrivateKeyPassphrase = ''; - } else if (password.startsWith('vault_password')) { - const vaultId = password.split(/\.(.+)/)[1] || ''; - initialValues[`credentialPasswordVault_${vaultId}`] = ''; - } + initialValues.credential_passwords[password] = ''; }); return initialValues; } @@ -203,44 +152,31 @@ function getInitialValues(launchConfig, selectedCredentials = []) { ); if (launchConfigCredential?.passwords_needed.length > 0) { - if (launchConfigCredential.passwords_needed.includes('ssh_password')) { - initialValues.credentialPasswordSsh = ''; - } - if ( - launchConfigCredential.passwords_needed.includes('become_password') - ) { - initialValues.credentialPasswordPrivilegeEscalation = ''; - } - if ( - launchConfigCredential.passwords_needed.includes('ssh_key_unlock') - ) { - initialValues.credentialPasswordPrivateKeyPassphrase = ''; - } - - const vaultPasswordIds = launchConfigCredential.passwords_needed - .filter(passwordNeeded => passwordNeeded.startsWith('vault_password')) - .map(vaultPassword => vaultPassword.split(/\.(.+)/)[1] || ''); - - vaultPasswordIds.forEach(vaultPasswordId => { - initialValues[`credentialPasswordVault_${vaultPasswordId}`] = ''; + launchConfigCredential.passwords_needed.forEach(password => { + initialValues.credential_passwords[password] = ''; }); } } else { if (credential?.inputs?.password === 'ASK') { - initialValues.credentialPasswordSsh = ''; + initialValues.credential_passwords.ssh_password = ''; } if (credential?.inputs?.become_password === 'ASK') { - initialValues.credentialPasswordPrivilegeEscalation = ''; + initialValues.credential_passwords.become_password = ''; } if (credential?.inputs?.ssh_key_unlock === 'ASK') { - initialValues.credentialPasswordPrivateKeyPassphrase = ''; + initialValues.credential_passwords.ssh_key_unlock = ''; } if (credential?.inputs?.vault_password === 'ASK') { - initialValues[`credentialPasswordVault_${credential.inputs.vault_id}`] = - ''; + if (!credential.inputs.vault_id || credential.inputs.vault_id === '') { + initialValues.credential_passwords.vault_password = ''; + } else { + initialValues.credential_passwords[ + `vault_password.${credential.inputs.vault_id}` + ] = ''; + } } } }); @@ -249,12 +185,6 @@ function getInitialValues(launchConfig, selectedCredentials = []) { } function checkForError(launchConfig, values) { - const { - credentialPasswordSsh, - credentialPasswordPrivilegeEscalation, - credentialPasswordPrivateKeyPassphrase, - } = values; - let hasError = false; if ( @@ -262,20 +192,8 @@ function checkForError(launchConfig, values) { launchConfig.passwords_needed_to_start ) { launchConfig.passwords_needed_to_start.forEach(password => { - if ( - (password === 'ssh_password' && - isValueMissing(credentialPasswordSsh)) || - (password === 'become_password' && - isValueMissing(credentialPasswordPrivilegeEscalation)) || - (password === 'ssh_key_unlock' && - isValueMissing(credentialPasswordPrivateKeyPassphrase)) - ) { + if (isValueMissing(values.credential_passwords[password])) { hasError = true; - } else if (password.startsWith('vault_password')) { - const vaultId = password.split(/\.(.+)/)[1] || ''; - if (isValueMissing(values[`credentialPasswordVault_${vaultId}`])) { - hasError = true; - } } }); } else if (values.credentials) { @@ -286,42 +204,30 @@ function checkForError(launchConfig, values) { ); if (launchConfigCredential?.passwords_needed.length > 0) { - if ( - (launchConfigCredential.passwords_needed.includes('ssh_password') && - isValueMissing(credentialPasswordSsh)) || - (launchConfigCredential.passwords_needed.includes( - 'become_password' - ) && - isValueMissing(credentialPasswordPrivilegeEscalation)) || - (launchConfigCredential.passwords_needed.includes( - 'ssh_key_unlock' - ) && - isValueMissing(credentialPasswordPrivateKeyPassphrase)) - ) { - hasError = true; - } - - launchConfigCredential.passwords_needed - .filter(passwordNeeded => - passwordNeeded.startsWith('vault_password') - ) - .map(vaultPassword => vaultPassword.split(/\.(.+)/)[1] || '') - .forEach(vaultId => { - if ( - isValueMissing(values[`credentialPasswordVault_${vaultId}`]) - ) { - hasError = true; - } - }); + launchConfigCredential.passwords_needed.forEach(password => { + if (isValueMissing(values.credential_passwords[password])) { + hasError = true; + } + }); } } else { if ( - (credential?.inputs?.password === 'ASK' && - isValueMissing(credentialPasswordSsh)) || - (credential?.inputs?.become_password === 'ASK' && - isValueMissing(credentialPasswordPrivilegeEscalation)) || - (credential?.inputs?.ssh_key_unlock === 'ASK' && - isValueMissing(credentialPasswordPrivateKeyPassphrase)) + credential?.inputs?.password === 'ASK' && + isValueMissing(values.credential_passwords.ssh_password) + ) { + hasError = true; + } + + if ( + credential?.inputs?.become_password === 'ASK' && + isValueMissing(values.credential_passwords.become_password) + ) { + hasError = true; + } + + if ( + credential?.inputs?.ssh_key_unlock === 'ASK' && + isValueMissing(values.credential_passwords.ssh_key_unlock) ) { hasError = true; } @@ -329,7 +235,13 @@ function checkForError(launchConfig, values) { if ( credential?.inputs?.vault_password === 'ASK' && isValueMissing( - values[`credentialPasswordVault_${credential.inputs.vault_id}`] + values.credential_passwords[ + `vault_password${ + credential.inputs.vault_id !== '' + ? `.${credential.inputs.vault_id}` + : '' + }` + ] ) ) { hasError = true; diff --git a/awx/ui_next/src/components/LaunchPrompt/useLaunchSteps.js b/awx/ui_next/src/components/LaunchPrompt/useLaunchSteps.js index 616aeb0a26..0460a2d7d8 100644 --- a/awx/ui_next/src/components/LaunchPrompt/useLaunchSteps.js +++ b/awx/ui_next/src/components/LaunchPrompt/useLaunchSteps.js @@ -83,6 +83,27 @@ export default function useLaunchSteps( Object.keys(formikValues).forEach(formikValueKey => { if ( + formikValueKey === 'credential_passwords' && + Object.prototype.hasOwnProperty.call( + newFormValues, + 'credential_passwords' + ) + ) { + const formikCredentialPasswords = formikValues.credential_passwords; + Object.keys(formikCredentialPasswords).forEach( + credentialPasswordValueKey => { + if ( + Object.prototype.hasOwnProperty.call( + newFormValues.credential_passwords, + credentialPasswordValueKey + ) + ) { + newFormValues.credential_passwords[credentialPasswordValueKey] = + formikCredentialPasswords[credentialPasswordValueKey]; + } + } + ); + } else if ( Object.prototype.hasOwnProperty.call(newFormValues, formikValueKey) ) { newFormValues[formikValueKey] = formikValues[formikValueKey]; diff --git a/awx/ui_next/src/util/prompt/getCredentialPasswords.js b/awx/ui_next/src/util/prompt/getCredentialPasswords.js deleted file mode 100644 index d38ba858a3..0000000000 --- a/awx/ui_next/src/util/prompt/getCredentialPasswords.js +++ /dev/null @@ -1,29 +0,0 @@ -export default function getCredentialPasswords(values) { - const credentialPasswords = {}; - Object.keys(values) - .filter(valueKey => valueKey.startsWith('credentialPassword')) - .forEach(credentialValueKey => { - if (credentialValueKey === 'credentialPasswordSsh') { - credentialPasswords.ssh_password = values[credentialValueKey]; - } - - if (credentialValueKey === 'credentialPasswordPrivilegeEscalation') { - credentialPasswords.become_password = values[credentialValueKey]; - } - - if (credentialValueKey === 'credentialPasswordPrivateKeyPassphrase') { - credentialPasswords.ssh_key_unlock = values[credentialValueKey]; - } - - if (credentialValueKey.startsWith('credentialPasswordVault_')) { - const vaultId = credentialValueKey.split('credentialPasswordVault_')[1]; - if (vaultId.length > 0) { - credentialPasswords[`vault_password.${vaultId}`] = - values[credentialValueKey]; - } else { - credentialPasswords.vault_password = values[credentialValueKey]; - } - } - }); - return credentialPasswords; -} diff --git a/awx/ui_next/src/util/prompt/getCredentialPasswords.test.js b/awx/ui_next/src/util/prompt/getCredentialPasswords.test.js deleted file mode 100644 index 2959d42141..0000000000 --- a/awx/ui_next/src/util/prompt/getCredentialPasswords.test.js +++ /dev/null @@ -1,66 +0,0 @@ -import getCredentialPasswords from './getCredentialPasswords'; - -describe('getCredentialPasswords', () => { - test('should handle ssh password', () => { - expect( - getCredentialPasswords({ - credentialPasswordSsh: 'foobar', - }) - ).toEqual({ - ssh_password: 'foobar', - }); - }); - test('should handle become password', () => { - expect( - getCredentialPasswords({ - credentialPasswordPrivilegeEscalation: 'foobar', - }) - ).toEqual({ - become_password: 'foobar', - }); - }); - test('should handle ssh key unlock', () => { - expect( - getCredentialPasswords({ - credentialPasswordPrivateKeyPassphrase: 'foobar', - }) - ).toEqual({ - ssh_key_unlock: 'foobar', - }); - }); - test('should handle vault password with identifier', () => { - expect( - getCredentialPasswords({ - credentialPasswordVault_1: 'foobar', - }) - ).toEqual({ - 'vault_password.1': 'foobar', - }); - }); - test('should handle vault password without identifier', () => { - expect( - getCredentialPasswords({ - credentialPasswordVault_: 'foobar', - }) - ).toEqual({ - vault_password: 'foobar', - }); - }); - test('should handle all password types', () => { - expect( - getCredentialPasswords({ - credentialPasswordSsh: '1', - credentialPasswordPrivilegeEscalation: '2', - credentialPasswordPrivateKeyPassphrase: '3', - credentialPasswordVault_: '4', - credentialPasswordVault_1: '5', - }) - ).toEqual({ - ssh_password: '1', - become_password: '2', - ssh_key_unlock: '3', - vault_password: '4', - 'vault_password.1': '5', - }); - }); -});