Login callbacks: Difference between revisions
No edit summary |
David Mudrak (talk | contribs) m (Text replacement - "<code php>" to "<syntaxhighlight lang="php">") |
||
(12 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
There are cases where we want any plugin to do some check or action as part of the require_login check or related things around logging in or passwords but which are not handled by an authentication plugin. | There are cases where we want any plugin to do some check or action as part of the require_login check or related things around logging in or passwords but which are not handled by an authentication plugin. | ||
== after_config == | |||
{{Moodle 3.8}} | |||
Triggered as soon as practical on every moodle bootstrap after config has been loaded. The $USER object is available at this point too. | |||
<syntaxhighlight lang="php"> | |||
function tool_myplugin_after_config() { | |||
// Tweak some config. | |||
} | |||
</syntaxhighlight> | |||
Implemented in https://tracker.moodle.org/browse/MDL-66340 | |||
This callback is very "raw" and so there are a number of edge cases that you should think about and possibly protect against. If this callback throws an exception that you can very easily brick your moodle site | |||
# running while in unit tests | |||
# during install | |||
# during upgrade | |||
# generic exceptions of any type | |||
Also depending on the defines set before config.php is required, you may not have a $USER object, or other apis, eg if ABORT_AFTER_CONFIG or NO_MOODLE_COOKIES is defined. | |||
== after_require_login == | == after_require_login == | ||
Line 12: | Line 35: | ||
* enforcing various types of course visibility dependencies, eg 'before you can do course X you need to complete course Y' | * enforcing various types of course visibility dependencies, eg 'before you can do course X you need to complete course Y' | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_after_require_login() { | function tool_myplugin_after_require_login() { | ||
if (should_divert()) { | if (should_divert()) { | ||
Line 18: | Line 41: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> | ||
Implemented in https://tracker.moodle.org/browse/MDL-60470 | Implemented in https://tracker.moodle.org/browse/MDL-60470 | ||
'''Gotcha''': The intent behind this callback was to have a single callback which fires on every page as soon as you know which user you are dealing with. But there is an edge case which is for pages which do not ever call require_login (or one of the variants like require_admin(), require_course_login()). But in these situations the user is still logged in. If a page like this is the first page they visit after they login then after_require_login will not fire until they try to visit another page which does call require_login. Below is a workaround using the `after_config` callback added in 3.8: | |||
<syntaxhighlight lang="php"> | |||
function tool_myplugin_after_config() { | |||
if (isloggedin() && !isguestuser()) { | |||
tool_myplugin_after_require_login(); | |||
} | |||
} | |||
</syntaxhighlight> | |||
== check_password_policy == | == check_password_policy == | ||
{{Moodle 3.6}} | This callback allows a plugin to add additional password tests. {{Moodle 3.6}} | ||
https://tracker.moodle.org/browse/MDL-61694 | |||
Since 3.8 this callback can also accept a $user object so that various rule can be applied against that user (eg your password cannot contain your name) {{Moodle 3.8}} | |||
<syntaxhighlight lang="php"> | |||
/** | |||
* A check password callback | |||
* | |||
* @param string $password The password to be validated. | |||
* @param stdClass $user A user object to perform validation against if preset. Defaults to null | |||
* @return string Returns a string of any errors presented by the checks, or an empty string for success. | |||
* | |||
*/ | |||
function tool_passwordvalidator_check_password_policy($password, $user = null) { | |||
return ''; | |||
} | |||
</syntaxhighlight> | |||
== print_password_policy == | == print_password_policy == | ||
Line 46: | Line 92: | ||
eg to do actions before sign up such as acceptance of policies, validations, etc | eg to do actions before sign up such as acceptance of policies, validations, etc | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_pre_signup_requests() { | function tool_myplugin_pre_signup_requests() { | ||
// Do some special policy | // Do some special policy | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-61485 | https://tracker.moodle.org/browse/MDL-61485 | ||
Line 61: | Line 107: | ||
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_extend_change_password_form($mform, $user) { | function tool_myplugin_extend_change_password_form($mform, $user) { | ||
// Inject a static element of the user's username | // Inject a static element of the user's username | ||
$mform->addElement('static', 'injectedstatic', $user->username); | $mform->addElement('static', 'injectedstatic', $user->username); | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 77: | Line 123: | ||
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_extend_set_password_form($mform, $user) { | function tool_myplugin_extend_set_password_form($mform, $user) { | ||
// Inject a static element of the user's username | // Inject a static element of the user's username | ||
$mform->addElement('static', 'injectedstatic', $user->username); | $mform->addElement('static', 'injectedstatic', $user->username); | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 93: | Line 139: | ||
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_extend_forgot_password_form($mform) { | function tool_myplugin_extend_forgot_password_form($mform) { | ||
// Inject a static element of the word 'injected' | // Inject a static element of the word 'injected' | ||
$mform->addElement('static', 'injectedstatic', 'injected'); | $mform->addElement('static', 'injectedstatic', 'injected'); | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 109: | Line 155: | ||
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_extend_signup_form($mform) { | function tool_myplugin_extend_signup_form($mform) { | ||
// Inject a static element of the word 'injected' | // Inject a static element of the word 'injected' | ||
$mform->addElement('static', 'injectedstatic', 'injected'); | $mform->addElement('static', 'injectedstatic', 'injected'); | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 125: | Line 171: | ||
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_validate_extend_change_password_form($data, $user) { | function tool_myplugin_validate_extend_change_password_form($data, $user) { | ||
// Validate that an injected elements equals the word 'test' | // Validate that an injected elements equals the word 'test' | ||
Line 134: | Line 180: | ||
return $errors; | return $errors; | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 145: | Line 191: | ||
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_validate_extend_set_password_form($data, $user) { | function tool_myplugin_validate_extend_set_password_form($data, $user) { | ||
// Validate that an injected elements equals the word 'test' | // Validate that an injected elements equals the word 'test' | ||
Line 154: | Line 200: | ||
return $errors; | return $errors; | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 165: | Line 211: | ||
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_validate_extend_forgot_password_form($data) { | function tool_myplugin_validate_extend_forgot_password_form($data) { | ||
// Validate that an injected elements equals the word 'test' | // Validate that an injected elements equals the word 'test' | ||
Line 174: | Line 220: | ||
return $errors; | return $errors; | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 185: | Line 231: | ||
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_validate_extend_signup_form($data) { | function tool_myplugin_validate_extend_signup_form($data) { | ||
// Validate that an injected elements equals the word 'test' | // Validate that an injected elements equals the word 'test' | ||
Line 194: | Line 240: | ||
return $errors; | return $errors; | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 203: | Line 249: | ||
WIP: Fire any additional actions required after a user changes their password. This function is passed the submitted form data. | WIP: Fire any additional actions required after a user changes their password. This function is passed the submitted form data. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_post_change_password_requests($data) { | function tool_myplugin_post_change_password_requests($data) { | ||
// Display a popup message that echoes what a user submitted in an injected element | // Display a popup message that echoes what a user submitted in an injected element | ||
Line 211: | Line 256: | ||
echo "<script type='text/javascript'>alert('$message');</script>"; | echo "<script type='text/javascript'>alert('$message');</script>"; | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 220: | Line 265: | ||
WIP: Fire any additional actions required after a user resets their password. This function is passed the submitted form data. | WIP: Fire any additional actions required after a user resets their password. This function is passed the submitted form data. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_post_set_password_requests($data) { | function tool_myplugin_post_set_password_requests($data) { | ||
// Display a popup message that echoes what a user submitted in an injected element | // Display a popup message that echoes what a user submitted in an injected element | ||
Line 228: | Line 272: | ||
echo "<script type='text/javascript'>alert('$message');</script>"; | echo "<script type='text/javascript'>alert('$message');</script>"; | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 237: | Line 281: | ||
WIP: Fire any additional actions required after a user submits a password reset request. This function is passed the submitted form data. | WIP: Fire any additional actions required after a user submits a password reset request. This function is passed the submitted form data. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_post_forgot_password_requests($data) { | function tool_myplugin_post_forgot_password_requests($data) { | ||
// Display a popup message that echoes what a user submitted in an injected element | // Display a popup message that echoes what a user submitted in an injected element | ||
Line 245: | Line 288: | ||
echo "<script type='text/javascript'>alert('$message');</script>"; | echo "<script type='text/javascript'>alert('$message');</script>"; | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 | ||
Line 254: | Line 297: | ||
WIP: Fire any additional actions required after a user creates an account. This function is passed the submitted form data. | WIP: Fire any additional actions required after a user creates an account. This function is passed the submitted form data. | ||
< | <syntaxhighlight lang="php"> | ||
function tool_myplugin_post_signup_requests($data) { | function tool_myplugin_post_signup_requests($data) { | ||
// Display a popup message that echoes what a user submitted in an injected element | // Display a popup message that echoes what a user submitted in an injected element | ||
Line 262: | Line 304: | ||
echo "<script type='text/javascript'>alert('$message');</script>"; | echo "<script type='text/javascript'>alert('$message');</script>"; | ||
} | } | ||
</ | </syntaxhighlight> | ||
https://tracker.moodle.org/browse/MDL-66173 | https://tracker.moodle.org/browse/MDL-66173 |
Latest revision as of 13:33, 14 July 2021
There are cases where we want any plugin to do some check or action as part of the require_login check or related things around logging in or passwords but which are not handled by an authentication plugin.
after_config
Moodle 3.8
Triggered as soon as practical on every moodle bootstrap after config has been loaded. The $USER object is available at this point too.
function tool_myplugin_after_config() {
// Tweak some config.
}
Implemented in https://tracker.moodle.org/browse/MDL-66340
This callback is very "raw" and so there are a number of edge cases that you should think about and possibly protect against. If this callback throws an exception that you can very easily brick your moodle site
- running while in unit tests
- during install
- during upgrade
- generic exceptions of any type
Also depending on the defines set before config.php is required, you may not have a $USER object, or other apis, eg if ABORT_AFTER_CONFIG or NO_MOODLE_COOKIES is defined.
after_require_login
Moodle 3.7
This callback allow a plugin to add additional behavior after require_login is called. Some use cases:
- replacing the sitepolicy feature with a more robust / advanced version
- augmenting the 'user fully setup' workflow to add more steps but outside their profile editing page
- adding extra layers of checks, eg an ip address check but doing this across whole courses instead of at the sitelevel which is too coarse, or at the activity level which is too fine.
- enforcing various types of course visibility dependencies, eg 'before you can do course X you need to complete course Y'
function tool_myplugin_after_require_login() {
if (should_divert()) {
redirect($somewhere);
}
}
Implemented in https://tracker.moodle.org/browse/MDL-60470
Gotcha: The intent behind this callback was to have a single callback which fires on every page as soon as you know which user you are dealing with. But there is an edge case which is for pages which do not ever call require_login (or one of the variants like require_admin(), require_course_login()). But in these situations the user is still logged in. If a page like this is the first page they visit after they login then after_require_login will not fire until they try to visit another page which does call require_login. Below is a workaround using the `after_config` callback added in 3.8:
function tool_myplugin_after_config() {
if (isloggedin() && !isguestuser()) {
tool_myplugin_after_require_login();
}
}
check_password_policy
This callback allows a plugin to add additional password tests. Moodle 3.6
https://tracker.moodle.org/browse/MDL-61694
Since 3.8 this callback can also accept a $user object so that various rule can be applied against that user (eg your password cannot contain your name) Moodle 3.8
/**
* A check password callback
*
* @param string $password The password to be validated.
* @param stdClass $user A user object to perform validation against if preset. Defaults to null
* @return string Returns a string of any errors presented by the checks, or an empty string for success.
*
*/
function tool_passwordvalidator_check_password_policy($password, $user = null) {
return '';
}
print_password_policy
Moodle 3.8
This callback allows a plugin to explain the additional password added via check_password_policy
https://tracker.moodle.org/browse/MDL-66278
pre_signup_requests
Moodle 3.5
eg to do actions before sign up such as acceptance of policies, validations, etc
function tool_myplugin_pre_signup_requests() {
// Do some special policy
}
https://tracker.moodle.org/browse/MDL-61485
extend_change_password_form
Moodle 3.8
WIP: This callback allows for injection of additional form elements into the change password form, to allow for more complicated behaviour such as 2FA.
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users.
function tool_myplugin_extend_change_password_form($mform, $user) {
// Inject a static element of the user's username
$mform->addElement('static', 'injectedstatic', $user->username);
}
https://tracker.moodle.org/browse/MDL-66173
extend_set_password_form
Moodle 3.8
WIP: This callback allows for injection of additional form elements into the set password form, to allow for more complicated behaviour such as 2FA.
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users.
function tool_myplugin_extend_set_password_form($mform, $user) {
// Inject a static element of the user's username
$mform->addElement('static', 'injectedstatic', $user->username);
}
https://tracker.moodle.org/browse/MDL-66173
extend_forgot_password_form
Moodle 3.8
WIP: This callback allows for injection of additional form elements into the forgot password form, to allow for more complicated behaviour such as 2FA.
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users.
function tool_myplugin_extend_forgot_password_form($mform) {
// Inject a static element of the word 'injected'
$mform->addElement('static', 'injectedstatic', 'injected');
}
https://tracker.moodle.org/browse/MDL-66173
extend_signup_form
Moodle 3.8
WIP: This callback allows for injection of additional form elements into the forgot password form, to allow for more complicated behaviour such as 2FA.
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users.
function tool_myplugin_extend_signup_form($mform) {
// Inject a static element of the word 'injected'
$mform->addElement('static', 'injectedstatic', 'injected');
}
https://tracker.moodle.org/browse/MDL-66173
validate_extend_change_password_form
Moodle 3.8
WIP: This callback allows for additional validation of existing and additional form elements, to allow for more complicated behaviour such as 2FA.
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users.
function tool_myplugin_validate_extend_change_password_form($data, $user) {
// Validate that an injected elements equals the word 'test'
$errors = array();
if ($data['injectedtext'] != 'test') {
$errors['injectedtext'] = 'wrong';
}
return $errors;
}
https://tracker.moodle.org/browse/MDL-66173
validate_extend_set_password_form
Moodle 3.8
WIP: This callback allows for additional validation of existing and additional form elements, to allow for more complicated behaviour such as 2FA.
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users.
function tool_myplugin_validate_extend_set_password_form($data, $user) {
// Validate that an injected elements equals the word 'test'
$errors = array();
if ($data['injectedtext'] != 'test') {
$errors['injectedtext'] = 'wrong';
}
return $errors;
}
https://tracker.moodle.org/browse/MDL-66173
validate_extend_forgot_password_form
Moodle 3.8
WIP: This callback allows for additional validation of existing and additional form elements, to allow for more complicated behaviour such as 2FA.
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users.
function tool_myplugin_validate_extend_forgot_password_form($data) {
// Validate that an injected elements equals the word 'test'
$errors = array();
if ($data['injectedtext'] != 'test') {
$errors['injectedtext'] = 'wrong';
}
return $errors;
}
https://tracker.moodle.org/browse/MDL-66173
validate_extend_signup_form
Moodle 3.8
WIP: This callback allows for additional validation of existing and additional form elements, to allow for more complicated behaviour such as 2FA.
Note: This hook is not supported or compatible with the Webservices API or the Moodle mobile app. It does not damage or interrupt any current functionality of the mobile application, however injected form elements and actions will not be executed for mobile users.
function tool_myplugin_validate_extend_signup_form($data) {
// Validate that an injected elements equals the word 'test'
$errors = array();
if ($data['injectedtext'] != 'test') {
$errors['injectedtext'] = 'wrong';
}
return $errors;
}
https://tracker.moodle.org/browse/MDL-66173
post_change_password_requests
Moodle 3.8
WIP: Fire any additional actions required after a user changes their password. This function is passed the submitted form data.
function tool_myplugin_post_change_password_requests($data) {
// Display a popup message that echoes what a user submitted in an injected element
$message = ('post_change_password_request - Input: '.$data->injectedtext);
echo "<script type='text/javascript'>alert('$message');</script>";
}
https://tracker.moodle.org/browse/MDL-66173
post_set_password_requests
Moodle 3.8
WIP: Fire any additional actions required after a user resets their password. This function is passed the submitted form data.
function tool_myplugin_post_set_password_requests($data) {
// Display a popup message that echoes what a user submitted in an injected element
$message = ('post_set_password_request - Input: '.$data->injectedtext);
echo "<script type='text/javascript'>alert('$message');</script>";
}
https://tracker.moodle.org/browse/MDL-66173
post_forgot_password_requests
Moodle 3.8
WIP: Fire any additional actions required after a user submits a password reset request. This function is passed the submitted form data.
function tool_myplugin_post_forgot_password_requests($data) {
// Display a popup message that echoes what a user submitted in an injected element
$message = ('post_forgot_password_request - Input: '.$data->injectedtext);
echo "<script type='text/javascript'>alert('$message');</script>";
}
https://tracker.moodle.org/browse/MDL-66173
post_signup_requests
Moodle 3.8
WIP: Fire any additional actions required after a user creates an account. This function is passed the submitted form data.
function tool_myplugin_post_signup_requests($data) {
// Display a popup message that echoes what a user submitted in an injected element
$message = ('post_signup_request - Input: '.$data->injectedtext);
echo "<script type='text/javascript'>alert('$message');</script>";
}