Create warning banner CTA to add a second authentication method#6188
Create warning banner CTA to add a second authentication method#6188
Conversation
There was a problem hiding this comment.
| def multiple_factors_enabled? | |
| return if MfaPolicy.new(current_user).multiple_factors_enabled? | |
| end |
It looks like the view calls this method directly so this definition isn't needed?
There was a problem hiding this comment.
You are right. Fixing this now
There was a problem hiding this comment.
I would consider moving the HTML outside of this translation, maybe even putting the period inside the link copy?
5884fd6 to
bebda5a
Compare
There was a problem hiding this comment.
Nit: Can we bring the closing tag onto the same line as the closing parenthesis, for consistency with line 32?
| ) | |
| %> | |
| ) %> |
There was a problem hiding this comment.
Should this be inverted? In other words, are we expecting to show a banner if the user does not have multiple factors set up?
There was a problem hiding this comment.
At first, it felt kind of tricky to name since we are seeking the false value. I will think this through some more--maybe only-one-factor-enabled or something that shows what the variable actually does
There was a problem hiding this comment.
Since the view doesn't deal with the user, but rather an instance variable set by the controller, I might expect the stubbing to occur with the @multiple_factors_enabled variable, not the user (where user stubbing could happen in the controller tests). Also, we're only testing one of the two possible variations of this behavior.
Maybe something like...
| context 'mfa banner' do | |
| let(:user) { create(:user, :signed_up, :with_webauthn_platform, :with_phone) } | |
| it 'does not show a banner if multiple factors are enabled' do | |
| render | |
| expect(rendered).not_to have_content(I18n.t('multi_factor_authentication.second_method_warning.text')) | |
| end | |
| end | |
| context 'mfa banner' do | |
| let(:multiple_factors_enabled) { false } | |
| before do | |
| @multiple_factors_enabled = multiple_factors_enabled | |
| end | |
| it 'shows a banner' do | |
| render | |
| expect(rendered).to have_content(t('multi_factor_authentication.second_method_warning.text')) | |
| end | |
| context 'with multiple factors enabled' do | |
| let(:multiple_factors_enabled) { true } | |
| it 'does not show a banner' do | |
| render | |
| expect(rendered).not_to have_content(t('multi_factor_authentication.second_method_warning.text')) | |
| end | |
| end | |
| end |
There was a problem hiding this comment.
Should this banner only be shown when the select_multiple_mfa_options feature flag is enabled?
57b053d to
de92cae
Compare
There was a problem hiding this comment.
bet one could put this on one line if we wanted
| <%= t( | |
| 'mfa.second_method_warning.text', | |
| ) %> | |
| <%= t('mfa.second_method_warning.text') %> |
There was a problem hiding this comment.
This makes sense. I probably did this while I was frustrated with the linter 😬
de92cae to
9e28d5f
Compare
There was a problem hiding this comment.
Can we use a simple ! negation?
| <% if @multiple_factors_enabled == false && IdentityConfig.store.select_multiple_mfa_options == false %> | |
| <% if !@multiple_factors_enabled && !IdentityConfig.store.select_multiple_mfa_options %> |
There was a problem hiding this comment.
Should we be checking that select_multiple_mfa_options is enabled, not disabled? I'm expecting the notice would only be shown when feature flag is turned on?
| <% if @multiple_factors_enabled == false && IdentityConfig.store.select_multiple_mfa_options == false %> | |
| <% if !@multiple_factors_enabled && IdentityConfig.store.select_multiple_mfa_options %> |
There was a problem hiding this comment.
It should be enabled because we only want it when select_multiple_mfa_options is true. I think I just needed fresh eyes on this 😅
ed57522 to
26a9ae8
Compare
03e1df8 to
2e24033
Compare
aduth
left a comment
There was a problem hiding this comment.
Small comment about the specs and clarifying question about the link, but otherwise looks good! 👍
| <%= link_to( | ||
| t('mfa.second_method_warning.link'), | ||
| login_two_factor_options_url, | ||
| ) %> |
There was a problem hiding this comment.
Is this link supposed to be functional right now? When I tested, it looks like it just refreshes the same page.
There was a problem hiding this comment.
It is supposed to be functional. Turns out I used login_two_factor_options_url (which doesn't exist) and that caused the 302 that happened in between the click -> redirect -> same page.
There was a problem hiding this comment.
Hm, after testing again with the latest version of the branch, it still doesn't seem to be working for me.
On a related note, it might also be good to have some feature specs for this flow to have some end-to-end assurance that the user experience is working as expected.
There was a problem hiding this comment.
I had not pushed the change up yet. That's my mistake.
I agree with having feature specs. I hadn't thought of starting that because most of the tickets for the feature were about building out the UI as the routing was being completed.
There was a problem hiding this comment.
I also just learned that those tests are being written in the "good path" flow, that is already being started.
There was a problem hiding this comment.
Another note, feature specs for the "good path" are being written in this PR. Since this is for the sad path, I am garnering that we can add on to the "sad path" after the "happy path" since the only way to get to this banner is to click "Skip for now" and that is coming in after the interstitial page routing is complete.
bfda7f3 to
d837622
Compare
There was a problem hiding this comment.
erblint will get cranky at this
| two_factor_options_url(:mfa_selected => @multiple_factors_enabled), | |
| two_factor_options_url(mfa_selected: @multiple_factors_enabled), |
Style/HashSyntax: Use the new Ruby 1.9 hash syntax.
In file: app/views/sign_up/completions/show.html.erb:31
There was a problem hiding this comment.
surprising indentation here (it's tabs... :/)
| include DocAuthHelper | |
| include SamlAuthHelper | |
| context 'multiple factor authentication feature is disabled' do | |
| include DocAuthHelper | |
| include SamlAuthHelper | |
| context 'multiple factor authentication feature is disabled' do |
b697c06 to
d19b205
Compare
2a4ba34 to
db1129d
Compare
| it 'displays a banner' do | ||
| visit_idp_from_sp_with_ial1(:oidc) | ||
| user = sign_up_and_set_password | ||
| select_2fa_option('backup_code') | ||
| click_continue | ||
|
|
||
| expect(page).to have_current_path(sign_up_completed_path) | ||
| expect(MfaPolicy.new(user).multiple_factors_enabled?).to eq false | ||
| expect(page).to have_content(t('mfa.second_method_warning.text')) | ||
| end | ||
|
|
||
| it 'does not display a banner' do |
There was a problem hiding this comment.
Could we clarify the difference between these two test case descriptions?
Either with context....
context 'with one MFA selected' do
it 'displays a banner' do
# ...
context 'with multiple MFA selected' do
it 'does not display a banner' doOr in the name itself:
it 'displays a banner after configuring a single MFA' do
# ...
it 'does not display a banner after configuring multiple MFA' do| <%= render(AlertComponent.new(type: :warning, class: 'margin-bottom-4')) do %> | ||
| <%= link_to( | ||
| t('mfa.second_method_warning.link'), | ||
| two_factor_options_url(mfa_selected: @multiple_factors_enabled), |
There was a problem hiding this comment.
Passing @multiple_factors_enabled here gives me the impression the parameter is handled as either true or false, when in reality the value doesn't seem to matter, since the check for params[:mfa_selected].present? would pass regardless if it was "true" or "false".
I wonder if instead, we should name it something which indicates that they're being sent for the purpose of setting up another MFA, e.g.
| two_factor_options_url(mfa_selected: @multiple_factors_enabled), | |
| two_factor_options_url(multiple_mfa_setup: ''), |
Or, maybe we just disable the logic of confirm_user_needs_2fa_setup altogether, if we're now expecting that a user might be setting up multiple MFAs? (Speaking of: should the logic there be considering the feature flag?)
There was a problem hiding this comment.
From what I understand, .present? requires a boolean value. Now, if we want to test if the multiple_mfa_setup simply exists, params.has_key?() appears to be what we are looking for. I can swap that out because we are not doing anything with the true or false value.
As for check if the logic is there and if the feature flag is enabled, I am not sure if that is needed. On that line, I was thinking that line returns that if the param exists. That param is only added with the link on the banner, and that banner only shows if the flag is on and multiple factors are not enabled. So it is like that check is being done beforehand.
With confirm_user_needs_2fa_setup, I am not sure if that should be disabled because we still need to determine if user_needs_sp_auth_method_setup? is true. I can see the case for confirm_user_needs_2fa_setup being refactored to better describe what it will check and if that logic should reflect whether or not a service provider will require MFA setup.
aduth
left a comment
There was a problem hiding this comment.
Small comment about typo, but otherwise LGTM 👍
There was a problem hiding this comment.
Typo:
| return if params.has_key?(:multipe_mfa_setup) | |
| return if params.has_key?(:multiple_mfa_setup) |
There was a problem hiding this comment.
| two_factor_options_url(multipe_mfa_setup: ''), | |
| two_factor_options_url(multiple_mfa_setup: ''), |
3f26711 to
73a1937
Compare
…s to add a second MFA changelog: Improvements, Multi-factor authentication feature, Add call to action banner to add second MFA options Co-Authored-By: Andrew Duthie <andrew.duthie@gsa.gov>
73a1937 to
061e04d
Compare
This PR adds a CTA for users to add a second authentication banner in order to best secure their account. This is part of the "sad path" when a user does not select more than one method.
Note: