Skip to content

Commit

Permalink
feat: add a way to prevent gracemode redirects if user has passed cer…
Browse files Browse the repository at this point in the history
…tain factors
  • Loading branch information
keevan committed Nov 28, 2023
1 parent 19904b9 commit 1756328
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 5 deletions.
9 changes: 9 additions & 0 deletions classes/local/factor/object_factor_base.php
Original file line number Diff line number Diff line change
Expand Up @@ -635,4 +635,13 @@ public function global_validation($data, $files): array {
public function global_submit($data) {
return;
}

/**
* Returns whether or not the factor has passed
*
* @return bool
*/
public function passed(): bool {
return $this->get_state() == \tool_mfa\plugininfo\factor::STATE_PASS;
}
}
8 changes: 4 additions & 4 deletions classes/manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static function display_debug_notification() {

// Stop adding weight if 100 achieved.
if (!$weighttoggle) {
$achieved = $factor->get_state() == \tool_mfa\plugininfo\factor::STATE_PASS ? $factor->get_weight() : 0;
$achieved = $factor->passed() ? $factor->get_weight() : 0;
$achieved = '+'.$achieved;
$runningtotal += $achieved;
} else {
Expand Down Expand Up @@ -147,7 +147,7 @@ public static function get_total_weight() {
$factors = \tool_mfa\plugininfo\factor::get_active_user_factor_types();

foreach ($factors as $factor) {
if ($factor->get_state() == \tool_mfa\plugininfo\factor::STATE_PASS) {
if ($factor->passed()) {
$totalweight += $factor->get_weight();
}
}
Expand Down Expand Up @@ -818,7 +818,7 @@ public static function get_cumulative_weight() {
$factors = \tool_mfa\plugininfo\factor::get_active_user_factor_types();
$totalweight = 0;
foreach ($factors as $factor) {
if ($factor->get_state() == \tool_mfa\plugininfo\factor::STATE_PASS) {
if ($factor->passed()) {
$totalweight += $factor->get_weight();
// If over 100, break. Dont care about >100.
if ($totalweight >= 100) {
Expand Down Expand Up @@ -851,7 +851,7 @@ public static function check_factor_pending($factorname) {
continue;
}

if ($factor->get_state() == \tool_mfa\plugininfo\factor::STATE_PASS) {
if ($factor->passed()) {
$totalweight += $factor->get_weight();
if ($totalweight >= 100) {
$weighttoggle = true;
Expand Down
35 changes: 34 additions & 1 deletion factor/grace/classes/factor.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public function get_state($redirectable = true) {
// If gracemode would have given points, but now doesnt,
// Jump out of the loop and force a factor setup.
// We will return once there is a setup, or the user tries to leave.
if (get_config('factor_grace', 'forcesetup') && $redirectable) {
if ($redirectable && get_config('factor_grace', 'forcesetup')) {
if (empty($SESSION->mfa_gracemode_recursive)) {
// Set a gracemode lock so any further recursive gets fall past any recursive calls.
$SESSION->mfa_gracemode_recursive = true;
Expand All @@ -124,9 +124,15 @@ public function get_state($redirectable = true) {
foreach ($factorurls as $factorurl) {
if ($factorurl->compare($cleanurl)) {
$redirectable = false;
break;
}
}

// Checking if there are contributing factors, that should not cause a redirect.
if ($redirectable && $this->should_skip_force_setup()) {
$redirectable = false;
}

// We should never redirect if we have already passed.
if ($redirectable && \tool_mfa\manager::get_cumulative_weight() >= 100) {
$redirectable = false;
Expand Down Expand Up @@ -302,4 +308,31 @@ public function get_affecting_factors(): array {
});
return $factors;
}

/**
* Returns whether or not the force setup of MFA is skippable
*
* @return bool
*/
private function should_skip_force_setup(): bool {
// Checking if there are contributing factors, that should not cause a redirect.
$active = \tool_mfa\plugininfo\factor::get_active_user_factor_types();
$noredirectlist = get_config('factor_grace', 'noredirectlist');
if (!$noredirectlist) {
return false;
}

$values = explode(',', $noredirectlist);
$keys = array_flip($values);

foreach ($active as $factor) {
if ($factor->passed()
&& isset($keys[$factor->name])
&& $factor->get_weight() > 0) {
return true;
}
}

return false;
}
}
2 changes: 2 additions & 0 deletions factor/grace/lang/en/factor_grace.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
$string['settings:customwarning_help'] = 'Add content here to replace the grace warning notification with custom HTML contents. Adding {timeremaining} in text will replace it with the current grace duration for the user, and {setuplink} will replace with the URL of the setup page for the user.';
$string['settings:forcesetup'] = 'Force factor setup';
$string['settings:forcesetup_help'] = 'Forces a user to the preferences page to setup MFA when the gracemode period expires. If set to off, users will be unable to authenticate when the grace period expires.';
$string['settings:noredirectlist'] = 'Force factor skip list';
$string['settings:noredirectlist_help'] = 'In cases where certain users DO NOT need to set up MFA. If any selected factors contribute points, grace mode will NOT force factor setup.';
$string['settings:graceperiod'] = 'Grace period';
$string['settings:graceperiod_help'] = 'Period of time when users can access Moodle without configured and enabled factors';
$string['settings:ignorelist'] = 'Ignored factors';
Expand Down
9 changes: 9 additions & 0 deletions factor/grace/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@
new lang_string('settings:forcesetup', 'factor_grace'),
new lang_string('settings:forcesetup_help', 'factor_grace'), 0));

$allfactors = \tool_mfa\plugininfo\factor::get_factors();
$noredirectlistfactors = [];
foreach ($allfactors as $factor) {
$noredirectlistfactors[$factor->name] = $factor->get_display_name();
}
$settings->add(new admin_setting_configmultiselect('factor_grace/noredirectlist',
new lang_string('settings:noredirectlist', 'factor_grace'),
new lang_string('settings:noredirectlist_help', 'factor_grace'), [], $noredirectlistfactors));

$settings->add(new admin_setting_configduration('factor_grace/graceperiod',
new lang_string('settings:graceperiod', 'factor_grace'),
new lang_string('settings:graceperiod_help', 'factor_grace'), '604800'));
Expand Down

0 comments on commit 1756328

Please sign in to comment.