moodle/admin/tool/mfa/classes/plugininfo/factor.php
Stevani Andolo a639783409 MDL-78509 tool_mfa: Boarded the tool_mfa into core
In this patch the "commitid" of the "upstream" has been included in this
commit. Also, we did not include three factors, which are SMS, Security
Questions and Login Banner.

Co-authored-by: Peter Burnett <peterburnett@catalyst-au.net>
Co-authored-by: Misha Golenkov <golenkovm@gmail.com>
Co-authored-by: Brendan Heywood <brendan@catalyst-au.net>
Co-authored-by: Alex Morris <alex.morris@catalyst.net.nz>
Co-authored-by: Dan Marsden <dan@danmarsden.com>
Co-authored-by: Kevin Pham <kevinpham@catalyst-au.net>
Co-authored-by: Chris Pratt <tonyyeb@gmail.com>
Co-authored-by: Andrew Lyons <andrew@nicols.co.uk>
Co-authored-by: Tomo Tsuyuki <tomotsuyuki@catalyst-au.net>
Co-authored-by: Liam Kearney <https://github.com/LiamKearn>
Co-authored-by: Nicholas Hoobin <nicholashoobin@catalyst-au.net>
Co-authored-by: Scott Verbeek <scottverbeek@catalyst-au.net>
Co-authored-by: nomisge <https://github.com/nomisge>
Co-authored-by: Dmitrii Metelkin <dmitriim@catalyst-au.net>
Co-authored-by: Matthew Hilton <matthewhilton@catalyst-au.net>
Co-authored-by: Michael Geering <https://github.com/dryj>
Co-authored-by: alphadijkstra <https://github.com/alphadijkstra>
2023-08-29 11:06:44 +08:00

293 lines
8 KiB
PHP

<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace tool_mfa\plugininfo;
/**
* Subplugin info class.
*
* @package tool_mfa
* @author Mikhail Golenkov <golenkovm@gmail.com>
* @copyright Catalyst IT
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class factor extends \core\plugininfo\base {
/** @var string */
const STATE_UNKNOWN = 'unknown';
/** @var string */
const STATE_PASS = 'pass';
/** @var string */
const STATE_FAIL = 'fail';
/** @var string */
const STATE_NEUTRAL = 'neutral';
/** @var string Locked state is identical to neutral, but can't be overridden */
const STATE_LOCKED = 'locked';
/**
* Finds all MFA factors.
*
* @return array of factor objects.
*/
public static function get_factors() {
$return = [];
$factors = \core_plugin_manager::instance()->get_plugins_of_type('factor');
foreach ($factors as $factor) {
$classname = '\\factor_'.$factor->name.'\\factor';
if (class_exists($classname)) {
$return[] = new $classname($factor->name);
}
}
return self::sort_factors_by_order($return);
}
/**
* Sorts factors by configured order.
*
* @param array $unsorted of factor objects
* @return array of factor objects
* @throws \dml_exception
*/
public static function sort_factors_by_order($unsorted) {
$sorted = [];
$orderarray = explode(',', get_config('tool_mfa', 'factor_order'));
foreach ($orderarray as $order => $factorname) {
foreach ($unsorted as $key => $factor) {
if ($factor->name == $factorname) {
$sorted[] = $factor;
unset($unsorted[$key]);
}
}
}
$sorted = array_merge($sorted, $unsorted);
return $sorted;
}
/**
* Finds factor by its name.
*
* @param string $name
*
* @return mixed factor object or false if factor not found.
*/
public static function get_factor($name) {
$factors = \core_plugin_manager::instance()->get_plugins_of_type('factor');
foreach ($factors as $factor) {
if ($name == $factor->name) {
$classname = '\\factor_'.$factor->name.'\\factor';
if (class_exists($classname)) {
return new $classname($factor->name);
}
}
}
return false;
}
/**
* Finds all enabled factors.
*
* @return array of factor objects
*/
public static function get_enabled_factors() {
$return = [];
$factors = self::get_factors();
foreach ($factors as $factor) {
if ($factor->is_enabled()) {
$return[] = $factor;
}
}
return $return;
}
/**
* Finds active factors for current user.
*
* @return array of factor objects.
*/
public static function get_active_user_factor_types() {
global $USER;
$return = [];
$factors = self::get_enabled_factors();
foreach ($factors as $factor) {
$userfactors = $factor->get_active_user_factors($USER);
if (count($userfactors) > 0) {
$return[] = $factor;
}
}
return $return;
}
/**
* Finds active factors for given user.
*
* @param stdClass $user the user to get types for.
* @return array of factor objects.
*/
public static function get_active_other_user_factor_types($user) {
$return = [];
$factors = self::get_enabled_factors();
foreach ($factors as $factor) {
$userfactors = $factor->get_active_user_factors($user);
if (count($userfactors) > 0) {
$return[] = $factor;
}
}
return $return;
}
/**
* Returns next factor to authenticate user.
*
* @return mixed factor object the next factor to be authenticated or false.
*/
public static function get_next_user_factor() {
$factors = self::get_active_user_factor_types();
foreach ($factors as $factor) {
if (!$factor->has_input()) {
continue;
}
if ($factor->get_state() == self::STATE_UNKNOWN) {
return $factor;
}
}
return new \tool_mfa\local\factor\fallback();
}
/**
* Returns the list of available actions with factor.
*
* @return array
*/
public static function get_factor_actions() {
$actions = [];
$actions[] = 'setup';
$actions[] = 'revoke';
$actions[] = 'enable';
$actions[] = 'revoke';
$actions[] = 'disable';
$actions[] = 'up';
$actions[] = 'down';
return $actions;
}
/**
* Returns the information about plugin availability
*
* True means that the plugin is enabled. False means that the plugin is
* disabled. Null means that the information is not available, or the
* plugin does not support configurable availability or the availability
* can not be changed.
*
* @return null|bool
*/
public function is_enabled() {
if (!$this->rootdir) {
// Plugin missing.
return false;
}
$factor = $this->get_factor($this->name);
if ($factor) {
return $factor->is_enabled();
}
return false;
}
/**
* Returns section name for settings.
*
* @return string
*/
public function get_settings_section_name() {
return $this->type . '_' . $this->name;
}
/**
* Loads factor settings to the settings tree
*
* This function usually includes settings.php file in plugins folder.
* Alternatively it can create a link to some settings page (instance of admin_externalpage)
*
* @param \part_of_admin_tree $adminroot
* @param string $parentnodename
* @param bool $hassiteconfig whether the current user has moodle/site:config capability
*/
public function load_settings(\part_of_admin_tree $adminroot, $parentnodename, $hassiteconfig) {
if (!$this->is_installed_and_upgraded()) {
return;
}
if (!$hassiteconfig || !file_exists($this->full_path('settings.php'))) {
return;
}
$section = $this->get_settings_section_name();
$settings = new \admin_settingpage($section, $this->displayname, 'moodle/site:config', $this->is_enabled() === false);
if ($adminroot->fulltree) {
include($this->full_path('settings.php'));
}
$adminroot->add($parentnodename, $settings);
}
/**
* Checks that given factor exists.
*
* @param string $factorname
*
* @return bool
*/
public static function factor_exists($factorname) {
$factor = self::get_factor($factorname);
return !$factor ? false : true;
}
/**
* Returns instance of any factor from the factorid.
*
* @param int $factorid
*
* @return stdClass|null Factor instance or nothing if not found.
*/
public static function get_instance_from_id($factorid) {
global $DB;
return $DB->get_record('tool_mfa', ['id' => $factorid]);
}
}