mirror of
https://github.com/moodle/moodle.git
synced 2025-06-02 14:15:11 +02:00
Merge branch 'MDL-56092-master' of git://github.com/jleyva/moodle
This commit is contained in:
commit
2a864ee9a8
124
auth/classes/external.php
Normal file
124
auth/classes/external.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?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 external API
|
||||
*
|
||||
* @package core_auth
|
||||
* @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
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
require_once($CFG->libdir . '/externallib.php');
|
||||
require_once($CFG->libdir . '/authlib.php');
|
||||
|
||||
/**
|
||||
* Auth external functions
|
||||
*
|
||||
* @package core_auth
|
||||
* @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 core_auth_external extends external_api {
|
||||
|
||||
/**
|
||||
* Describes the parameters for confirm_user.
|
||||
*
|
||||
* @return external_external_function_parameters
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public static function confirm_user_parameters() {
|
||||
return new external_function_parameters(
|
||||
array(
|
||||
'username' => new external_value(core_user::get_property_type('username'), 'User name'),
|
||||
'secret' => new external_value(core_user::get_property_type('secret'), 'Confirmation secret'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm a user account.
|
||||
*
|
||||
* @param string $username user name
|
||||
* @param string $secret confirmation secret (random string) used for validating the confirm request
|
||||
* @return array warnings and success status (true if the user was confirmed, false if he was already confirmed)
|
||||
* @since Moodle 3.2
|
||||
* @throws moodle_exception
|
||||
*/
|
||||
public static function confirm_user($username, $secret) {
|
||||
global $PAGE;
|
||||
|
||||
$warnings = array();
|
||||
$params = self::validate_parameters(
|
||||
self::confirm_user_parameters(),
|
||||
array(
|
||||
'username' => $username,
|
||||
'secret' => $secret,
|
||||
)
|
||||
);
|
||||
|
||||
$context = context_system::instance();
|
||||
$PAGE->set_context($context);
|
||||
|
||||
if (!$authplugin = signup_get_user_confirmation_authplugin()) {
|
||||
throw new moodle_exception('confirmationnotenabled');
|
||||
}
|
||||
|
||||
$confirmed = $authplugin->user_confirm($username, $secret);
|
||||
|
||||
if ($confirmed == AUTH_CONFIRM_ALREADY) {
|
||||
$success = false;
|
||||
$warnings[] = array(
|
||||
'item' => 'user',
|
||||
'itemid' => 0,
|
||||
'warningcode' => 'alreadyconfirmed',
|
||||
'message' => s(get_string('alreadyconfirmed'))
|
||||
);
|
||||
} else if ($confirmed == AUTH_CONFIRM_OK) {
|
||||
$success = true;
|
||||
} else {
|
||||
throw new moodle_exception('invalidconfirmdata');
|
||||
}
|
||||
|
||||
$result = array(
|
||||
'success' => $success,
|
||||
'warnings' => $warnings,
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the confirm_user return value.
|
||||
*
|
||||
* @return external_single_structure
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public static function confirm_user_returns() {
|
||||
|
||||
return new external_single_structure(
|
||||
array(
|
||||
'success' => new external_value(PARAM_BOOL, 'True if the user was confirmed, false if he was already confirmed'),
|
||||
'warnings' => new external_warnings(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
352
auth/email/classes/external.php
Normal file
352
auth/email/classes/external.php
Normal file
@ -0,0 +1,352 @@
|
||||
<?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
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
require_once($CFG->libdir . '/externallib.php');
|
||||
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_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();
|
||||
}
|
||||
if (!empty($CFG->sitepolicy)) {
|
||||
$result['sitepolicy'] = $CFG->sitepolicy;
|
||||
}
|
||||
if (!empty($CFG->defaultcity)) {
|
||||
$result['defaultcity'] = $CFG->defaultcity;
|
||||
}
|
||||
if (!empty($CFG->country)) {
|
||||
$result['country'] = $CFG->country;
|
||||
}
|
||||
|
||||
if ($fields = profile_get_signup_fields()) {
|
||||
$result['profilefields'] = array();
|
||||
foreach ($fields as $field) {
|
||||
$fielddata = $field->object->get_field_config_for_external();
|
||||
$fielddata['categoryname'] = external_format_string($field->categoryname, $context->id);
|
||||
$fielddata['name'] = external_format_string($fielddata['name'], $context->id);
|
||||
list($fielddata['defaultdata'], $fielddata['defaultdataformat']) =
|
||||
external_format_text($fielddata['defaultdata'], $fielddata['defaultdataformat'], $context->id);
|
||||
|
||||
$result['profilefields'][] = $fielddata;
|
||||
}
|
||||
}
|
||||
|
||||
if (signup_captcha_enabled()) {
|
||||
require_once($CFG->libdir . '/recaptchalib.php');
|
||||
// We return the public key, maybe we want to use the javascript api to get the image.
|
||||
$result['recaptchapublickey'] = $CFG->recaptchapublickey;
|
||||
list($result['recaptchachallengehash'], $result['recaptchachallengeimage'], $result['recaptchachallengejs']) =
|
||||
recaptcha_get_challenge_hash_and_urls(RECAPTCHA_API_SECURE_SERVER, $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(
|
||||
array(
|
||||
'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_URL, 'Site policy url', VALUE_OPTIONAL),
|
||||
'defaultcity' => new external_value(PARAM_NOTAGS, 'Default city', VALUE_OPTIONAL),
|
||||
'country' => new external_value(PARAM_ALPHA, 'Default country', VALUE_OPTIONAL),
|
||||
'profilefields' => new external_multiple_structure(
|
||||
new external_single_structure(
|
||||
array(
|
||||
'id' => new external_value(PARAM_INT, 'Profile field id', VALUE_OPTIONAL),
|
||||
'shortname' => new external_value(PARAM_ALPHANUM, 'Password policy', VALUE_OPTIONAL),
|
||||
'name' => new external_value(PARAM_TEXT, '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_TEXT, '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_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()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @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()) {
|
||||
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,
|
||||
)
|
||||
);
|
||||
|
||||
// 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'];
|
||||
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.php');
|
||||
$response = recaptcha_check_answer($CFG->recaptchaprivatekey, getremoteaddr(), $params['recaptchachallengehash'],
|
||||
$params['recaptcharesponse'], true);
|
||||
if (!$response->is_valid) {
|
||||
$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');
|
||||
$authplugin->user_signup($user, false);
|
||||
|
||||
$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(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
46
auth/email/db/services.php
Normal file
46
auth/email/db/services.php
Normal 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,
|
||||
),
|
||||
);
|
||||
|
150
auth/email/tests/external_test.php
Normal file
150
auth/email/tests/external_test.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?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
|
||||
*/
|
||||
|
||||
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 auth_email_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
/**
|
||||
* Set up for every test
|
||||
*/
|
||||
public function setUp() {
|
||||
global $CFG, $DB;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$CFG->registerauth = 'email';
|
||||
|
||||
$categoryid = $DB->insert_record('user_info_category', array('name' => 'Cat 1', 'sortorder' => 1));
|
||||
$this->field1 = $DB->insert_record('user_info_field', array(
|
||||
'shortname' => 'frogname', 'name' => 'Name of frog', 'categoryid' => $categoryid,
|
||||
'datatype' => 'text', 'signup' => 1, 'visible' => 1, 'required' => 1));
|
||||
$this->field2 = $DB->insert_record('user_info_field', array(
|
||||
'shortname' => 'sometext', 'name' => 'Some text in textarea', 'categoryid' => $categoryid,
|
||||
'datatype' => 'textarea', 'signup' => 1, 'visible' => 1, 'required' => 1));
|
||||
}
|
||||
|
||||
public function test_get_signup_settings() {
|
||||
global $CFG;
|
||||
|
||||
$CFG->defaultcity = 'Bcn';
|
||||
$CFG->country = 'ES';
|
||||
$CFG->sitepolicy = 'https://moodle.org';
|
||||
|
||||
$result = auth_email_external::get_signup_settings();
|
||||
$result = 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);
|
||||
$this->assertCount(2, $result['profilefields']);
|
||||
$this->assertEquals('text', $result['profilefields'][0]['datatype']);
|
||||
$this->assertEquals('textarea', $result['profilefields'][1]['datatype']);
|
||||
}
|
||||
|
||||
public function test_signup_user() {
|
||||
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 = 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 = 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);
|
||||
}
|
||||
}
|
@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$plugin->version = 2016052300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->version = 2016052302; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2016051900; // Requires this Moodle version
|
||||
$plugin->component = 'auth_email'; // Full name of the plugin (used for diagnostics)
|
||||
|
92
auth/tests/external_test.php
Normal file
92
auth/tests/external_test.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?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 external functions tests.
|
||||
*
|
||||
* @package core_auth
|
||||
* @category external
|
||||
* @copyright 2016 Juan Leyva
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
|
||||
|
||||
/**
|
||||
* External auth API tests.
|
||||
*
|
||||
* @package core_auth
|
||||
* @copyright 2016 Juan Leyva
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
class core_auth_external_testcase extends externallib_advanced_testcase {
|
||||
|
||||
/**
|
||||
* Set up for every test
|
||||
*/
|
||||
public function setUp() {
|
||||
global $CFG;
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$CFG->registerauth = 'email';
|
||||
}
|
||||
|
||||
/**
|
||||
* Test confirm_user
|
||||
*/
|
||||
public function test_confirm_user() {
|
||||
global $DB;
|
||||
|
||||
$username = 'pepe';
|
||||
$password = 'abcdefAª.ªª!!3';
|
||||
$firstname = 'Pepe';
|
||||
$lastname = 'Pérez';
|
||||
$email = 'myemail@no.zbc';
|
||||
|
||||
// Create new user.
|
||||
$result = auth_email_external::signup_user($username, $password, $firstname, $lastname, $email);
|
||||
$result = external_api::clean_returnvalue(auth_email_external::signup_user_returns(), $result);
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertEmpty($result['warnings']);
|
||||
$secret = $DB->get_field('user', 'secret', array('username' => $username));
|
||||
|
||||
// Confirm the user.
|
||||
$result = core_auth_external::confirm_user($username, $secret);
|
||||
$result = external_api::clean_returnvalue(core_auth_external::confirm_user_returns(), $result);
|
||||
$this->assertTrue($result['success']);
|
||||
$this->assertEmpty($result['warnings']);
|
||||
$confirmed = $DB->get_field('user', 'confirmed', array('username' => $username));
|
||||
$this->assertEquals(1, $confirmed);
|
||||
|
||||
// Try to confirm the user again.
|
||||
$result = core_auth_external::confirm_user($username, $secret);
|
||||
$result = external_api::clean_returnvalue(core_auth_external::confirm_user_returns(), $result);
|
||||
$this->assertFalse($result['success']);
|
||||
$this->assertCount(1, $result['warnings']);
|
||||
$this->assertEquals('alreadyconfirmed', $result['warnings'][0]['warningcode']);
|
||||
|
||||
// Try to use an invalid secret.
|
||||
$this->expectException('moodle_exception');
|
||||
$this->expectExceptionMessage(get_string('invalidconfirmdata', 'error'));
|
||||
$result = core_auth_external::confirm_user($username, 'zzZZzz');
|
||||
}
|
||||
}
|
@ -172,6 +172,7 @@ $string['categorytoolong'] = 'Category name too long';
|
||||
$string['categoryidnumbertaken'] = 'ID number is already used for another category';
|
||||
$string['commentmisconf'] = 'Comment ID is misconfigured';
|
||||
$string['componentisuptodate'] = 'Component is up-to-date';
|
||||
$string['confirmationnotenabled'] = 'User confirmation is not enabled on this site';
|
||||
$string['confirmsesskeybad'] = 'Sorry, but your session key could not be confirmed to carry out this action. This security feature prevents against accidental or malicious execution of important functions in your name. Please make sure you really wanted to execute this function.';
|
||||
$string['couldnotassignrole'] = 'A serious but unspecified error occurred while trying to assign a role to you';
|
||||
$string['couldnotupdatenoexistinguser'] = 'Cannot update the user - user doesn\'t exist';
|
||||
@ -462,6 +463,7 @@ $string['querystringcannotbeempty'] = 'The query string cannot be empty.';
|
||||
$string['redirecterrordetected'] = 'Unsupported redirect detected, script execution terminated';
|
||||
$string['refoundto'] = 'Can be refunded to {$a}';
|
||||
$string['refoundtoorigi'] = 'Refunded to original amount: {$a}';
|
||||
$string['registrationdisabled'] = 'Registration is disabled on this site';
|
||||
$string['remotedownloaderror'] = '<p>The download of the component to your server failed. Please verify proxy settings; the PHP cURL extension is highly recommended.</p>
|
||||
<p>You must download the <a href="{$a->url}">{$a->url}</a> file manually, copy it to "{$a->dest}" in your server and unzip it there.</p>';
|
||||
$string['remotedownloadnotallowed'] = 'Download of components to your server isn\'t allowed (allow_url_fopen is disabled).<br /><br />You must download the <a href="{$a->url}">{$a->url}</a> file manually, copy it to "{$a->dest}" in your server and unzip it there.';
|
||||
|
120
lib/authlib.php
120
lib/authlib.php
@ -796,3 +796,123 @@ function login_unlock_account($user) {
|
||||
|
||||
// Note: do not clear the lockout secret because user might click on the link repeatedly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the captcha element is enabled, and the admin settings fulfil its requirements.
|
||||
* @return bool
|
||||
*/
|
||||
function signup_captcha_enabled() {
|
||||
global $CFG;
|
||||
$authplugin = get_auth_plugin($CFG->registerauth);
|
||||
return !empty($CFG->recaptchapublickey) && !empty($CFG->recaptchaprivatekey) && $authplugin->is_captcha_enabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the standard sign-up data (except recaptcha that is validated by the form element).
|
||||
*
|
||||
* @param array $data the sign-up data
|
||||
* @param array $files files among the data
|
||||
* @return array list of errors, being the key the data element name and the value the error itself
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
function signup_validate_data($data, $files) {
|
||||
global $CFG, $DB;
|
||||
|
||||
$errors = array();
|
||||
$authplugin = get_auth_plugin($CFG->registerauth);
|
||||
|
||||
if ($DB->record_exists('user', array('username' => $data['username'], 'mnethostid' => $CFG->mnet_localhost_id))) {
|
||||
$errors['username'] = get_string('usernameexists');
|
||||
} else {
|
||||
// Check allowed characters.
|
||||
if ($data['username'] !== core_text::strtolower($data['username'])) {
|
||||
$errors['username'] = get_string('usernamelowercase');
|
||||
} else {
|
||||
if ($data['username'] !== core_user::clean_field($data['username'], 'username')) {
|
||||
$errors['username'] = get_string('invalidusername');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Check if user exists in external db.
|
||||
// TODO: maybe we should check all enabled plugins instead.
|
||||
if ($authplugin->user_exists($data['username'])) {
|
||||
$errors['username'] = get_string('usernameexists');
|
||||
}
|
||||
|
||||
if (! validate_email($data['email'])) {
|
||||
$errors['email'] = get_string('invalidemail');
|
||||
|
||||
} else if ($DB->record_exists('user', array('email' => $data['email']))) {
|
||||
$errors['email'] = get_string('emailexists').' <a href="forgot_password.php">'.get_string('newpassword').'?</a>';
|
||||
}
|
||||
if (empty($data['email2'])) {
|
||||
$errors['email2'] = get_string('missingemail');
|
||||
|
||||
} else if ($data['email2'] != $data['email']) {
|
||||
$errors['email2'] = get_string('invalidemail');
|
||||
}
|
||||
if (!isset($errors['email'])) {
|
||||
if ($err = email_is_not_allowed($data['email'])) {
|
||||
$errors['email'] = $err;
|
||||
}
|
||||
}
|
||||
|
||||
$errmsg = '';
|
||||
if (!check_password_policy($data['password'], $errmsg)) {
|
||||
$errors['password'] = $errmsg;
|
||||
}
|
||||
|
||||
// Validate customisable profile fields. (profile_validation expects an object as the parameter with userid set).
|
||||
$dataobject = (object)$data;
|
||||
$dataobject->id = 0;
|
||||
$errors += profile_validation($dataobject, $files);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the missing fields to a user that is going to be created
|
||||
*
|
||||
* @param stdClass $user the new user object
|
||||
* @return stdClass the user filled
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
function signup_setup_new_user($user) {
|
||||
global $CFG;
|
||||
|
||||
$user->confirmed = 0;
|
||||
$user->lang = current_language();
|
||||
$user->firstaccess = 0;
|
||||
$user->timecreated = time();
|
||||
$user->mnethostid = $CFG->mnet_localhost_id;
|
||||
$user->secret = random_string(15);
|
||||
$user->auth = $CFG->registerauth;
|
||||
// Initialize alternate name fields to empty strings.
|
||||
$namefields = array_diff(get_all_user_name_fields(), useredit_get_required_name_fields());
|
||||
foreach ($namefields as $namefield) {
|
||||
$user->$namefield = '';
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user confirmation is enabled on this site and return the auth plugin handling registration if enabled.
|
||||
*
|
||||
* @return stdClass the current auth plugin handling user registration or false if registration not enabled
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
function signup_get_user_confirmation_authplugin() {
|
||||
global $CFG;
|
||||
|
||||
if (empty($CFG->registerauth)) {
|
||||
return false;
|
||||
}
|
||||
$authplugin = get_auth_plugin($CFG->registerauth);
|
||||
|
||||
if (!$authplugin->can_confirm()) {
|
||||
return false;
|
||||
}
|
||||
return $authplugin;
|
||||
}
|
||||
|
@ -34,6 +34,14 @@
|
||||
*/
|
||||
|
||||
$functions = array(
|
||||
'core_auth_confirm_user' => array(
|
||||
'classname' => 'core_auth_external',
|
||||
'methodname' => 'confirm_user',
|
||||
'description' => 'Confirm a user account.',
|
||||
'type' => 'write',
|
||||
'ajax' => true,
|
||||
'loginrequired' => false,
|
||||
),
|
||||
'core_badges_get_user_badges' => array(
|
||||
'classname' => 'core_badges_external',
|
||||
'methodname' => 'get_user_badges',
|
||||
|
@ -96,6 +96,28 @@ function _recaptcha_http_post($host, $path, $data, $port = 80, $https=false) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the recaptcha challenge and image and javascript urls
|
||||
*
|
||||
* @param string $server server url
|
||||
* @param string $pubkey public key
|
||||
* @param string $errorpart error part to append
|
||||
* @return array the challenge hash, image and javascript url
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
function recaptcha_get_challenge_hash_and_urls($server, $pubkey, $errorpart = '') {
|
||||
global $CFG;
|
||||
|
||||
require_once($CFG->libdir . '/filelib.php');
|
||||
$html = download_file_content($server . '/noscript?k=' . $pubkey . $errorpart, null, null, false, 300, 20, true);
|
||||
preg_match('/image\?c\=([A-Za-z0-9\-\_]*)\"/', $html, $matches);
|
||||
$challengehash = $matches[1];
|
||||
$imageurl = $server . '/image?c=' . $challengehash;
|
||||
|
||||
$jsurl = $server . '/challenge?k=' . $pubkey . $errorpart;
|
||||
|
||||
return array($challengehash, $imageurl, $jsurl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -111,7 +133,7 @@ function _recaptcha_http_post($host, $path, $data, $port = 80, $https=false) {
|
||||
* @return string - The HTML to be embedded in the user's form.
|
||||
*/
|
||||
function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) {
|
||||
global $CFG, $PAGE;
|
||||
global $PAGE;
|
||||
|
||||
$recaptchatype = optional_param('recaptcha', 'image', PARAM_TEXT);
|
||||
|
||||
@ -127,14 +149,10 @@ function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) {
|
||||
|
||||
$errorpart = "";
|
||||
if ($error) {
|
||||
$errorpart = "&error=" . $error;
|
||||
$errorpart = "&error=" . $error;
|
||||
}
|
||||
|
||||
require_once $CFG->libdir . '/filelib.php';
|
||||
$html = download_file_content($server . '/noscript?k=' . $pubkey . $errorpart, null, null, false, 300, 20, true);
|
||||
preg_match('/image\?c\=([A-Za-z0-9\-\_]*)\"/', $html, $matches);
|
||||
$challenge_hash = $matches[1];
|
||||
$image_url = $server . '/image?c=' . $challenge_hash;
|
||||
list($challengehash, $imageurl, $jsurl) = recaptcha_get_challenge_hash_and_urls($server, $pubkey, $errorpart);
|
||||
|
||||
$strincorrectpleasetryagain = get_string('incorrectpleasetryagain', 'auth');
|
||||
$strenterthewordsabove = get_string('enterthewordsabove', 'auth');
|
||||
@ -143,10 +161,10 @@ function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) {
|
||||
$strgetanaudiocaptcha = get_string('getanaudiocaptcha', 'auth');
|
||||
$strgetanimagecaptcha = get_string('getanimagecaptcha', 'auth');
|
||||
|
||||
$return = html_writer::script('', $server . '/challenge?k=' . $pubkey . $errorpart);
|
||||
$return = html_writer::script('', $jsurl);
|
||||
$return .= '<noscript>
|
||||
<div id="recaptcha_widget_noscript">
|
||||
<div id="recaptcha_image_noscript"><img src="' . $image_url . '" alt="reCAPTCHA"/></div>';
|
||||
<div id="recaptcha_image_noscript"><img src="' . $imageurl . '" alt="reCAPTCHA"/></div>';
|
||||
|
||||
if ($error == 'incorrect-captcha-sol') {
|
||||
$return .= '<div class="recaptcha_only_if_incorrect_sol" style="color:red">' . $strincorrectpleasetryagain . '</div>';
|
||||
@ -155,13 +173,13 @@ function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false) {
|
||||
if ($recaptchatype == 'image') {
|
||||
$return .= '<span class="recaptcha_only_if_image">' . $strenterthewordsabove . '</span>';
|
||||
} elseif ($recaptchatype == 'audio') {
|
||||
$return .= '<span class="recaptcha_only_if_audio">' . $strenterthenumbersyouhear . '</span>';
|
||||
$return .= '<span class="recaptcha_only_if_audio">' . $strenterthenumbersyouhear . '</span>';
|
||||
}
|
||||
|
||||
|
||||
$return .= '<input type="text" id="recaptcha_response_field_noscript" name="recaptcha_response_field" />';
|
||||
$return .= '<input type="hidden" id="recaptcha_challenge_field_noscript" name="recaptcha_challenge_field" value="' . $challenge_hash . '" />';
|
||||
$return .= '<input type="hidden" id="recaptcha_challenge_field_noscript" name="recaptcha_challenge_field" value="' . $challengehash . '" />';
|
||||
$return .= '<div><a href="signup.php">' . $strgetanothercaptcha . '</a></div>';
|
||||
|
||||
|
||||
// Disabling audio recaptchas for now: not language-independent
|
||||
/*
|
||||
if ($recaptchatype == 'image') {
|
||||
@ -226,7 +244,7 @@ function recaptcha_check_answer ($privkey, $remoteip, $challenge, $response, $ht
|
||||
'challenge' => $challenge,
|
||||
'response' => $response
|
||||
),
|
||||
$https
|
||||
$https
|
||||
);
|
||||
|
||||
$answers = explode ("\n", $response [1]);
|
||||
|
@ -97,6 +97,8 @@ information provided here is intended especially for developers.
|
||||
* Action menus do_not_enhance() is deprecated, use a list of action_icon instead.
|
||||
* The user_not_fully_set_up() function has a new $strict parameter (defaulting to true) in order to decide when
|
||||
custom fields (and other checks) should be evaluated to determine if the user has been completely setup.
|
||||
* profile_field_base class has new methods: get_field_config_for_external() and get_field_properties().
|
||||
This two new methods should be implemented by profile field plugins to make them compatible with Web Services.
|
||||
|
||||
=== 3.1 ===
|
||||
|
||||
|
@ -34,13 +34,8 @@ $s = optional_param('s', '', PARAM_RAW); // Old parameter: username
|
||||
$PAGE->set_url('/login/confirm.php');
|
||||
$PAGE->set_context(context_system::instance());
|
||||
|
||||
if (empty($CFG->registerauth)) {
|
||||
print_error('cannotusepage2');
|
||||
}
|
||||
$authplugin = get_auth_plugin($CFG->registerauth);
|
||||
|
||||
if (!$authplugin->can_confirm()) {
|
||||
print_error('cannotusepage2');
|
||||
if (!$authplugin = signup_get_user_confirmation_authplugin()) {
|
||||
throw new moodle_exception('confirmationnotenabled');
|
||||
}
|
||||
|
||||
if (!empty($data) || (!empty($p) && !empty($s))) {
|
||||
|
@ -70,18 +70,8 @@ if ($mform_signup->is_cancelled()) {
|
||||
redirect(get_login_url());
|
||||
|
||||
} else if ($user = $mform_signup->get_data()) {
|
||||
$user->confirmed = 0;
|
||||
$user->lang = current_language();
|
||||
$user->firstaccess = 0;
|
||||
$user->timecreated = time();
|
||||
$user->mnethostid = $CFG->mnet_localhost_id;
|
||||
$user->secret = random_string(15);
|
||||
$user->auth = $CFG->registerauth;
|
||||
// Initialize alternate name fields to empty strings.
|
||||
$namefields = array_diff(get_all_user_name_fields(), useredit_get_required_name_fields());
|
||||
foreach ($namefields as $namefield) {
|
||||
$user->$namefield = '';
|
||||
}
|
||||
// Add missing required fields.
|
||||
$user = signup_setup_new_user($user);
|
||||
|
||||
$authplugin->user_signup($user, true); // prints notice and link to login/index.php
|
||||
exit; //never reached
|
||||
|
@ -92,7 +92,7 @@ class login_signup_form extends moodleform {
|
||||
|
||||
profile_signup_fields($mform);
|
||||
|
||||
if ($this->signup_captcha_enabled()) {
|
||||
if (signup_captcha_enabled()) {
|
||||
$mform->addElement('recaptcha', 'recaptcha_element', get_string('security_question', 'auth'), array('https' => $CFG->loginhttps));
|
||||
$mform->addHelpButton('recaptcha_element', 'recaptcha', 'auth');
|
||||
$mform->closeHeaderBefore('recaptcha_element');
|
||||
@ -122,57 +122,9 @@ class login_signup_form extends moodleform {
|
||||
}
|
||||
|
||||
function validation($data, $files) {
|
||||
global $CFG, $DB;
|
||||
$errors = parent::validation($data, $files);
|
||||
|
||||
$authplugin = get_auth_plugin($CFG->registerauth);
|
||||
|
||||
if ($DB->record_exists('user', array('username'=>$data['username'], 'mnethostid'=>$CFG->mnet_localhost_id))) {
|
||||
$errors['username'] = get_string('usernameexists');
|
||||
} else {
|
||||
//check allowed characters
|
||||
if ($data['username'] !== core_text::strtolower($data['username'])) {
|
||||
$errors['username'] = get_string('usernamelowercase');
|
||||
} else {
|
||||
if ($data['username'] !== core_user::clean_field($data['username'], 'username')) {
|
||||
$errors['username'] = get_string('invalidusername');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//check if user exists in external db
|
||||
//TODO: maybe we should check all enabled plugins instead
|
||||
if ($authplugin->user_exists($data['username'])) {
|
||||
$errors['username'] = get_string('usernameexists');
|
||||
}
|
||||
|
||||
|
||||
if (! validate_email($data['email'])) {
|
||||
$errors['email'] = get_string('invalidemail');
|
||||
|
||||
} else if ($DB->record_exists('user', array('email'=>$data['email']))) {
|
||||
$errors['email'] = get_string('emailexists').' <a href="forgot_password.php">'.get_string('newpassword').'?</a>';
|
||||
}
|
||||
if (empty($data['email2'])) {
|
||||
$errors['email2'] = get_string('missingemail');
|
||||
|
||||
} else if ($data['email2'] != $data['email']) {
|
||||
$errors['email2'] = get_string('invalidemail');
|
||||
}
|
||||
if (!isset($errors['email'])) {
|
||||
if ($err = email_is_not_allowed($data['email'])) {
|
||||
$errors['email'] = $err;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$errmsg = '';
|
||||
if (!check_password_policy($data['password'], $errmsg)) {
|
||||
$errors['password'] = $errmsg;
|
||||
}
|
||||
|
||||
if ($this->signup_captcha_enabled()) {
|
||||
if (signup_captcha_enabled()) {
|
||||
$recaptcha_element = $this->_form->getElement('recaptcha_element');
|
||||
if (!empty($this->_form->_submitValues['recaptcha_challenge_field'])) {
|
||||
$challenge_field = $this->_form->_submitValues['recaptcha_challenge_field'];
|
||||
@ -184,23 +136,10 @@ class login_signup_form extends moodleform {
|
||||
$errors['recaptcha'] = get_string('missingrecaptchachallengefield');
|
||||
}
|
||||
}
|
||||
// Validate customisable profile fields. (profile_validation expects an object as the parameter with userid set)
|
||||
$dataobject = (object)$data;
|
||||
$dataobject->id = 0;
|
||||
$errors += profile_validation($dataobject, $files);
|
||||
|
||||
$errors += signup_validate_data($data, $files);
|
||||
|
||||
return $errors;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not the captcha element is enabled, and the admin settings fulfil its requirements.
|
||||
* @return bool
|
||||
*/
|
||||
function signup_captcha_enabled() {
|
||||
global $CFG;
|
||||
$authplugin = get_auth_plugin($CFG->registerauth);
|
||||
return !empty($CFG->recaptchapublickey) && !empty($CFG->recaptchaprivatekey) && $authplugin->is_captcha_enabled();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -91,6 +91,16 @@ class profile_field_checkbox extends profile_field_base {
|
||||
return '<input disabled="disabled" type="checkbox" name="'.$this->inputname.'" '.$checked.' />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field type and null properties.
|
||||
* This will be used for validating the data submitted by a user.
|
||||
*
|
||||
* @return array the param type and null property
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public function get_field_properties() {
|
||||
return array(PARAM_BOOL, NULL_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,4 +122,15 @@ class profile_field_datetime extends profile_field_base {
|
||||
public function is_empty() {
|
||||
return empty($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field type and null properties.
|
||||
* This will be used for validating the data submitted by a user.
|
||||
*
|
||||
* @return array the param type and null property
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public function get_field_properties() {
|
||||
return array(PARAM_INT, NULL_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
|
@ -165,6 +165,17 @@ class profile_field_menu extends profile_field_base {
|
||||
}
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field type and null properties.
|
||||
* This will be used for validating the data submitted by a user.
|
||||
*
|
||||
* @return array the param type and null property
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public function get_field_properties() {
|
||||
return array(PARAM_TEXT, NULL_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -68,6 +68,16 @@ class profile_field_text extends profile_field_base {
|
||||
$mform->setType($this->inputname, PARAM_TEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field type and null properties.
|
||||
* This will be used for validating the data submitted by a user.
|
||||
*
|
||||
* @return array the param type and null property
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public function get_field_properties() {
|
||||
return array(PARAM_TEXT, NULL_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,6 +81,16 @@ class profile_field_textarea extends profile_field_base {
|
||||
return format_text($this->data, $this->dataformat, array('overflowdiv' => true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field type and null properties.
|
||||
* This will be used for validating the data submitted by a user.
|
||||
*
|
||||
* @return array the param type and null property
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public function get_field_properties() {
|
||||
return array(PARAM_RAW, NULL_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -387,6 +387,28 @@ class profile_field_base {
|
||||
public function is_signup_field() {
|
||||
return (boolean)$this->field->signup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field settings suitable to be exported via an external function.
|
||||
* By default it return all the field settings.
|
||||
*
|
||||
* @return array all the settings
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public function get_field_config_for_external() {
|
||||
return (array) $this->field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the field type and null properties.
|
||||
* This will be used for validating the data submitted by a user.
|
||||
*
|
||||
* @return array the param type and null property
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
public function get_field_properties() {
|
||||
return array(PARAM_RAW, NULL_NOT_ALLOWED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -528,13 +550,15 @@ function profile_display_fields($userid) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds code snippet to a moodle form object for custom profile fields that
|
||||
* should appear on the signup page
|
||||
* @param moodleform $mform moodle form object
|
||||
* Retrieves a list of profile fields that must be displayed in the sign-up form.
|
||||
*
|
||||
* @return array list of profile fields info
|
||||
* @since Moodle 3.2
|
||||
*/
|
||||
function profile_signup_fields($mform) {
|
||||
function profile_get_signup_fields() {
|
||||
global $CFG, $DB;
|
||||
|
||||
$profilefields = array();
|
||||
// Only retrieve required custom fields (with category information)
|
||||
// results are sort by categories, then by fields.
|
||||
$sql = "SELECT uf.id as fieldid, ic.id as categoryid, ic.name as categoryname, uf.datatype
|
||||
@ -543,17 +567,39 @@ function profile_signup_fields($mform) {
|
||||
ON uf.categoryid = ic.id AND uf.signup = 1 AND uf.visible<>0
|
||||
ORDER BY ic.sortorder ASC, uf.sortorder ASC";
|
||||
|
||||
if ( $fields = $DB->get_records_sql($sql)) {
|
||||
if ($fields = $DB->get_records_sql($sql)) {
|
||||
foreach ($fields as $field) {
|
||||
require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
|
||||
$newfield = 'profile_field_'.$field->datatype;
|
||||
$fieldobject = new $newfield($field->fieldid);
|
||||
|
||||
$profilefields[] = (object) array(
|
||||
'categoryid' => $field->categoryid,
|
||||
'categoryname' => $field->categoryname,
|
||||
'fieldid' => $field->fieldid,
|
||||
'datatype' => $field->datatype,
|
||||
'object' => $fieldobject
|
||||
);
|
||||
}
|
||||
}
|
||||
return $profilefields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds code snippet to a moodle form object for custom profile fields that
|
||||
* should appear on the signup page
|
||||
* @param moodleform $mform moodle form object
|
||||
*/
|
||||
function profile_signup_fields($mform) {
|
||||
|
||||
if ($fields = profile_get_signup_fields()) {
|
||||
foreach ($fields as $field) {
|
||||
// Check if we change the categories.
|
||||
if (!isset($currentcat) || $currentcat != $field->categoryid) {
|
||||
$currentcat = $field->categoryid;
|
||||
$mform->addElement('header', 'category_'.$field->categoryid, format_string($field->categoryname));
|
||||
}
|
||||
require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php');
|
||||
$newfield = 'profile_field_'.$field->datatype;
|
||||
$formfield = new $newfield($field->fieldid);
|
||||
$formfield->edit_field($mform);
|
||||
};
|
||||
$field->object->edit_field($mform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2016100404.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2016100500.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user