diff --git a/auth/nologin/auth.php b/auth/nologin/auth.php
index 9a1ec28e591..7b7dd3a0128 100644
--- a/auth/nologin/auth.php
+++ b/auth/nologin/auth.php
@@ -103,6 +103,33 @@ class auth_plugin_nologin extends auth_plugin_base {
function can_be_manually_set() {
return true;
}
+
+ /**
+ * Returns information on how the specified user can change their password.
+ * User accounts with authentication type set to nologin are disabled accounts.
+ * They cannot change their password.
+ *
+ * @param stdClass $user A user object
+ * @return string[] An array of strings with keys subject and message
+ */
+ public function get_password_change_info(stdClass $user) : array {
+ $site = get_site();
+
+ $data = new stdClass();
+ $data->firstname = $user->firstname;
+ $data->lastname = $user->lastname;
+ $data->username = $user->username;
+ $data->sitename = format_string($site->fullname);
+ $data->admin = generate_email_signoff();
+
+ $message = get_string('emailpasswordchangeinfodisabled', '', $data);
+ $subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
+
+ return [
+ 'subject' => $subject,
+ 'message' => $message
+ ];
+ }
}
diff --git a/auth/oauth2/classes/auth.php b/auth/oauth2/classes/auth.php
index 1ecfca81cf7..448c00ea6c7 100644
--- a/auth/oauth2/classes/auth.php
+++ b/auth/oauth2/classes/auth.php
@@ -611,4 +611,30 @@ class auth extends \auth_plugin_base {
$this->update_picture($user);
redirect($redirecturl);
}
+
+ /**
+ * Returns information on how the specified user can change their password.
+ * The password of the oauth2 accounts is not stored in Moodle.
+ *
+ * @param stdClass $user A user object
+ * @return string[] An array of strings with keys subject and message
+ */
+ public function get_password_change_info(stdClass $user) : array {
+ $site = get_site();
+
+ $data = new stdClass();
+ $data->firstname = $user->firstname;
+ $data->lastname = $user->lastname;
+ $data->username = $user->username;
+ $data->sitename = format_string($site->fullname);
+ $data->admin = generate_email_signoff();
+
+ $message = get_string('emailpasswordchangeinfo', 'auth_oauth2', $data);
+ $subject = get_string('emailpasswordchangeinfosubject', 'auth_oauth2', format_string($site->fullname));
+
+ return [
+ 'subject' => $subject,
+ 'message' => $message
+ ];
+ }
}
diff --git a/auth/oauth2/lang/en/auth_oauth2.php b/auth/oauth2/lang/en/auth_oauth2.php
index ed38e2dc744..b6fe4b6431a 100644
--- a/auth/oauth2/lang/en/auth_oauth2.php
+++ b/auth/oauth2/lang/en/auth_oauth2.php
@@ -70,6 +70,15 @@ $string['emailconfirmlinksent'] = '
An existing account was found with this em
An email should have been sent to your address at {$a}.
It contains easy instructions to link your accounts.
If you have any difficulty, contact the site administrator.
';
+$string['emailpasswordchangeinfo'] = 'Hi {$a->firstname},
+
+Someone (probably you) has requested a new password for your account on \'{$a->sitename}\'.
+
+However your password cannot be reset because you are using your account on another site to log in.
+
+Please log in as before, using the link on the login page.
+{$a->admin}';
+$string['emailpasswordchangeinfosubject'] = '{$a}: Change password information';
$string['info'] = 'External account';
$string['issuer'] = 'OAuth 2 Service';
$string['issuernologin'] = 'This issuer can not be used to login';
diff --git a/auth/oauth2/tests/auth_test.php b/auth/oauth2/tests/auth_test.php
new file mode 100644
index 00000000000..ab5b2ff74b5
--- /dev/null
+++ b/auth/oauth2/tests/auth_test.php
@@ -0,0 +1,53 @@
+.
+
+/**
+ * Auth oauth2 auth functions tests.
+ *
+ * @package auth_oauth2
+ * @category test
+ * @copyright 2019 Shamim Rezaie
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+/**
+ * Tests for the \auth_oauth2\auth class.
+ *
+ * @copyright 2019 Shamim Rezaie
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class auth_oauth2_auth_testcase extends advanced_testcase {
+
+ public function test_get_password_change_info() {
+ $this->resetAfterTest();
+
+ $user = $this->getDataGenerator()->create_user(['auth' => 'oauth2']);
+ $auth = get_auth_plugin($user->auth);
+ $info = $auth->get_password_change_info($user);
+
+ $this->assertEquals(
+ ['subject', 'message'],
+ array_keys($info),
+ '', 0.0, 10, true);
+ $this->assertContains(
+ 'your password cannot be reset because you are using your account on another site to log in',
+ $info['message']);
+ }
+}
\ No newline at end of file
diff --git a/auth/upgrade.txt b/auth/upgrade.txt
index 4e0502be17f..917165985d3 100644
--- a/auth/upgrade.txt
+++ b/auth/upgrade.txt
@@ -1,6 +1,11 @@
This files describes API changes in /auth/* - plugins,
information provided here is intended especially for developers.
+=== 3.7 ===
+
+* get_password_change_info() method is added to the base class and returns an array containing the subject and body of the message
+ to the user that contains instructions on how to change their password. Authentication plugins can override this method if needed.
+
=== 3.6 ===
* Login forms generated from Moodle must include a login token to protect automated logins. See \core\session\manager::get_login_token().
diff --git a/lib/authlib.php b/lib/authlib.php
index 33a193f094c..4308a43d00c 100644
--- a/lib/authlib.php
+++ b/lib/authlib.php
@@ -758,6 +758,45 @@ class auth_plugin_base {
}
return $data;
}
+
+ /**
+ * Returns information on how the specified user can change their password.
+ *
+ * @param stdClass $user A user object
+ * @return string[] An array of strings with keys subject and message
+ */
+ public function get_password_change_info(stdClass $user) : array {
+ $site = get_site();
+ $systemcontext = context_system::instance();
+
+ $data = new stdClass();
+ $data->firstname = $user->firstname;
+ $data->lastname = $user->lastname;
+ $data->username = $user->username;
+ $data->sitename = format_string($site->fullname);
+ $data->admin = generate_email_signoff();
+
+ if ($this->can_change_password() and $this->change_password_url()) {
+ // We have some external url for password changing.
+ $data->link = $this->change_password_url();
+ } else {
+ // No way to change password, sorry.
+ $data->link = '';
+ }
+
+ if (!empty($data->link) and has_capability('moodle/user:changeownpassword', $systemcontext, $user->id)) {
+ $subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
+ $message = get_string('emailpasswordchangeinfo', '', $data);
+ } else {
+ $subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
+ $message = get_string('emailpasswordchangeinfofail', '', $data);
+ }
+
+ return [
+ 'subject' => $subject,
+ 'message' => $message
+ ];
+ }
}
/**
diff --git a/lib/moodlelib.php b/lib/moodlelib.php
index f3b227f6b4c..ad2c738b7ac 100644
--- a/lib/moodlelib.php
+++ b/lib/moodlelib.php
@@ -6431,17 +6431,14 @@ function send_password_change_confirmation_email($user, $resetrecord) {
}
/**
- * Sends an email containinginformation on how to change your password.
+ * Sends an email containing information on how to change your password.
*
* @param stdClass $user A {@link $USER} object
* @return bool Returns true if mail was sent OK and false if there was an error.
*/
function send_password_change_info($user) {
- global $CFG;
-
$site = get_site();
$supportuser = core_user::get_support_user();
- $systemcontext = context_system::instance();
$data = new stdClass();
$data->firstname = $user->firstname;
@@ -6450,35 +6447,18 @@ function send_password_change_info($user) {
$data->sitename = format_string($site->fullname);
$data->admin = generate_email_signoff();
- $userauth = get_auth_plugin($user->auth);
-
- if (!is_enabled_auth($user->auth) or $user->auth == 'nologin') {
+ if (!is_enabled_auth($user->auth)) {
$message = get_string('emailpasswordchangeinfodisabled', '', $data);
$subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
// Directly email rather than using the messaging system to ensure its not routed to a popup or jabber.
return email_to_user($user, $supportuser, $subject, $message);
}
- if ($userauth->can_change_password() and $userauth->change_password_url()) {
- // We have some external url for password changing.
- $data->link .= $userauth->change_password_url();
-
- } else {
- // No way to change password, sorry.
- $data->link = '';
- }
-
- if (!empty($data->link) and has_capability('moodle/user:changeownpassword', $systemcontext, $user->id)) {
- $message = get_string('emailpasswordchangeinfo', '', $data);
- $subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
- } else {
- $message = get_string('emailpasswordchangeinfofail', '', $data);
- $subject = get_string('emailpasswordchangeinfosubject', '', format_string($site->fullname));
- }
+ $userauth = get_auth_plugin($user->auth);
+ ['subject' => $subject, 'message' => $message] = $userauth->get_password_change_info($user);
// Directly email rather than using the messaging system to ensure its not routed to a popup or jabber.
return email_to_user($user, $supportuser, $subject, $message);
-
}
/**
diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php
index 199f3f10f36..fc742d5f948 100644
--- a/lib/tests/moodlelib_test.php
+++ b/lib/tests/moodlelib_test.php
@@ -4354,4 +4354,20 @@ class core_moodlelib_testcase extends advanced_testcase {
$this->assertFalse($fetcheduser);
}
}
+
+ /**
+ * Test for send_password_change_().
+ */
+ public function test_send_password_change_info() {
+ $this->resetAfterTest();
+
+ $user = $this->getDataGenerator()->create_user();
+
+ $sink = $this->redirectEmails(); // Make sure we are redirecting emails.
+ send_password_change_info($user);
+ $result = $sink->get_messages();
+ $sink->close();
+
+ $this->assertContains('passwords cannot be reset on this site', $result[0]->body);
+ }
}