diff --git a/spec/features/openid_connect/vtr_spec.rb b/spec/features/openid_connect/vtr_spec.rb index 21102cfd3e4..f0abcb9c697 100644 --- a/spec/features/openid_connect/vtr_spec.rb +++ b/spec/features/openid_connect/vtr_spec.rb @@ -88,15 +88,10 @@ expect(page).to have_content(t('two_factor_authentication.two_factor_hspd12_choice_intro')) # User must setup PIV/CAC before continuing - visit setup_piv_cac_path - - nonce = piv_cac_nonce_from_form_action - visit_piv_cac_service( - setup_piv_cac_url, - nonce: nonce, - uuid: SecureRandom.uuid, - subject: 'SomeIgnoredSubject', - ) + select_2fa_option('piv_cac') + fill_in t('instructions.mfa.piv_cac.step_1'), with: 'Card' + click_on t('forms.piv_cac_setup.submit') + follow_piv_cac_redirect click_agree_and_continue click_on 'Continue' diff --git a/spec/features/saml/vtr_spec.rb b/spec/features/saml/vtr_spec.rb index 50b1d711eac..0a30581b34f 100644 --- a/spec/features/saml/vtr_spec.rb +++ b/spec/features/saml/vtr_spec.rb @@ -116,16 +116,11 @@ expect(page).to have_content(t('two_factor_authentication.two_factor_hspd12_choice_intro')) # User must setup PIV/CAC before continuing - visit setup_piv_cac_path - nonce = piv_cac_nonce_from_form_action - visit_piv_cac_service( - setup_piv_cac_url, - nonce: nonce, - uuid: SecureRandom.uuid, - subject: 'SomeIgnoredSubject', - ) + select_2fa_option('piv_cac') + fill_in t('instructions.mfa.piv_cac.step_1'), with: 'Card' + click_on t('forms.piv_cac_setup.submit') + follow_piv_cac_redirect - click_submit_default click_agree_and_continue click_submit_default expect_successful_saml_redirect diff --git a/spec/features/two_factor_authentication/sign_in_spec.rb b/spec/features/two_factor_authentication/sign_in_spec.rb index d635017367b..2118db20cb2 100644 --- a/spec/features/two_factor_authentication/sign_in_spec.rb +++ b/spec/features/two_factor_authentication/sign_in_spec.rb @@ -405,36 +405,24 @@ def attempt_to_bypass_2fa end scenario 'user uses PIV/CAC as their second factor' do - stub_piv_cac_service - user = user_with_piv_cac sign_in_before_2fa(user) + stub_piv_cac_service(uuid: user.piv_cac_configurations.first.x509_dn_uuid) - nonce = visit_login_two_factor_piv_cac_and_get_nonce + click_on t('forms.piv_cac_mfa.submit') + follow_piv_cac_redirect - visit_piv_cac_service( - login_two_factor_piv_cac_path, - uuid: user.piv_cac_configurations.first.x509_dn_uuid, - dn: 'C=US, O=U.S. Government, OU=DoD, OU=PKI, CN=DOE.JOHN.1234', - nonce: nonce, - ) expect(current_path).to eq account_path end scenario 'user uses incorrect PIV/CAC as their second factor' do - stub_piv_cac_service - user = user_with_piv_cac sign_in_before_2fa(user) + stub_piv_cac_service(uuid: Random.uuid) - nonce = visit_login_two_factor_piv_cac_and_get_nonce + click_on t('forms.piv_cac_mfa.submit') + follow_piv_cac_redirect - visit_piv_cac_service( - login_two_factor_piv_cac_path, - uuid: user.piv_cac_configurations.first.x509_dn_uuid + 'X', - dn: 'C=US, O=U.S. Government, OU=DoD, OU=PKI, CN=DOE.JOHN.12345', - nonce: nonce, - ) expect(current_path).to eq login_two_factor_piv_cac_path expect(page).to have_content(t('two_factor_authentication.invalid_piv_cac')) end diff --git a/spec/features/users/piv_cac_management_spec.rb b/spec/features/users/piv_cac_management_spec.rb index 123d268a90d..4951e5709e6 100644 --- a/spec/features/users/piv_cac_management_spec.rb +++ b/spec/features/users/piv_cac_management_spec.rb @@ -9,7 +9,7 @@ allow(Identity::Hostdata).to receive(:env).and_return('test') allow(Identity::Hostdata).to receive(:domain).and_return('example.com') - stub_piv_cac_service + stub_piv_cac_service(uuid:) sign_in_and_2fa_user(user) visit account_two_factor_authentication_path @@ -18,14 +18,9 @@ expect(page.response_headers['Content-Security-Policy'].split(';').map(&:strip)). to(include("form-action https://*.pivcac.test.example.com 'self'")) - nonce = piv_cac_nonce_from_form_action - - visit_piv_cac_service( - setup_piv_cac_url, - nonce: nonce, - uuid: uuid, - subject: 'SomeIgnoredSubject', - ) + fill_in t('instructions.mfa.piv_cac.step_1'), with: 'Card' + click_on t('forms.piv_cac_setup.submit') + follow_piv_cac_redirect expect(current_path).to eq account_path visit account_two_factor_authentication_path @@ -56,20 +51,15 @@ end scenario 'disallows association of a piv/cac with the same name' do - stub_piv_cac_service + stub_piv_cac_service(uuid:) sign_in_and_2fa_user(user) visit account_two_factor_authentication_path click_link t('account.index.piv_cac_add'), href: setup_piv_cac_url - nonce = piv_cac_nonce_from_form_action - - visit_piv_cac_service( - setup_piv_cac_url, - nonce: nonce, - uuid: uuid, - subject: 'SomeIgnoredSubject', - ) + fill_in t('instructions.mfa.piv_cac.step_1'), with: 'Card' + click_on t('forms.piv_cac_setup.submit') + follow_piv_cac_redirect expect(current_path).to eq account_path @@ -83,19 +73,16 @@ end scenario 'displays error for piv/cac with no certificate and accepts more error info' do - stub_piv_cac_service + stub_piv_cac_service(error: 'certificate.none') sign_in_and_2fa_user(user) visit account_two_factor_authentication_path click_link t('account.index.piv_cac_add'), href: setup_piv_cac_url - nonce = piv_cac_nonce_from_form_action - visit_piv_cac_service( - setup_piv_cac_url, - nonce: nonce, - error: 'certificate.none', - key_id: 'AB:CD:EF', - ) + fill_in t('instructions.mfa.piv_cac.step_1'), with: 'Card' + click_on t('forms.piv_cac_setup.submit') + follow_piv_cac_redirect + expect(current_path).to eq setup_piv_cac_error_path expect(page).to have_link(t('instructions.mfa.piv_cac.try_again'), href: setup_piv_cac_url) expect(page).to have_content( @@ -107,19 +94,16 @@ end scenario 'displays error for expires certificate piv/cac and accepts more error info' do - stub_piv_cac_service + stub_piv_cac_service(error: 'certificate.expired') sign_in_and_2fa_user(user) visit account_two_factor_authentication_path click_link t('account.index.piv_cac_add'), href: setup_piv_cac_url - nonce = piv_cac_nonce_from_form_action - visit_piv_cac_service( - setup_piv_cac_url, - nonce: nonce, - error: 'certificate.expired', - key_id: 'AB:CD:EF', - ) + fill_in t('instructions.mfa.piv_cac.step_1'), with: 'Card' + click_on t('forms.piv_cac_setup.submit') + follow_piv_cac_redirect + expect(current_path).to eq setup_piv_cac_error_path expect(page).to have_link( t('instructions.mfa.piv_cac.please_try_again'), diff --git a/spec/features/users/sign_in_spec.rb b/spec/features/users/sign_in_spec.rb index 6b5495a85f7..2fb3daf39cd 100644 --- a/spec/features/users/sign_in_spec.rb +++ b/spec/features/users/sign_in_spec.rb @@ -132,14 +132,8 @@ allow(FeatureManagement).to receive(:development_and_identity_pki_disabled?).and_return(false) stub_piv_cac_service - nonce = get_piv_cac_nonce_from_link(find_link(t('forms.piv_cac_login.submit'))) - visit_piv_cac_service( - current_url, - nonce: nonce, - dn: 'C=US, O=U.S. Government, OU=DoD, OU=PKI, CN=DOE.JOHN.1234', - uuid: SecureRandom.uuid, - subject: 'SomeIgnoredSubject', - ) + click_on t('forms.piv_cac_login.submit') + follow_piv_cac_redirect expect(page).to have_current_path(login_piv_cac_error_path(error: 'user.not_found')) visit sign_up_email_path diff --git a/spec/support/features/session_helper.rb b/spec/support/features/session_helper.rb index f1b63bfd743..809264ecff6 100644 --- a/spec/support/features/session_helper.rb +++ b/spec/support/features/session_helper.rb @@ -64,21 +64,14 @@ def signin_with_piv(user = user_with_piv_cac) end def signin_with_piv_error(error) - user = user_with_piv_cac visit new_user_session_path click_on t('account.login.piv_cac') allow(FeatureManagement).to receive(:development_and_identity_pki_disabled?).and_return(false) - stub_piv_cac_service - nonce = get_piv_cac_nonce_from_link(find_link(t('forms.piv_cac_login.submit'))) - visit_piv_cac_service( - current_url, - nonce: nonce, - uuid: user.piv_cac_configurations.first.x509_dn_uuid, - subject: 'SomeIgnoredSubject', - error: error, - ) + stub_piv_cac_service(error:) + click_on t('forms.piv_cac_login.submit') + follow_piv_cac_redirect end def signin_with_bad_piv @@ -93,14 +86,9 @@ def fill_in_piv_cac_credentials_and_submit(user, piv_cac_configurations&.first&.x509_dn_uuid) allow(FeatureManagement).to receive(:development_and_identity_pki_disabled?).and_return(false) - stub_piv_cac_service - nonce = get_piv_cac_nonce_from_link(find_link(t('forms.piv_cac_login.submit'))) - visit_piv_cac_service( - current_url, - nonce: nonce, - uuid: uuid, - subject: 'SomeIgnoredSubject', - ) + stub_piv_cac_service(uuid:) + click_on t('forms.piv_cac_login.submit') + follow_piv_cac_redirect end def fill_in_bad_piv_cac_credentials_and_submit @@ -537,16 +525,9 @@ def register_user_with_piv_cac(email = 'test@test.com') def set_up_2fa_with_piv_cac stub_piv_cac_service select_2fa_option('piv_cac') - - expect(page).to have_current_path setup_piv_cac_path - - nonce = piv_cac_nonce_from_form_action - visit_piv_cac_service( - setup_piv_cac_url, - nonce: nonce, - uuid: SecureRandom.uuid, - subject: 'SomeIgnoredSubject', - ) + fill_in t('instructions.mfa.piv_cac.step_1'), with: 'Card' + click_on t('forms.piv_cac_setup.submit') + follow_piv_cac_redirect end def skip_second_mfa_prompt @@ -559,7 +540,7 @@ def sign_in_via_branded_page(user) click_submit_default end - def stub_piv_cac_service(error: nil) + def stub_piv_cac_service(error: nil, uuid: Random.uuid) allow(IdentityConfig.store).to receive(:identity_pki_disabled).and_return(false) allow(IdentityConfig.store).to receive(:piv_cac_service_url). and_return('http://piv.example.com/') @@ -582,7 +563,7 @@ def stub_piv_cac_service(error: nil) query['redirect_uri'], token: { dn: 'C=US, O=U.S. Government, OU=DoD, OU=PKI, CN=DOE.JOHN.1234', - uuid: SecureRandom.uuid, + uuid:, subject: 'SomeIgnoredSubject', nonce: query['nonce'], error:, @@ -600,36 +581,6 @@ def follow_piv_cac_redirect visit redirect_url end - def visit_piv_cac_service(idp_url, token_data) - visit(idp_url + '?token=' + CGI.escape(token_data.to_json)) - end - - def visit_login_two_factor_piv_cac_and_get_nonce - visit login_two_factor_piv_cac_path - get_piv_cac_nonce_from_link(find_link(t('forms.piv_cac_mfa.submit'))) - end - - # This is a bit convoluted because we generate a nonce when we visit the - # link. The link provides a redirect to the piv/cac service with the nonce. - # This way, even if JavaScript fetches the link to grab the nonce, a new nonce - # is generated when the user clicks on the link. - def get_piv_cac_nonce_from_link(link) - go_back = current_path - visit link['href'] - nonce = Rack::Utils.parse_nested_query(URI(current_url).query)['nonce'] - visit go_back - nonce - end - - def piv_cac_nonce_from_form_action - go_back = current_path - fill_in 'name', with: 'Card ' + SecureRandom.uuid - click_button t('forms.piv_cac_setup.submit') - nonce = Rack::Utils.parse_nested_query(URI(current_url).query)['nonce'] - visit go_back - nonce - end - def link_identity(user, service_provider, ial = nil) IdentityLinker.new( user,