MDL-80612 auth: Allow plugins to identify Moodle users on the CLI

This commit is contained in:
Brendan Heywood 2024-03-21 00:09:12 +11:00
parent c895def59b
commit 2d286ef8f8
5 changed files with 170 additions and 0 deletions

View File

@ -4,6 +4,7 @@ information provided here is intended especially for developers.
=== 4.4 ===
* A sesskey is no longer passed to the auth/test_settings.php page so it can no longer be required in test_settings().
* Auth plugins can now attempt to identify users running CLI scripts using a new method find_cli_user()
=== 4.2 ===
* Support for configuration with the deprecated auth_config.php file has been removed.

View File

@ -832,6 +832,66 @@ class auth_plugin_base {
public function get_extrauserinfo(): array {
return $this->extrauserinfo;
}
/**
* Returns the enabled auth plugins
*
* @return array of plugin classes
*/
public static function get_enabled_auth_plugin_classes(): array {
$plugins = [];
$authsequence = get_enabled_auth_plugins();
foreach ($authsequence as $authname) {
$plugins[] = get_auth_plugin($authname);
}
return $plugins;
}
/**
* Find an OS level admin Moodle user account
*
* Used when running CLI scripts. Only accounts which are
* site admin will be accepted.
*
* @return null|stdClass Admin user record if found
*/
public static function find_cli_admin_user(): ?stdClass {
$plugins = static::get_enabled_auth_plugin_classes();
foreach ($plugins as $authplugin) {
$user = $authplugin->find_cli_user();
// This MUST be a valid admin user.
if (!empty($user) && is_siteadmin($user->id)) {
return $user;
}
}
return null;
}
/**
* Find and login as an OS level admin Moodle user account
*
* Used for running CLI scripts which must be admin accounts.
*/
public static function login_cli_admin_user(): void {
$user = static::find_cli_admin_user();
if (!empty($user)) {
\core\session\manager::set_user($user);
}
}
/**
* Identify a Moodle account on the CLI
*
* For example a plugin might use posix_geteuid and posix_getpwuid
* to find the username of the OS level user and then match that
* against Moodle user accounts.
*
* @return null|stdClass User user record if found
*/
public function find_cli_user(): ?stdClass {
// Override if needed.
return null;
}
}
/**

View File

@ -1027,6 +1027,11 @@ if (!empty($CFG->debugvalidators) and !empty($CFG->guestloginbutton)) {
// can be using in the logfile and stripped out if needed.
set_access_log_user();
if (CLI_SCRIPT && !empty($CFG->version)) {
// Allow auth plugins to optionally authenticate users on the CLI.
require_once($CFG->libdir. '/authlib.php');
auth_plugin_base::login_cli_admin_user();
}
// Ensure the urlrewriteclass is setup correctly (to avoid crippling site).
if (isset($CFG->urlrewriteclass)) {

View File

@ -504,4 +504,50 @@ class authlib_test extends \advanced_testcase {
// Restore the original email address validator.
\moodle_phpmailer::$validator = $defaultvalidator;
}
/**
* Test the find_cli_user method
* @covers ::find_cli_user
*/
public function test_find_cli_user(): void {
global $CFG, $USER;
require_once("$CFG->libdir/authlib.php");
require_once("$CFG->libdir/tests/fixtures/testable_auth_plugin_base.php");
$this->resetAfterTest();
$user = \testable_auth_plugin_base::find_cli_admin_user();
$this->assertEmpty($user);
$u1 = $this->getDataGenerator()->create_user([
'username' => 'abcdef',
'email' => 'abcdef@example.com',
]);
$user = \testable_auth_plugin_base::find_cli_admin_user();
$this->assertEmpty($user); // User is not an admin yet.
\testable_auth_plugin_base::login_cli_admin_user();
$this->assertEquals($USER->id, 0); // User is not logged in.
$CFG->siteadmins .= "," . $u1->id;
\testable_auth_plugin_base::login_cli_admin_user();
$this->assertEquals($USER->id, $u1->id); // User is now logged in.
$user = \testable_auth_plugin_base::find_cli_admin_user();
$this->assertNotEmpty($user);
}
/**
* Test the get_enabled_auth_plugin_classes method
* @covers ::get_enabled_auth_plugin_classes
*/
public function test_get_enabled_auth_plugin_classes(): void {
global $CFG;
require_once("$CFG->libdir/authlib.php");
$plugins = \auth_plugin_base::get_enabled_auth_plugin_classes();
$this->assertEquals(get_class($plugins[0]), 'auth_plugin_manual');
$this->assertEquals(count($plugins), 3);
}
}

View File

@ -0,0 +1,58 @@
<?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/>.
/**
* Provides testable_auth_plugin_base class.
*
* @package core
* @subpackage fixtures
* @category test
* @copyright 2024 Catalyst IT
* @author Brendan Heywood <brendan@catalyst-au.net>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class testable_auth_plugin_base extends \auth_plugin_base {
/**
* Override to add test auth plugin
*
* @return array of plugin classes
*/
public static function get_enabled_auth_plugin_classes(): array {
$plugins = parent::get_enabled_auth_plugin_classes();
$plugins[] = new testable_auth_plugin_base();
return $plugins;
}
/**
* Identify a Moodle account on the CLI
*
* For example a plugin might use posix_geteuid and posix_getpwuid
* to find the username of the OS level user and then match that
* against Moodle user accounts.
*
* @return null|stdClass User user record if found
*/
public function find_cli_user(): ?stdClass {
global $DB;
$user = $DB->get_record('user', ['username' => 'abcdef']);
if ($user) {
return $user;
}
return null;
}
}