Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/en/rst/using/two-factor-authentication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,10 @@ Do not store recovery codes with your password or on the device that provides
your second factor. If you are unsure whether your codes remain private,
generate and print a new set.

BMO recovery codes cannot replace a Duo verification, even though the 2FA
preferences page offers Duo users the recovery-code generator. Duo users should
configure more than one authentication method in Duo and contact `Mozilla
Service Desk`_ if none of those methods are available.
BMO does not offer its recovery-code generator for Duo accounts because BMO
recovery codes cannot replace a Duo verification. Duo users should configure
more than one authentication method in Duo and contact `Mozilla Service Desk`_
if none of those methods are available.

.. _two-factor-troubleshooting:

Expand Down
49 changes: 49 additions & 0 deletions qa/t/2_test_login_duo.t
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,56 @@ $sel->is_text_present_ok(
'The changes to your two-factor authentication have been saved',
'Duo successfully enabled');

ok(
$sel->is_element_present('mfa-disable'),
'Duo preferences are displayed'
);
ok(
!$sel->is_element_present('mfa-recovery'),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No positive control (low). !is_element_present('mfa-recovery') is satisfied by any page that lacks the button. If the navigation race above leaves the browser on the pre-submit page, an error page, or the Duo redirect page, this passes vacuously and the regression it guards goes unnoticed.

Asserting a control element that must be present on the Duo prefs tab — e.g. ok($sel->is_element_present('mfa-disable'), ...) — alongside it makes the absence meaningful.

(For what it's worth, the locator itself is fine: _fix_locator (Selenium.pm:480) makes this an exact @id/@name match, so mfa-recovery-container / mfa-recovery-frame don't false-positive.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c5eec07. The test now confirms mfa-disable is present on the Duo preferences page before asserting that mfa-recovery is absent.

'Recovery code generation is not offered for Duo'
);

# A forged recovery request must fail before opening the Duo prompt.
$sel->driver->execute_script(
q{document.getElementById('mfa-auth-container').style.display = 'block';}
);
$sel->type_ok('mfa-password', $config->{admin_user_passwd});
$sel->driver->execute_script(q{
const source = document.forms.userprefsform;
const form = document.createElement('form');
form.method = 'post';
form.action = source.action;

[
['tab', 'mfa'],
['token', source.elements.token.value],
['dosave', '1'],
['mfa_action', 'recovery'],
['mfa', 'TOTP'],
['password', source.elements.password.value],
].forEach(([name, value]) => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = name;
input.value = value;
form.appendChild(input);
});

document.body.appendChild(form);
form.submit();
});
foreach (1 .. WAIT_TIME / 1000) {
last if $sel->get_title eq 'Duo Security Error';
sleep 1;
}
$sel->title_is('Duo Security Error');
$sel->is_text_present_ok(
'Recovery codes are not available when using Duo Security',
'Forged Duo recovery request rejected'
);

# Disable Duo for the admin user
$sel->open_ok('/userprefs.cgi?tab=mfa');
$sel->click_ok('mfa-disable');
$sel->type_ok('mfa-password', $config->{admin_user_passwd});
$sel->click_ok('update');
Expand Down