first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+259
View File
@@ -0,0 +1,259 @@
<?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/>.
/**
* Authentication Plugin: Email Authentication
*
* @author Martin Dougiamas
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package auth_email
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/authlib.php');
/**
* Email authentication plugin.
*/
class auth_plugin_email extends auth_plugin_base {
/**
* Constructor.
*/
public function __construct() {
$this->authtype = 'email';
$this->config = get_config('auth_email');
}
/**
* Old syntax of class constructor. Deprecated in PHP7.
*
* @deprecated since Moodle 3.1
*/
public function auth_plugin_email() {
debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
self::__construct();
}
/**
* Returns true if the username and password work and false if they are
* wrong or don't exist.
*
* @param string $username The username
* @param string $password The password
* @return bool Authentication success or failure.
*/
function user_login($username, $password) {
global $CFG, $DB;
if ($user = $DB->get_record('user', array('username'=>$username, 'mnethostid'=>$CFG->mnet_localhost_id))) {
return validate_internal_user_password($user, $password);
}
return false;
}
/**
* Updates the user's password.
*
* called when the user password is updated.
*
* @param object $user User table object (with system magic quotes)
* @param string $newpassword Plaintext password (with system magic quotes)
* @return boolean result
*
*/
function user_update_password($user, $newpassword) {
$user = get_complete_user_data('id', $user->id);
// This will also update the stored hash to the latest algorithm
// if the existing hash is using an out-of-date algorithm (or the
// legacy md5 algorithm).
return update_internal_user_password($user, $newpassword);
}
function can_signup() {
return true;
}
/**
* Sign up a new user ready for confirmation.
* Password is passed in plaintext.
*
* @param object $user new user object
* @param boolean $notify print notice with link and terminate
*/
function user_signup($user, $notify=true) {
// Standard signup, without custom confirmatinurl.
return $this->user_signup_with_confirmation($user, $notify);
}
/**
* Sign up a new user ready for confirmation.
*
* Password is passed in plaintext.
* A custom confirmationurl could be used.
*
* @param object $user new user object
* @param boolean $notify print notice with link and terminate
* @param string $confirmationurl user confirmation URL
* @return boolean true if everything well ok and $notify is set to true
* @throws moodle_exception
* @since Moodle 3.2
*/
public function user_signup_with_confirmation($user, $notify=true, $confirmationurl = null) {
global $CFG, $DB, $SESSION;
require_once($CFG->dirroot.'/user/profile/lib.php');
require_once($CFG->dirroot.'/user/lib.php');
$plainpassword = $user->password;
$user->password = hash_internal_user_password($user->password);
if (empty($user->calendartype)) {
$user->calendartype = $CFG->calendartype;
}
$user->id = user_create_user($user, false, false);
user_add_password_history($user->id, $plainpassword);
// Save any custom profile field information.
profile_save_data($user);
// Save wantsurl against user's profile, so we can return them there upon confirmation.
if (!empty($SESSION->wantsurl)) {
set_user_preference('auth_email_wantsurl', $SESSION->wantsurl, $user);
}
// Trigger event.
\core\event\user_created::create_from_userid($user->id)->trigger();
if (! send_confirmation_email($user, $confirmationurl)) {
throw new \moodle_exception('auth_emailnoemail', 'auth_email');
}
if ($notify) {
global $CFG, $PAGE, $OUTPUT;
$emailconfirm = get_string('emailconfirm');
$PAGE->navbar->add($emailconfirm);
$PAGE->set_title($emailconfirm);
$PAGE->set_heading($PAGE->course->fullname);
echo $OUTPUT->header();
notice(get_string('emailconfirmsent', '', $user->email), "$CFG->wwwroot/index.php");
} else {
return true;
}
}
/**
* Returns true if plugin allows confirming of new users.
*
* @return bool
*/
function can_confirm() {
return true;
}
/**
* Confirm the new user as registered.
*
* @param string $username
* @param string $confirmsecret
*/
function user_confirm($username, $confirmsecret) {
global $DB, $SESSION;
$user = get_complete_user_data('username', $username);
if (!empty($user)) {
if ($user->auth != $this->authtype) {
return AUTH_CONFIRM_ERROR;
} else if ($user->secret === $confirmsecret && $user->confirmed) {
return AUTH_CONFIRM_ALREADY;
} else if ($user->secret === $confirmsecret) { // They have provided the secret key to get in
$DB->set_field("user", "confirmed", 1, array("id"=>$user->id));
if ($wantsurl = get_user_preferences('auth_email_wantsurl', false, $user)) {
// Ensure user gets returned to page they were trying to access before signing up.
$SESSION->wantsurl = $wantsurl;
unset_user_preference('auth_email_wantsurl', $user);
}
return AUTH_CONFIRM_OK;
}
} else {
return AUTH_CONFIRM_ERROR;
}
}
function prevent_local_passwords() {
return false;
}
/**
* Returns true if this authentication plugin is 'internal'.
*
* @return bool
*/
function is_internal() {
return true;
}
/**
* Returns true if this authentication plugin can change the user's
* password.
*
* @return bool
*/
function can_change_password() {
return true;
}
/**
* Returns the URL for changing the user's pw, or empty if the default can
* be used.
*
* @return moodle_url
*/
function change_password_url() {
return null; // use default internal method
}
/**
* Returns true if plugin allows resetting of internal password.
*
* @return bool
*/
function can_reset_password() {
return true;
}
/**
* Returns true if plugin can be manually set.
*
* @return bool
*/
function can_be_manually_set() {
return true;
}
/**
* Returns whether or not the captcha element is enabled.
* @return bool
*/
function is_captcha_enabled() {
return get_config("auth_{$this->authtype}", 'recaptcha');
}
}
+384
View File
@@ -0,0 +1,384 @@
<?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/>.
/**
* Auth e-mail external API
*
* @package auth_email
* @category external
* @copyright 2016 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.2
*/
use core_external\external_api;
use core_external\external_format_value;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
defined('MOODLE_INTERNAL') || die;
require_once($CFG->libdir . '/authlib.php');
require_once($CFG->dirroot . '/user/editlib.php');
require_once($CFG->dirroot . '/user/profile/lib.php');
/**
* Auth e-mail external functions
*
* @package auth_email
* @category external
* @copyright 2016 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.2
*/
class auth_email_external extends external_api {
/**
* Check if registration is enabled in this site.
*
* @throws moodle_exception
* @since Moodle 3.2
*/
protected static function check_signup_enabled() {
global $CFG;
if (empty($CFG->registerauth) or $CFG->registerauth != 'email') {
throw new moodle_exception('registrationdisabled', 'error');
}
}
/**
* Describes the parameters for get_signup_settings.
*
* @return external_function_parameters
* @since Moodle 3.2
*/
public static function get_signup_settings_parameters() {
return new external_function_parameters(array());
}
/**
* Get the signup required settings and profile fields.
*
* @return array settings and possible warnings
* @since Moodle 3.2
* @throws moodle_exception
*/
public static function get_signup_settings() {
global $CFG, $PAGE;
$context = context_system::instance();
// We need this to make work the format text functions.
$PAGE->set_context($context);
self::check_signup_enabled();
$result = array();
$result['namefields'] = useredit_get_required_name_fields();
if (!empty($CFG->passwordpolicy)) {
$result['passwordpolicy'] = print_password_policy();
}
$manager = new \core_privacy\local\sitepolicy\manager();
if ($sitepolicy = $manager->get_embed_url()) {
$result['sitepolicy'] = $sitepolicy->out(false);
}
if (!empty($CFG->sitepolicyhandler)) {
$result['sitepolicyhandler'] = $CFG->sitepolicyhandler;
}
if (!empty($CFG->defaultcity)) {
$result['defaultcity'] = $CFG->defaultcity;
}
if (!empty($CFG->country)) {
$result['country'] = $CFG->country;
}
$result['extendedusernamechars'] = !empty($CFG->extendedusernamechars);
if ($fields = profile_get_signup_fields()) {
$result['profilefields'] = array();
foreach ($fields as $field) {
$fielddata = $field->object->get_field_config_for_external();
$fielddata['categoryname'] = \core_external\util::format_string($field->categoryname, $context->id);
$fielddata['name'] = \core_external\util::format_string($fielddata['name'], $context->id);
list($fielddata['defaultdata'], $fielddata['defaultdataformat']) =
\core_external\util::format_text($fielddata['defaultdata'], $fielddata['defaultdataformat'], $context->id);
$result['profilefields'][] = $fielddata;
}
}
if (signup_captcha_enabled()) {
// With reCAPTCHA v2 the captcha will be rendered by the mobile client using just the publickey.
$result['recaptchapublickey'] = $CFG->recaptchapublickey;
}
$result['warnings'] = array();
return $result;
}
/**
* Describes the get_signup_settings return value.
*
* @return external_single_structure
* @since Moodle 3.2
*/
public static function get_signup_settings_returns() {
return new external_single_structure(
[
'namefields' => new external_multiple_structure(
new external_value(PARAM_NOTAGS, 'The order of the name fields')
),
'passwordpolicy' => new external_value(PARAM_RAW, 'Password policy', VALUE_OPTIONAL),
'sitepolicy' => new external_value(PARAM_RAW, 'Site policy', VALUE_OPTIONAL),
'sitepolicyhandler' => new external_value(PARAM_PLUGIN, 'Site policy handler', VALUE_OPTIONAL),
'defaultcity' => new external_value(PARAM_NOTAGS, 'Default city', VALUE_OPTIONAL),
'country' => new external_value(PARAM_ALPHA, 'Default country', VALUE_OPTIONAL),
'extendedusernamechars' => new external_value(
PARAM_BOOL, 'Extended characters in usernames or not', VALUE_OPTIONAL
),
'profilefields' => new external_multiple_structure(
new external_single_structure(
[
'id' => new external_value(PARAM_INT, 'Profile field id', VALUE_OPTIONAL),
'shortname' => new external_value(PARAM_ALPHANUMEXT, 'Profile field shortname', VALUE_OPTIONAL),
'name' => new external_value(PARAM_RAW, 'Profield field name', VALUE_OPTIONAL),
'datatype' => new external_value(PARAM_ALPHANUMEXT, 'Profield field datatype', VALUE_OPTIONAL),
'description' => new external_value(PARAM_RAW, 'Profield field description', VALUE_OPTIONAL),
'descriptionformat' => new external_format_value('description'),
'categoryid' => new external_value(PARAM_INT, 'Profield field category id', VALUE_OPTIONAL),
'categoryname' => new external_value(PARAM_RAW, 'Profield field category name', VALUE_OPTIONAL),
'sortorder' => new external_value(PARAM_INT, 'Profield field sort order', VALUE_OPTIONAL),
'required' => new external_value(PARAM_INT, 'Profield field required', VALUE_OPTIONAL),
'locked' => new external_value(PARAM_INT, 'Profield field locked', VALUE_OPTIONAL),
'visible' => new external_value(PARAM_INT, 'Profield field visible', VALUE_OPTIONAL),
'forceunique' => new external_value(PARAM_INT, 'Profield field unique', VALUE_OPTIONAL),
'signup' => new external_value(PARAM_INT, 'Profield field in signup form', VALUE_OPTIONAL),
'defaultdata' => new external_value(PARAM_RAW, 'Profield field default data', VALUE_OPTIONAL),
'defaultdataformat' => new external_format_value('defaultdata'),
'param1' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL),
'param2' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL),
'param3' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL),
'param4' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL),
'param5' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL),
]
), 'Required profile fields', VALUE_OPTIONAL
),
'recaptchapublickey' => new external_value(PARAM_RAW, 'Recaptcha public key', VALUE_OPTIONAL),
'recaptchachallengehash' => new external_value(PARAM_RAW, 'Recaptcha challenge hash', VALUE_OPTIONAL),
'recaptchachallengeimage' => new external_value(PARAM_URL, 'Recaptcha challenge noscript image', VALUE_OPTIONAL),
'recaptchachallengejs' => new external_value(PARAM_URL, 'Recaptcha challenge js url', VALUE_OPTIONAL),
'warnings' => new external_warnings(),
]
);
}
/**
* Describes the parameters for signup_user.
*
* @return external_function_parameters
* @since Moodle 3.2
*/
public static function signup_user_parameters() {
return new external_function_parameters(
array(
'username' => new external_value(core_user::get_property_type('username'), 'Username'),
'password' => new external_value(core_user::get_property_type('password'), 'Plain text password'),
'firstname' => new external_value(core_user::get_property_type('firstname'), 'The first name(s) of the user'),
'lastname' => new external_value(core_user::get_property_type('lastname'), 'The family name of the user'),
'email' => new external_value(core_user::get_property_type('email'), 'A valid and unique email address'),
'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user', VALUE_DEFAULT, ''),
'country' => new external_value(core_user::get_property_type('country'), 'Home country code', VALUE_DEFAULT, ''),
'recaptchachallengehash' => new external_value(PARAM_RAW, 'Recaptcha challenge hash', VALUE_DEFAULT, ''),
'recaptcharesponse' => new external_value(PARAM_NOTAGS, 'Recaptcha response', VALUE_DEFAULT, ''),
'customprofilefields' => new external_multiple_structure(
new external_single_structure(
array(
'type' => new external_value(PARAM_ALPHANUMEXT, 'The type of the custom field'),
'name' => new external_value(PARAM_ALPHANUMEXT, 'The name of the custom field'),
'value' => new external_value(PARAM_RAW, 'Custom field value, can be an encoded json if required')
)
), 'User custom fields (also known as user profile fields)', VALUE_DEFAULT, array()
),
'redirect' => new external_value(PARAM_LOCALURL, 'Redirect the user to this site url after confirmation.',
VALUE_DEFAULT, ''),
)
);
}
/**
* Get the signup required settings and profile fields.
*
* @param string $username username
* @param string $password plain text password
* @param string $firstname the first name(s) of the user
* @param string $lastname the family name of the user
* @param string $email a valid and unique email address
* @param string $city home city of the user
* @param string $country home country code
* @param string $recaptchachallengehash recaptcha challenge hash
* @param string $recaptcharesponse recaptcha response
* @param array $customprofilefields user custom fields (also known as user profile fields)
* @param string $redirect Site url to redirect the user after confirmation
* @return array settings and possible warnings
* @since Moodle 3.2
* @throws moodle_exception
* @throws invalid_parameter_exception
*/
public static function signup_user($username, $password, $firstname, $lastname, $email, $city = '', $country = '',
$recaptchachallengehash = '', $recaptcharesponse = '', $customprofilefields = array(),
$redirect = '') {
global $CFG, $PAGE;
$warnings = array();
$params = self::validate_parameters(
self::signup_user_parameters(),
array(
'username' => $username,
'password' => $password,
'firstname' => $firstname,
'lastname' => $lastname,
'email' => $email,
'city' => $city,
'country' => $country,
'recaptchachallengehash' => $recaptchachallengehash,
'recaptcharesponse' => $recaptcharesponse,
'customprofilefields' => $customprofilefields,
'redirect' => $redirect,
)
);
// We need this to make work the format text functions.
$context = context_system::instance();
$PAGE->set_context($context);
self::check_signup_enabled();
// Validate profile fields param types.
$allowedfields = profile_get_signup_fields();
$fieldproperties = array();
$fieldsrequired = array();
foreach ($allowedfields as $field) {
$fieldproperties[$field->object->inputname] = $field->object->get_field_properties();
if ($field->object->is_required()) {
$fieldsrequired[$field->object->inputname] = true;
}
}
foreach ($params['customprofilefields'] as $profilefield) {
if (!array_key_exists($profilefield['name'], $fieldproperties)) {
throw new invalid_parameter_exception('Invalid field' . $profilefield['name']);
}
list($type, $allownull) = $fieldproperties[$profilefield['name']];
validate_param($profilefield['value'], $type, $allownull);
// Remove from the potential required list.
if (isset($fieldsrequired[$profilefield['name']])) {
unset($fieldsrequired[$profilefield['name']]);
}
}
if (!empty($fieldsrequired)) {
throw new invalid_parameter_exception('Missing required parameters: ' . implode(',', array_keys($fieldsrequired)));
}
// Validate the data sent.
$data = $params;
$data['email2'] = $data['email'];
// Force policy agreed if a site policy is set. The client is responsible of implementing the interface check.
$manager = new \core_privacy\local\sitepolicy\manager();
if ($manager->is_defined()) {
$data['policyagreed'] = 1;
}
unset($data['recaptcharesponse']);
unset($data['customprofilefields']);
// Add profile fields data.
foreach ($params['customprofilefields'] as $profilefield) {
// First, check if the value is a json (some profile fields like text area uses an array for sending data).
$datadecoded = json_decode($profilefield['value'], true);
if (is_array($datadecoded) && (json_last_error() == JSON_ERROR_NONE)) {
$data[$profilefield['name']] = $datadecoded;
} else {
$data[$profilefield['name']] = $profilefield['value'];
}
}
$errors = signup_validate_data($data, array());
// Validate recaptcha.
if (signup_captcha_enabled()) {
require_once($CFG->libdir . '/recaptchalib_v2.php');
$response = recaptcha_check_response(RECAPTCHA_VERIFY_URL, $CFG->recaptchaprivatekey,
getremoteaddr(), $params['recaptcharesponse']);
if (!$response['isvalid']) {
$errors['recaptcharesponse'] = $response['error'];
}
}
if (!empty($errors)) {
foreach ($errors as $itemname => $message) {
$warnings[] = array(
'item' => $itemname,
'itemid' => 0,
'warningcode' => 'fielderror',
'message' => s($message)
);
}
$result = array(
'success' => false,
'warnings' => $warnings,
);
} else {
// Save the user.
$user = signup_setup_new_user((object) $data);
$authplugin = get_auth_plugin('email');
// Check if we should redirect the user once the user is confirmed.
$confirmationurl = null;
if (!empty($params['redirect'])) {
// Pass via moodle_url to fix thinks like admin links.
$redirect = new moodle_url($params['redirect']);
$confirmationurl = new moodle_url('/login/confirm.php', array('redirect' => $redirect->out()));
}
$authplugin->user_signup_with_confirmation($user, false, $confirmationurl);
$result = array(
'success' => true,
'warnings' => array(),
);
}
return $result;
}
/**
* Describes the signup_user return value.
*
* @return external_single_structure
* @since Moodle 3.2
*/
public static function signup_user_returns() {
return new external_single_structure(
array(
'success' => new external_value(PARAM_BOOL, 'True if the user was created false otherwise'),
'warnings' => new external_warnings(),
)
);
}
}
+41
View File
@@ -0,0 +1,41 @@
<?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/>.
/**
* Privacy Subsystem implementation for auth_email.
*
* @package auth_email
* @copyright 2018 Carlos Escobedo <carlos@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace auth_email\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for auth_email implementing null_provider.
*
* @copyright 2018 Carlos Escobedo <carlos@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+46
View File
@@ -0,0 +1,46 @@
<?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/>.
/**
* Auth email webservice definitions.
*
* @package auth_email
* @copyright 2016 Juan Leyva
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$functions = array(
'auth_email_get_signup_settings' => array(
'classname' => 'auth_email_external',
'methodname' => 'get_signup_settings',
'description' => 'Get the signup required settings and profile fields.',
'type' => 'read',
'ajax' => true,
'loginrequired' => false,
),
'auth_email_signup_user' => array(
'classname' => 'auth_email_external',
'methodname' => 'signup_user',
'description' => 'Adds a new user (pendingto be confirmed) in the site.',
'type' => 'write',
'ajax' => true,
'loginrequired' => false,
),
);
+44
View File
@@ -0,0 +1,44 @@
<?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/>.
/**
* No authentication plugin upgrade code
*
* @package auth_email
* @copyright 2017 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Function to upgrade auth_email.
* @param int $oldversion the version we are upgrading from
* @return bool result
*/
function xmldb_auth_email_upgrade($oldversion) {
// Automatically generated Moodle v4.1.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
+31
View File
@@ -0,0 +1,31 @@
<?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/>.
/**
* Strings for component 'auth_email', language 'en'.
*
* @package auth_email
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['auth_emaildescription'] = '<p>Email-based self-registration enables a user to create their own account via a \'Create new account\' button on the login page. The user then receives an email containing a secure link to a page where they can confirm their account. Future logins just check the username and password against the stored values in the Moodle database.</p><p>Note: In addition to enabling the plugin, email-based self-registration must also be selected from the self registration drop-down menu on the \'Manage authentication\' page.</p>';
$string['auth_emailnoemail'] = 'Tried to send you an email but failed!';
$string['auth_emailrecaptcha'] = 'Adds a visual/audio confirmation form element to the sign-up page for email self-registering users. This protects your site against spammers and contributes to a worthwhile cause. See https://www.google.com/recaptcha for more details.';
$string['auth_emailrecaptcha_key'] = 'Enable reCAPTCHA element';
$string['auth_emailsettings'] = 'Settings';
$string['pluginname'] = 'Email-based self-registration';
$string['privacy:metadata'] = 'The Email-based self-registration authentication plugin does not store any personal data.';
+46
View File
@@ -0,0 +1,46 @@
<?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/>.
/**
* Admin settings and defaults.
*
* @package auth_email
* @copyright 2017 Stephen Bourget
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($ADMIN->fulltree) {
// Introductory explanation.
$settings->add(new admin_setting_heading('auth_email/pluginname', '',
new lang_string('auth_emaildescription', 'auth_email')));
$options = array(
new lang_string('no'),
new lang_string('yes'),
);
$settings->add(new admin_setting_configselect('auth_email/recaptcha',
new lang_string('auth_emailrecaptcha_key', 'auth_email'),
new lang_string('auth_emailrecaptcha', 'auth_email'), 0, $options));
// Display locking / mapping of profile fields.
$authplugin = get_auth_plugin('email');
display_auth_lock_options($settings, $authplugin->authtype, $authplugin->userfields,
get_string('auth_fieldlocks_help', 'auth'), false, false);
}
@@ -0,0 +1,54 @@
<?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/>.
/**
* Step definition for auth_email
*
* @package auth_email
* @category test
* @copyright 2018 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');
/**
* Step definition for auth_email.
*
* @package auth_email
* @category test
* @copyright 2018 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_auth_email extends behat_base {
/**
* Emulate clicking on confirmation link from the email
*
* @When /^I confirm email for "(?P<username>(?:[^"]|\\")*)"$/
*
* @param string $username
*/
public function i_confirm_email_for($username) {
global $DB;
$secret = $DB->get_field('user', 'secret', ['username' => $username], MUST_EXIST);
$confirmationurl = new moodle_url('/login/confirm.php');
$confirmationpath = $confirmationurl->out_as_local_url(false);
$url = $confirmationpath . '?' . 'data='. $secret .'/'. $username;
$this->execute('behat_general::i_visit', [$url]);
}
}
+98
View File
@@ -0,0 +1,98 @@
@auth @auth_email
Feature: User must accept policy when logging in and signing up
In order to record user agreement to use the site
As a user
I need to be able to accept site policy during sign up
Scenario: Accept policy on sign up, no site policy
Given the following config values are set as admin:
| registerauth | email |
| passwordpolicy | 0 |
And I am on site homepage
And I follow "Log in"
When I click on "Create new account" "link"
Then I should not see "I understand and agree"
And I set the following fields to these values:
| Username | user1 |
| Password | user1 |
| Email address | user1@address.invalid |
| Email (again) | user1@address.invalid |
| First name | User1 |
| Last name | L1 |
And I press "Create my new account"
And I should see "Confirm your account"
And I should see "An email should have been sent to your address at user1@address.invalid"
And I confirm email for "user1"
And I should see "Thanks, User1 L1"
And I should see "Your registration has been confirmed"
And I open my profile in edit mode
And the field "First name" matches value "User1"
And I log out
# Confirm that user can login and browse the site (edit their profile).
And I log in as "user1"
And I open my profile in edit mode
And the field "First name" matches value "User1"
Scenario: Accept policy on sign up, with site policy
Given the following config values are set as admin:
| registerauth | email |
| passwordpolicy | 0 |
| sitepolicy | https://moodle.org |
And I am on site homepage
And I follow "Log in"
When I click on "Create new account" "link"
Then the field "I understand and agree" matches value "0"
And I set the following fields to these values:
| Username | user1 |
| Password | user1 |
| Email address | user1@address.invalid |
| Email (again) | user1@address.invalid |
| First name | User1 |
| Last name | L1 |
| I understand and agree | 1 |
And I press "Create my new account"
And I should see "Confirm your account"
And I should see "An email should have been sent to your address at user1@address.invalid"
And I confirm email for "user1"
And I should see "Thanks, User1 L1"
And I should see "Your registration has been confirmed"
And I open my profile in edit mode
And the field "First name" matches value "User1"
And I log out
# Confirm that user is not asked to agree to site policy again after the next login.
And I log in as "user1"
And I open my profile in edit mode
And the field "First name" matches value "User1"
Scenario Outline: Email validation during email registration
Given the following config values are set as admin:
| allowaccountssameemail | <allowsameemail> |
| registerauth | email |
| passwordpolicy | 0 |
And the following "users" exist:
| username | firstname | lastname | email |
| s1 | John | Doe | s1@example.com |
And I am on site homepage
And I follow "Log in"
When I click on "Create new account" "link"
And I set the following fields to these values:
| Username | s2 |
| Password | test |
| Email address | <email1> |
| Email (again) | <email2> |
| First name | Jane |
| Last name | Doe |
And I press "Create my new account"
Then I should <expect> "This email address is already registered. Perhaps you created an account in the past?"
And I should <expect2> "Invalid email address"
Examples:
| allowsameemail | email1 | email2 | expect | expect2 |
| 0 | s1@example.com | s1@example.com | see | not see |
| 0 | S1@EXAMPLE.COM | S1@EXAMPLE.COM | see | not see |
| 0 | s1@example.com | S1@EXAMPLE.COM | see | not see |
| 0 | s2@example.com | s1@example.com | not see | see |
| 1 | s1@example.com | s1@example.com | not see | not see |
| 1 | S1@EXAMPLE.COM | S1@EXAMPLE.COM | not see | not see |
| 1 | s1@example.com | S1@EXAMPLE.COM | not see | not see |
| 1 | s1@example.com | s2@example.com | not see | see |
+220
View File
@@ -0,0 +1,220 @@
<?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/>.
/**
* Auth email external functions tests.
*
* @package auth_email
* @category external
* @copyright 2016 Juan Leyva
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.2
*/
namespace auth_email\external;
use auth_email_external;
use externallib_advanced_testcase;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* External auth email API tests.
*
* @package auth_email
* @copyright 2016 Juan Leyva
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.2
*/
class external_test extends externallib_advanced_testcase {
/** @var int custom profile field1 ID. */
protected $field1;
/** @var int custom profile field2 ID. */
protected $field2;
/**
* Set up for every test
*/
public function setUp(): void {
global $CFG;
$this->resetAfterTest(true);
$CFG->registerauth = 'email';
$this->field1 = $this->getDataGenerator()->create_custom_profile_field(array(
'shortname' => 'frogname', 'name' => 'Name of frog',
'datatype' => 'text', 'signup' => 1, 'visible' => 1, 'required' => 1, 'sortorder' => 1))->id;
$this->field2 = $this->getDataGenerator()->create_custom_profile_field(array(
'shortname' => 'sometext', 'name' => 'Some text in textarea',
'datatype' => 'textarea', 'signup' => 1, 'visible' => 1, 'required' => 1, 'sortorder' => 2))->id;
}
public function test_get_signup_settings(): void {
global $CFG;
$CFG->defaultcity = 'Bcn';
$CFG->country = 'ES';
$CFG->sitepolicy = 'https://moodle.org';
$result = auth_email_external::get_signup_settings();
$result = \core_external\external_api::clean_returnvalue(auth_email_external::get_signup_settings_returns(), $result);
// Check expected data.
$this->assertEquals(array('firstname', 'lastname'), $result['namefields']);
$this->assertEquals($CFG->defaultcity, $result['defaultcity']);
$this->assertEquals($CFG->country, $result['country']);
$this->assertEquals($CFG->sitepolicy, $result['sitepolicy']);
$this->assertEquals(print_password_policy(), $result['passwordpolicy']);
$this->assertNotContains('recaptchachallengehash', $result);
$this->assertNotContains('recaptchachallengeimage', $result);
// Check if the extended username chars is returning false when is not set.
$this->assertFalse($result['extendedusernamechars']);
// Whip up a array with named entries to easily check against.
$namedarray = array();
foreach ($result['profilefields'] as $key => $value) {
$namedarray[$value['shortname']] = array(
'datatype' => $value['datatype']
);
}
// Just check if we have the fields from this test. If a plugin adds fields we'll let it slide.
$this->assertArrayHasKey('frogname', $namedarray);
$this->assertArrayHasKey('sometext', $namedarray);
$this->assertEquals('text', $namedarray['frogname']['datatype']);
$this->assertEquals('textarea', $namedarray['sometext']['datatype']);
$CFG->extendedusernamechars = true;
$result = auth_email_external::get_signup_settings();
$result = \core_external\external_api::clean_returnvalue(auth_email_external::get_signup_settings_returns(), $result);
$this->assertTrue($result['extendedusernamechars']);
}
/**
* Test get_signup_settings with mathjax in a profile field.
*/
public function test_get_signup_settings_with_mathjax_in_profile_fields(): void {
// Enable MathJax filter in content and headings.
$this->configure_filters([
['name' => 'mathjaxloader', 'state' => TEXTFILTER_ON, 'move' => -1, 'applytostrings' => true],
]);
// Create category with MathJax and a new field with MathJax.
$categoryname = 'Cat $$(a+b)=2$$';
$fieldname = 'Some text $$(a+b)=2$$';
$categoryid = $this->getDataGenerator()->create_custom_profile_field_category(['name' => $categoryname])->id;
$this->getDataGenerator()->create_custom_profile_field(array(
'shortname' => 'mathjaxname', 'name' => $fieldname, 'categoryid' => $categoryid,
'datatype' => 'textarea', 'signup' => 1, 'visible' => 1, 'required' => 1, 'sortorder' => 2));
$result = auth_email_external::get_signup_settings();
$result = \core_external\external_api::clean_returnvalue(auth_email_external::get_signup_settings_returns(), $result);
// Format the original data.
$sitecontext = \context_system::instance();
$categoryname = \core_external\util::format_string($categoryname, $sitecontext->id);
$fieldname = \core_external\util::format_string($fieldname, $sitecontext->id);
// Whip up a array with named entries to easily check against.
$namedarray = array();
foreach ($result['profilefields'] as $key => $value) {
$namedarray[$value['shortname']] = $value;
}
// Check the new profile field.
$this->assertArrayHasKey('mathjaxname', $namedarray);
$this->assertStringContainsString('<span class="filter_mathjaxloader_equation">',
$namedarray['mathjaxname']['categoryname']);
$this->assertStringContainsString('<span class="filter_mathjaxloader_equation">',
$namedarray['mathjaxname']['name']);
$this->assertEquals($categoryname, $namedarray['mathjaxname']['categoryname']);
$this->assertEquals($fieldname, $namedarray['mathjaxname']['name']);
}
public function test_signup_user(): void {
global $DB;
$username = 'pepe';
$password = 'abcdefAª.ªª!!3';
$firstname = 'Pepe';
$lastname = 'Pérez';
$email = 'myemail@no.zbc';
$city = 'Bcn';
$country = 'ES';
$customprofilefields = array(
array(
'type' => 'text',
'name' => 'profile_field_frogname',
'value' => 'random text',
),
array(
'type' => 'textarea',
'name' => 'profile_field_sometext',
'value' => json_encode(
array(
'text' => 'blah blah',
'format' => FORMAT_HTML
)
),
)
);
// Create new user.
$result = auth_email_external::signup_user($username, $password, $firstname, $lastname, $email, $city, $country,
'', '', $customprofilefields);
$result = \core_external\external_api::clean_returnvalue(auth_email_external::signup_user_returns(), $result);
$this->assertTrue($result['success']);
$this->assertEmpty($result['warnings']);
$user = $DB->get_record('user', array('username' => $username));
$this->assertEquals($firstname, $user->firstname);
$this->assertEquals($lastname, $user->lastname);
$this->assertEquals($email, $user->email);
$this->assertEquals($city, $user->city);
$this->assertEquals($country, $user->country);
$this->assertEquals(0, $user->confirmed);
$this->assertEquals(current_language(), $user->lang);
$this->assertEquals('email', $user->auth);
$infofield = $DB->get_record('user_info_data', array('userid' => $user->id, 'fieldid' => $this->field1));
$this->assertEquals($customprofilefields[0]['value'], $infofield->data);
$infofield = $DB->get_record('user_info_data', array('userid' => $user->id, 'fieldid' => $this->field2));
$this->assertEquals(json_decode($customprofilefields[1]['value'])->text, $infofield->data);
// Try to create a user with the same username, email and password. We ommit also the profile fields.
$password = 'abc';
$result = auth_email_external::signup_user($username, $password, $firstname, $lastname, $email, $city, $country,
'', '', $customprofilefields);
$result = \core_external\external_api::clean_returnvalue(auth_email_external::signup_user_returns(), $result);
$this->assertFalse($result['success']);
$this->assertCount(3, $result['warnings']);
$expectederrors = array('username', 'email', 'password');
$finalerrors = [];
foreach ($result['warnings'] as $warning) {
$finalerrors[] = $warning['item'];
}
$this->assertEquals($expectederrors, $finalerrors);
// Do not pass the required profile fields.
$this->expectException('invalid_parameter_exception');
$result = auth_email_external::signup_user($username, $password, $firstname, $lastname, $email, $city, $country);
}
}
+10
View File
@@ -0,0 +1,10 @@
This files describes API changes in /auth/email/*,
information provided here is intended especially for developers.
=== 4.4 ===
* External function auth_email_external::get_signup_settings() now returns the field "extendedusernamechars".
=== 3.3 ===
* The config.html file was migrated to use the admin settings API.
The identifier for configuration data stored in config_plugins table was converted from 'auth/email' to 'auth_email'.
+29
View File
@@ -0,0 +1,29 @@
<?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/>.
/**
* Version details
*
* @package auth_email
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'auth_email'; // Full name of the plugin (used for diagnostics)