MDL-66173 login: Added form injection, validation and post action hooks

This commit is contained in:
[Peter Burnett] 2019-08-02 10:34:19 +10:00 committed by burnetp1
parent c77052fb2b
commit dc25b71d8b
7 changed files with 222 additions and 0 deletions

View File

@ -29,6 +29,7 @@ require_once($CFG->dirroot.'/user/lib.php');
require_once('change_password_form.php');
require_once($CFG->libdir.'/authlib.php');
require_once($CFG->dirroot.'/webservice/lib.php');
require_once('lib.php');
$id = optional_param('id', SITEID, PARAM_INT); // current course
$return = optional_param('return', 0, PARAM_BOOL); // redirect after password change
@ -133,6 +134,9 @@ if ($mform->is_cancelled()) {
$strpasswordchanged = get_string('passwordchanged');
// Plugins can perform post password change actions once data has been validated.
core_login_post_change_password_requests($data);
$fullname = fullname($USER, true);
$PAGE->set_title($strpasswordchanged);

View File

@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->dirroot.'/user/lib.php');
require_once('lib.php');
class login_change_password_form extends moodleform {
@ -75,6 +76,9 @@ class login_change_password_form extends moodleform {
$mform->addElement('hidden', 'id', 0);
$mform->setType('id', PARAM_INT);
// Hook for plugins to extend form definition.
core_login_extend_change_password_form($mform, $USER);
// buttons
if (get_user_preferences('auth_forcepasswordchange')) {
$this->add_action_buttons(false);
@ -89,6 +93,9 @@ class login_change_password_form extends moodleform {
$errors = parent::validation($data, $files);
$reason = null;
// Extend validation for any form extensions from plugins.
$errors = array_merge($errors, core_login_validate_extend_change_password_form($data, $USER));
// ignore submitted username
if (!$user = authenticate_user_login($USER->username, $data['password'], true, $reason, false)) {
$errors['password'] = get_string('invalidlogin');

View File

@ -26,6 +26,7 @@ defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->dirroot.'/user/lib.php');
require_once('lib.php');
/**
* Reset forgotten password form definition.
@ -46,6 +47,9 @@ class login_forgot_password_form extends moodleform {
$mform = $this->_form;
$mform->setDisableShortforms(true);
// Hook for plugins to extend form definition.
core_login_extend_forgot_password_form($mform);
$mform->addElement('header', 'searchbyusername', get_string('searchbyusername'), '');
$purpose = user_edit_map_field_purpose($USER->id, 'username');
@ -74,6 +78,10 @@ class login_forgot_password_form extends moodleform {
function validation($data, $files) {
$errors = parent::validation($data, $files);
// Extend validation for any form extensions from plugins.
$errors = array_merge($errors, core_login_validate_extend_forgot_password_form($data));
$errors += core_login_validate_forgot_password_data($data);
return $errors;

View File

@ -51,6 +51,9 @@ function core_login_process_password_reset_request() {
}
list($status, $notice, $url) = core_login_process_password_reset($username, $email);
// Plugins can perform post forgot password actions once data has been validated.
core_login_post_forgot_password_requests($data);
// Any email has now been sent.
// Next display results to requesting user if settings permit.
echo $OUTPUT->header();
@ -283,6 +286,10 @@ function core_login_process_password_set($token) {
$urltogo = core_login_get_return_url();
unset($SESSION->wantsurl);
// Plugins can perform post set password actions once data has been validated.
core_login_post_set_password_requests($data, $user);
redirect($urltogo, get_string('passwordset'), 1);
}
}
@ -399,3 +406,181 @@ function core_login_pre_signup_requests() {
}
}
}
/**
* Plugins can extend forms.
*/
/** Inject form elements into change_password_form.
* @param mform $mform the form to inject elements into.
* @param stdClass $user the user object to use for context.
*/
function core_login_extend_change_password_form($mform, $user) {
$callbacks = get_plugins_with_function('extend_change_password_form');
foreach ($callbacks as $type => $plugins) {
foreach ($plugins as $plugin => $pluginfunction) {
$pluginfunction($mform, $user);
}
}
}
/** Inject form elements into set_password_form.
* @param mform $mform the form to inject elements into.
* @param stdClass $user the user object to use for context.
*/
function core_login_extend_set_password_form($mform, $user) {
$callbacks = get_plugins_with_function('extend_set_password_form');
foreach ($callbacks as $type => $plugins) {
foreach ($plugins as $plugin => $pluginfunction) {
$pluginfunction($mform, $user);
}
}
}
/** Inject form elements into forgot_password_form.
* @param mform $mform the form to inject elements into.
*/
function core_login_extend_forgot_password_form($mform) {
$callbacks = get_plugins_with_function('extend_forgot_password_form');
foreach ($callbacks as $type => $plugins) {
foreach ($plugins as $plugin => $pluginfunction) {
$pluginfunction($mform);
}
}
}
/** Inject form elements into signup_form.
* @param mform $mform the form to inject elements into.
*/
function core_login_extend_signup_form($mform) {
$callbacks = get_plugins_with_function('extend_signup_form');
foreach ($callbacks as $type => $plugins) {
foreach ($plugins as $plugin => $pluginfunction) {
$pluginfunction($mform);
}
}
}
/**
* Plugins can add additional validation to forms.
*/
/** Inject validation into change_password_form.
* @param array $data the data array from submitted form values.
* @param stdClass $user the user object to use for context.
* @return array $errors the updated array of errors from validation.
*/
function core_login_validate_extend_change_password_form($data, $user) {
$pluginsfunction = get_plugins_with_function('validate_extend_change_password_form');
$errors = array();
foreach ($pluginsfunction as $plugintype => $plugins) {
foreach ($plugins as $pluginfunction) {
$pluginerrors = $pluginfunction($data, $user);
$errors = array_merge($errors, $pluginerrors);
}
}
return $errors;
}
/** Inject validation into set_password_form.
* @param array $data the data array from submitted form values.
* @param stdClass $user the user object to use for context.
* @return array $errors the updated array of errors from validation.
*/
function core_login_validate_extend_set_password_form($data, $user) {
$pluginsfunction = get_plugins_with_function('validate_extend_set_password_form');
$errors = array();
foreach ($pluginsfunction as $plugintype => $plugins) {
foreach ($plugins as $pluginfunction) {
$pluginerrors = $pluginfunction($data, $user);
$errors = array_merge($errors, $pluginerrors);
}
}
return $errors;
}
/** Inject validation into forgot_password_form.
* @param array $data the data array from submitted form values.
* @return array $errors the updated array of errors from validation.
*/
function core_login_validate_extend_forgot_password_form($data) {
$pluginsfunction = get_plugins_with_function('validate_extend_forgot_password_form');
$errors = array();
foreach ($pluginsfunction as $plugintype => $plugins) {
foreach ($plugins as $pluginfunction) {
$pluginerrors = $pluginfunction($data);
$errors = array_merge($errors, $pluginerrors);
}
}
return $errors;
}
/** Inject validation into signup_form.
* @param array $data the data array from submitted form values.
* @return array $errors the updated array of errors from validation.
*/
function core_login_validate_extend_signup_form($data) {
$pluginsfunction = get_plugins_with_function('validate_extend_signup_form');
$errors = array();
foreach ($pluginsfunction as $plugintype => $plugins) {
foreach ($plugins as $pluginfunction) {
$pluginerrors = $pluginfunction($data);
$errors = array_merge($errors, $pluginerrors);
}
}
return $errors;
}
/**
* Plugins can perform post submission actions.
*/
/** Post change_password_form submission actions.
* @param stdClass $data the data object from the submitted form.
*/
function core_login_post_change_password_requests($data) {
$pluginsfunction = get_plugins_with_function('post_change_password_requests');
foreach ($pluginsfunction as $plugintype => $plugins) {
foreach ($plugins as $pluginfunction) {
$pluginfunction($data);
}
}
}
/** Post set_password_form submission actions.
* @param stdClass $data the data object from the submitted form.
* @param stdClass $user the user object for set_password context.
*/
function core_login_post_set_password_requests($data, $user) {
$pluginsfunction = get_plugins_with_function('post_set_password_requests');
foreach ($pluginsfunction as $plugintype => $plugins) {
foreach ($plugins as $pluginfunction) {
$pluginfunction($data, $user);
}
}
}
/** Post forgot_password_form submission actions.
* @param stdClass $data the data object from the submitted form.
*/
function core_login_post_forgot_password_requests($data) {
$pluginsfunction = get_plugins_with_function('post_forgot_password_requests');
foreach ($pluginsfunction as $plugintype => $plugins) {
foreach ($plugins as $pluginfunction) {
$pluginfunction($data);
}
}
}
/** Post signup_form submission actions.
* @param stdClass $data the data object from the submitted form.
*/
function core_login_post_signup_requests($data) {
$pluginsfunction = get_plugins_with_function('post_signup_requests');
foreach ($pluginsfunction as $plugintype => $plugins) {
foreach ($plugins as $pluginfunction) {
$pluginfunction($data);
}
}
}

View File

@ -27,6 +27,7 @@ defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->dirroot.'/user/lib.php');
require_once('lib.php');
/**
* Set forgotten password form definition.
@ -78,6 +79,10 @@ class login_set_password_form extends moodleform {
$mform->addRule('password2', get_string('required'), 'required', null, 'client');
$mform->setType('password2', PARAM_RAW);
// Hook for plugins to extend form definition.
$user = $this->_customdata;
core_login_extend_set_password_form($mform, $user);
$this->add_action_buttons(true);
}
@ -92,6 +97,9 @@ class login_set_password_form extends moodleform {
$errors = parent::validation($data, $files);
// Extend validation for any form extensions from plugins.
$errors = array_merge($errors, core_login_validate_extend_set_password_form($data, $user));
// Ignore submitted username.
if ($data['password'] !== $data['password2']) {
$errors['password'] = get_string('passwordsdiffer');

View File

@ -86,6 +86,9 @@ if ($mform_signup->is_cancelled()) {
// Add missing required fields.
$user = signup_setup_new_user($user);
// Plugins can perform post sign up actions once data has been validated.
core_login_post_signup_requests($user);
$authplugin->user_signup($user, true); // prints notice and link to login/index.php
exit; //never reached
}

View File

@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir.'/formslib.php');
require_once($CFG->dirroot.'/user/profile/lib.php');
require_once($CFG->dirroot . '/user/editlib.php');
require_once('lib.php');
class login_signup_form extends moodleform implements renderable, templatable {
function definition() {
@ -97,6 +98,9 @@ class login_signup_form extends moodleform implements renderable, templatable {
$mform->closeHeaderBefore('recaptcha_element');
}
// Hook for plugins to extend form definition.
core_login_extend_signup_form($mform);
// Add "Agree to sitepolicy" controls. By default it is a link to the policy text and a checkbox but
// it can be implemented differently in custom sitepolicy handlers.
$manager = new \core_privacy\local\sitepolicy\manager();
@ -128,6 +132,9 @@ class login_signup_form extends moodleform implements renderable, templatable {
public function validation($data, $files) {
$errors = parent::validation($data, $files);
// Extend validation for any form extensions from plugins.
$errors = array_merge($errors, core_login_validate_extend_signup_form($data));
if (signup_captcha_enabled()) {
$recaptchaelement = $this->_form->getElement('recaptcha_element');
if (!empty($this->_form->_submitValues['g-recaptcha-response'])) {