From 315abd55ac4fac778abbc64695320994abf36caf Mon Sep 17 00:00:00 2001 From: raortegar Date: Wed, 26 Mar 2025 09:49:38 +0100 Subject: [PATCH 1/2] MDL-84009 tool_mfa: Additional factor instances support --- admin/tool/mfa/action.php | 11 +++++++++ .../local/factor/object_factor_base.php | 24 +++++++++++++++++++ admin/tool/mfa/lang/en/tool_mfa.php | 1 + 3 files changed, 36 insertions(+) diff --git a/admin/tool/mfa/action.php b/admin/tool/mfa/action.php index 060d1ae6c54..9dc9eb333cc 100644 --- a/admin/tool/mfa/action.php +++ b/admin/tool/mfa/action.php @@ -169,6 +169,17 @@ switch ($action) { echo $OUTPUT->heading(get_string('managefactor', 'factor_' . $factorobject->name)); echo $OUTPUT->active_factors($factor); echo $OUTPUT->single_button($returnurl, get_string('back')); + + // Displays a setup additional button in case it is needed. + if ($factorobject->show_additional_setup_button()) { + echo $OUTPUT->single_button( + url: new \moodle_url('action.php', ['action' => 'setup', 'factor' => $factor]), + label: $factorobject->get_additional_setup_string(), + method: 'post', + options: ['type' => 'primary'], + ); + } + // JS for modal confirming replace and revoke actions. $PAGE->requires->js_call_amd('tool_mfa/confirmation_modal', 'init', [$context->id]); diff --git a/admin/tool/mfa/classes/local/factor/object_factor_base.php b/admin/tool/mfa/classes/local/factor/object_factor_base.php index 537be9bffe0..3195451bf59 100644 --- a/admin/tool/mfa/classes/local/factor/object_factor_base.php +++ b/admin/tool/mfa/classes/local/factor/object_factor_base.php @@ -433,6 +433,18 @@ abstract class object_factor_base implements object_factor { return $this->has_setup(); } + /** + * Returns true if a button should be shown to add factors of the same kind on the preferences page. + * For example, give user's the ability to set up multiple security keys. + * + * Override in child class if necessary. + * + * @return bool + */ + public function show_additional_setup_button(): bool { + return false; + } + /** * Returns true if a factor requires input from the user to verify. * @@ -590,6 +602,18 @@ abstract class object_factor_base implements object_factor { return get_string('setupfactor', 'tool_mfa'); } + /** + * Gets the string for additional setup button on preferences page. + * If the user has the ability to set up multiple security keys. + * + * Override in child class if necessary. + * + * @return string + */ + public function get_additional_setup_string(): string { + return get_string('setupfactorbuttonadditional', 'tool_mfa'); + } + /** * Gets the string for manage button on preferences page. * diff --git a/admin/tool/mfa/lang/en/tool_mfa.php b/admin/tool/mfa/lang/en/tool_mfa.php index ef7a75a6735..62e1d7eda38 100644 --- a/admin/tool/mfa/lang/en/tool_mfa.php +++ b/admin/tool/mfa/lang/en/tool_mfa.php @@ -150,6 +150,7 @@ $string['settings:redir_exclusions_help'] = 'Each new line is a relative URL fro $string['settings:weight'] = 'Factor weight'; $string['settings:weight_help'] = 'The weight of this factor if passed. A user needs at least 100 points to log in.'; $string['setupfactor'] = 'Set up factor'; +$string['setupfactorbuttonadditional'] = 'Add additional factor'; $string['state:fail'] = 'Fail'; $string['state:locked'] = 'Locked'; $string['state:neutral'] = 'Neutral'; From dab86dd04ab5e61898764d8970589fb9cff251f9 Mon Sep 17 00:00:00 2001 From: raortegar Date: Thu, 27 Mar 2025 07:25:18 +0100 Subject: [PATCH 2/2] MDL-84009 factor_webauthn: Add additional security keys --- .../mfa/factor/webauthn/classes/factor.php | 18 ++++++++++++++++++ .../webauthn/lang/en/factor_webauthn.php | 1 + ...l_mfa_setup_and_manage_user_factors.feature | 13 +++++++++++++ 3 files changed, 32 insertions(+) diff --git a/admin/tool/mfa/factor/webauthn/classes/factor.php b/admin/tool/mfa/factor/webauthn/classes/factor.php index 1be01d81d10..8427c0b5d09 100644 --- a/admin/tool/mfa/factor/webauthn/classes/factor.php +++ b/admin/tool/mfa/factor/webauthn/classes/factor.php @@ -111,6 +111,15 @@ class factor extends object_factor_base { return true; } + /** + * Returns true if an additional setup button should be shown on the preferences page. + * + * @return bool + */ + public function show_additional_setup_button(): bool { + return true; + } + /** * WebAuthn factor implementation. * @@ -151,6 +160,15 @@ class factor extends object_factor_base { return get_string('setupfactorbutton', 'factor_webauthn'); } + /** + * Gets the string for additional setup button on preferences page. + * + * @return string + */ + public function get_additional_setup_string(): string { + return get_string('setupfactorbuttonadditional', 'factor_webauthn'); + } + /** * Gets the string for manage button on preferences page. * diff --git a/admin/tool/mfa/factor/webauthn/lang/en/factor_webauthn.php b/admin/tool/mfa/factor/webauthn/lang/en/factor_webauthn.php index 11cd6227407..b8ef3c6d9b5 100644 --- a/admin/tool/mfa/factor/webauthn/lang/en/factor_webauthn.php +++ b/admin/tool/mfa/factor/webauthn/lang/en/factor_webauthn.php @@ -56,6 +56,7 @@ $string['settings:userverification'] = 'User verification'; $string['settings:userverification_help'] = 'Serves to ensure the person authenticating is in fact who they say they are. User verification can take various forms, such as password, PIN, fingerprint, etc.'; $string['setupfactor'] = 'Set up security key'; $string['setupfactorbutton'] = 'Set up'; +$string['setupfactorbuttonadditional'] = 'Add security key'; $string['setupfactor:instructionsregistersecuritykey'] = '2. Register a security key.'; $string['setupfactor:instructionssecuritykeyname'] = '1. Give your key a name.'; $string['setupfactor:intro'] = 'A security key is a physical device that you can use to authenticate yourself. Security keys can be USB tokens, Bluetooth devices, or event built-in fingerprint scanners on your phone or computer.'; diff --git a/admin/tool/mfa/tests/behat/tool_mfa_setup_and_manage_user_factors.feature b/admin/tool/mfa/tests/behat/tool_mfa_setup_and_manage_user_factors.feature index 0349bbce621..8739113d45c 100644 --- a/admin/tool/mfa/tests/behat/tool_mfa_setup_and_manage_user_factors.feature +++ b/admin/tool/mfa/tests/behat/tool_mfa_setup_and_manage_user_factors.feature @@ -32,6 +32,7 @@ Feature: Set up and manage user factors And I click on "Cancel" "button" And I click on "Manage security key" "button" And I should see "Manage security key" + And I should see "Add security key" @javascript Scenario: I can revoke a factor only when there is more than one active factor @@ -78,3 +79,15 @@ Feature: Set up and manage user factors And I click on "Replace" "button" in the "MacBook" "table_row" When I click on "Yes, replace" "button" in the "Replace 'MacBook' security key?" "dialogue" Then I should see "Replace security key" + + Scenario: I can add a new factor instance on the manage factor page + Given the following config values are set as admin: + | enabled | 1 | factor_webauthn | + And the following "tool_mfa > User factors" exist: + | username | factor | label | + | admin | webauthn | MacBook | + And I follow "Preferences" in the user menu + And I click on "Multi-factor authentication preferences" "link" + And I click on "Manage security key" "button" + When I click on "Add security key" "button" + Then I should see "Set up security key"