Skip to content

Commit

Permalink
MDL-8590 auth cleanup - reset password cleanup+fixes; backported from…
Browse files Browse the repository at this point in the history
… HEAD
  • Loading branch information
skodak committed Feb 22, 2007
1 parent de4add7 commit e8c5ac5
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 196 deletions.
4 changes: 2 additions & 2 deletions auth/db/auth.php
Expand Up @@ -190,8 +190,8 @@ function get_userinfo($username) {
/**
* Change a user's password
*
* @param object $user The user to update
* @param string $newpassword The new password
* @param object $user User table object (with system magic quotes)
* @param string $newpassword Plaintext password (with system magic quotes)
*
* @return bool True on success
*/
Expand Down
4 changes: 2 additions & 2 deletions auth/email/auth.php
Expand Up @@ -64,8 +64,8 @@ function user_login ($username, $password) {
*
* called when the user password is updated.
*
* @param object $user User
* @param string $newpassword Plaintext password
* @param object $user User table object (with system magic quotes)
* @param string $newpassword Plaintext password (with system magic quotes)
* @return boolean result
*
*/
Expand Down
2 changes: 1 addition & 1 deletion auth/manual/auth.php
Expand Up @@ -58,7 +58,7 @@ function user_login ($username, $password) {
* called when the user password is updated.
*
* @param object $user User table object (with system magic quotes)
* @param string $newpassword Plaintext password (with system magic quotes)
* @param string $newpassword Plaintext password (with system magic quotes)
* @return boolean result
*
*/
Expand Down
4 changes: 2 additions & 2 deletions auth/none/auth.php
Expand Up @@ -57,8 +57,8 @@ function user_login ($username, $password) {
*
* called when the user password is updated.
*
* @param object $user User
* @param string $newpassword Plaintext password
* @param object $user User table object (with system magic quotes)
* @param string $newpassword Plaintext password (with system magic quotes)
* @return boolean result
*
*/
Expand Down
2 changes: 2 additions & 0 deletions lang/en_utf8/moodle.php
Expand Up @@ -604,6 +604,7 @@
$string['forcetheme'] = 'Force theme';
$string['forgotaccount'] = 'Lost password?';
$string['forgotten'] = 'Forgotten your username or password?';
$string['forgottenduplicate'] = 'The email address is shared by several accounts, please enter username instead';
$string['forgotteninvalidurl'] = 'Invalid password reset URL';
$string['format'] = 'Format';
$string['formathtml'] = 'HTML format';
Expand Down Expand Up @@ -1462,6 +1463,7 @@
$string['userlist'] = 'User list';
$string['username'] = 'Username';
$string['usernameemailmatch'] = 'The username and email address do not relate to the same user';
$string['usernameoremail'] = 'Enter either username or email address';
$string['usernameexists'] = 'This username already exists, choose another';
$string['usernamelowercase'] = 'Only lowercase letters allowed';
$string['usernamenotfound'] = 'The username was not found in the database';
Expand Down
6 changes: 2 additions & 4 deletions lib/moodlelib.php
Expand Up @@ -3451,17 +3451,15 @@ function reset_password_and_mail($user) {
$site = get_site();
$from = get_admin();

$external = false;

$userauth = get_auth_plugin($user->auth);
if (!$userauth->can_change_password()) {
if (!$userauth->can_reset_password()) {
trigger_error("Attempt to reset user password for user $user->username with Auth $user->auth.");
return false;
}

$newpassword = generate_password();

if (!$userauth->user_update_password($user->username, $newpassword)) {
if (!$userauth->user_update_password(addslashes_recursive($user), addslashes($newpassword))) {
error("Could not set user password!");
}

Expand Down
259 changes: 78 additions & 181 deletions login/forgot_password.php
Expand Up @@ -7,150 +7,23 @@
require_once('../config.php');
require_once('forgot_password_form.php');

$action = optional_param('action', '', PARAM_ALPHA);
$p_secret = optional_param('p', false, PARAM_RAW);
$p_username = optional_param('s', false, PARAM_RAW);

httpsrequired();

$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
$sitecontext = get_context_instance(CONTEXT_SYSTEM);

// setup text strings
$strcancel = get_string('cancel');
$strconfirmednot = get_string('confirmednot');
$stremail = get_string('email');
$stremailnotfound = get_string('emailnotfound');
$strerror = get_string('error');
$strforgotten = get_string('passwordforgotten');
$strforgottenduplicate = get_string('forgottenduplicate', 'moodle', get_admin()); // does not exist in lang file??
$strforgotteninstruct = get_string('passwordforgotteninstructions');
$strinvalidemail = get_string('invalidemail');
$strinvalidurl = get_string('forgotteninvalidurl');
$strlogin = get_string('login');
$strloginalready = get_string('loginalready');
$strok = get_string('ok');
$strpasswordnohelp = get_string('passwordnohelp');
$strsecretalreadyused = get_string('secretalreadyused');
$strsenddetails = get_string('senddetails');
$strusername = get_string('username');
$strusernameemailmatch = get_string('usernameemailmatch');
$strusernamenotfound = get_string('usernamenotfound');

$errors = array();
$page = ''; // page to display

$strforgotten = get_string('passwordforgotten');
$strlogin = get_string('login');

// if you are logged in then you shouldn't be here!
if (isloggedin() && !isguestuser()) {
redirect($CFG->wwwroot.'/index.php', $strloginalready, 5);
if (isloggedin() and !isguestuser()) {
redirect($CFG->wwwroot.'/index.php', get_string('loginalready'), 5);
}

$mform = new login_forgot_password_form();

if ($mform->is_cancelled()) {
redirect($CFG->httpswwwroot.'/login/index.php');
}

if ($action == 'find' and $param = $mform->get_data()) {
///=====================
/// find the user in the database and mail info
///=====================

// first try the username
if (!empty($param->username)) {
if (!$user = get_complete_user_data('username', $param->username)) {
$errors[] = $strusernamenotfound;
}
} else {
$user = false;
}

// now try email
if (!empty($param->email)) {
// validate email address 1st
if (!validate_email($param->email)) {
$errors[] = $strinvalidemail;

} else if (count_records('user', 'email', $param->email) > 1) {
// (if there is more than one instance of the email then we
// cannot complete automated recovery)
$page = 'duplicateemail';
$errors[] = $strforgottenduplicate;

} else if (!$mailuser = get_complete_user_data('email', $param->email)) {
$errors[] = $stremailnotfound;
}

// just in case they did specify both...
// if $user exists then check they actually match (then just use $user)
if (!empty($user) and !empty($mailuser)) {
if ($user->id != $mailuser->id) {
$errors[] = $strusernameemailmatch;
}
$user = $mailuser;
}

// use email user if username not used or located
if (!empty($mailuser) and empty($user)) {
$user = $mailuser;
}
}

// if user located (and no errors) take the appropriate action
if (empty($errors) and !empty($user)) {

$userauth = get_auth_plugin($user->auth);

// check this user isn't 'unconfirmed'
if (empty($user->confirmed)) {
$errors[] = $strconfirmednot;

} else {
if (method_exists($userauth, 'can_reset_password') and $userauth->can_reset_password()) {
// reset internal password and notify user

// set 'secret' string
$user->secret = random_string(15);
if (!set_field('user', 'secret', $user->secret, 'id', $user->id)) {
error('error setting user secret string');
}

// send email (make sure mail block is off)
$user->mailstop = 0;
if (!send_password_change_confirmation_email($user)) {
error('error sending password change confirmation email');
}

// display confirm message
$page = 'emailconfirm';

} else {
// send email (make sure mail block is off)
$user->mailstop = 0;
if (!send_password_change_info($user)) {
error('error sending password change confirmation email');
}

// display confirm message
$page = 'emailconfirm';
}
}
}

if (!empty($CFG->protectusernames)) {
// do not give any hints about usernames or email!
$errors = array();
$page = 'emailmaybeconfirmed';
}

if (empty($param->username) and empty($param->email)) {
// nothing supplied - show error in any case
$errors[] = 'no email or username';
$page = '';
}


} else if ($p_secret !== false) {
if ($p_secret !== false) {
///=====================
/// user clicked on link in email message
///=====================
Expand All @@ -160,14 +33,16 @@
$user = get_complete_user_data('username', $p_username);

if (!empty($user) and $user->secret === '') {
$errors[] = $strsecretalreadyused;
print_header($strforgotten, $strforgotten,
"<a href=\"{$CFG->wwwroot}/login/index.php\">{$strlogin}</a>->{$strforgotten}");
error(get_string('secretalreadyused'));

} else if (!empty($user) and $user->secret == stripslashes($p_secret)) {
// make sure that url relates to a valid user

// check this isn't guest user
// TODO: add change password capability so that we can prevent participants to change password
if (isguestuser($user) or has_capability('moodle/legacy:guest', $sitecontext, $user->id, false)) {
if (has_capability('moodle/legacy:guest', $sitecontext, $user->id, false)) {
error('You cannot reset the guest password');
}

Expand All @@ -184,72 +59,94 @@
}

reset_login_count();
$page = 'emailsent';

$changepasswordurl = "{$CFG->httpswwwroot}/login/change_password.php";
$a = new object();
$a->email = $user->email;
$a->link = $changepasswordurl;
$stremailpasswordsent = get_string('emailpasswordsent', '', $a);

print_header($strforgotten, $strforgotten,
"<a href=\"{$CFG->wwwroot}/login/index.php\">{$strlogin}</a>->{$strforgotten}");
notice(get_string('emailpasswordsent', '', $a), $changepasswordurl);

} else {
$errors[] = $strinvalidurl;
print_header($strforgotten, $strforgotten,
"<a href=\"{$CFG->wwwroot}/login/index.php\">{$strlogin}</a>->{$strforgotten}");
error(get_string('forgotteninvalidurl'));
}

die; //never reached
}

$mform = new login_forgot_password_form();

//******************************
// DISPLAY PART
//******************************
if ($mform->is_cancelled()) {
redirect($CFG->httpswwwroot.'/login/index.php');

print_header($strforgotten, $strforgotten,
"<a href=\"{$CFG->wwwroot}/login/index.php\">{$strlogin}</a>->{$strforgotten}",
'form.email');
} else if ($data = $mform->get_data()) {
/// find the user in the database and mail info

if ($page == 'emailmaybeconfirmed') {
// Print general confirmation message
notice(get_string('emailpasswordconfirmmaybesent'), $CFG->wwwroot.'/index.php');
}
// first try the username
if (!empty($data->username)) {
$user = get_complete_user_data('username', $data->username);
} else {

$user = get_complete_user_data('email', $data->email);
}

if ($user and !empty($user->confirmed)) {

$userauth = get_auth_plugin($user->auth);

/// ---------------------------------------------
/// check $page for appropriate page to display
if ($page == 'emailconfirm') {
// Confirm (internal method) email sent
$protectedemail = preg_replace('/([^@]*)@(.*)/', '******@$2', $user->email); // obfuscate the email address to protect privacy
$stremailpasswordconfirmsent = get_string('emailpasswordconfirmsent', '', $protectedemail);
notice($stremailpasswordconfirmsent, $CFG->wwwroot.'/index.php');

} else if ($page == 'emailsent') {
// mail sent with new password
notice($stremailpasswordsent, $changepasswordurl);

} else if ($page == 'duplicateemail') {
// email address appears more than once
notice($strforgottenduplicate, $CFG->wwwroot.'/index.php');

} else {
// display any errors
if (!empty($errors)) {
print_box_start('generalbox boxwidthnormal boxaligncenter');
$s = $strerror;
$s .= '<ul class="errors">';
foreach ($errors as $error) {
$s .= '<li>'.$error.'</li>';
if (method_exists($userauth, 'can_reset_password') and $userauth->can_reset_password()) {
// reset internal password and notify user

// set 'secret' string
$user->secret = random_string(15);
if (!set_field('user', 'secret', $user->secret, 'id', $user->id)) {
error('error setting user secret string');
}

// send email (make sure mail block is off)
$user->mailstop = 0;
if (!send_password_change_confirmation_email($user)) {
error('error sending password change confirmation email');
}

} else {
// send email (make sure mail block is off)
$user->mailstop = 0;
if (!send_password_change_info($user)) {
error('error sending password change confirmation email');
}
}
$s .= '</ul>';
notify($s, 'notifyproblem');
print_box_end();
}
}

if(!$mform->get_data() or !empty($errors)) {
print_box_start('generalbox boxwidthnormal boxaligncenter');
echo $strforgotteninstruct;
print_box_end();
$mform->display();
print_header($strforgotten, $strforgotten,
"<a href=\"{$CFG->wwwroot}/login/index.php\">{$strlogin}</a>->{$strforgotten}");

if (empty($user->email) or !empty($CFG->protectusernames)) {
// Print general confirmation message
notice(get_string('emailpasswordconfirmmaybesent'), $CFG->wwwroot.'/index.php');

} else {
// Confirm email sent
$protectedemail = preg_replace('/([^@]*)@(.*)/', '******@$2', $user->email); // obfuscate the email address to protect privacy
$stremailpasswordconfirmsent = get_string('emailpasswordconfirmsent', '', $protectedemail);
notice($stremailpasswordconfirmsent, $CFG->wwwroot.'/index.php');
}

die; // never reached
}


/// DISPLAY FORM
print_header($strforgotten, $strforgotten,
"<a href=\"{$CFG->wwwroot}/login/index.php\">{$strlogin}</a>->{$strforgotten}", 'id_email');

print_box(get_string('passwordforgotteninstructions'), 'generalbox boxwidthnormal boxaligncenter');
$mform->display();

print_footer();

?>

0 comments on commit e8c5ac5

Please sign in to comment.