MDL-7768 forgot_password.php copnverted to use new forms:

* new forms
* minor refactoring and code cleanup
* secret is now cleared to prevent repeated use of change confirmation link, added new error message see MDL-7755 (patch by Andrew Walbran)
This commit is contained in:
skodak 2006-12-02 19:05:24 +00:00
parent 1437f0a5e3
commit 4adc9c4f60
3 changed files with 170 additions and 157 deletions

View File

@ -468,7 +468,7 @@ line at the top of your web browser window.
If you need help, please contact the site administrator,
$a->admin';
$string['emailpasswordconfirmationsubject'] = '$a: change password confirmation';
$string['emailpasswordconfirmationsubject'] = '$a: Change password confirmation';
$string['emailpasswordconfirmmaybesent'] = '<p>If you supplied correct username or address an email should have been sent to you.</p>
<p>It contains easy instructions to confirm and complete this password change.
If you continue to have difficulty, please contact the site administrator.</p>';
@ -1184,6 +1184,7 @@ $string['secondstotime432000'] = '5 days';
$string['secondstotime518400'] = '6 days';
$string['secondstotime604800'] = '1 Week';
$string['secondstotime86400'] = '1 day';
$string['secretalreadyused'] = 'Change password confirmation link was already used, password was not changed.';
$string['secs'] = 'secs';
$string['section'] = 'Section';
$string['sections'] = 'Sections';

View File

@ -1,107 +1,100 @@
<?php
<?php
// $Id$
// forgot password routine.
// forgot password routine.
// find the user and call the appropriate routine for their authentication
// type.
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();
//******************************
// GET PARAMS AND STRINGS
//******************************
// parameters from form
$param = new StdClass;
$param->action = optional_param( 'action','',PARAM_ALPHA );
$param->email = optional_param( 'email','',PARAM_CLEAN );
$param->p = optional_param( 'p','',PARAM_CLEAN );
$param->s = optional_param( 's','',PARAM_CLEAN );
$param->username = optional_param( 'username','',PARAM_CLEAN );
$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
// setup text strings
$txt = new StdClass;
$txt->cancel = get_string('cancel');
$txt->confirmednot = get_string('confirmednot');
$txt->email = get_string('email');
$txt->emailnotfound = get_string('emailnotfound');
$txt->forgotten = get_string('passwordforgotten');
$txt->forgottenduplicate = get_string('forgottenduplicate','moodle',get_admin() );
$txt->forgotteninstructions = get_string('passwordforgotteninstructions');
$txt->invalidemail = get_string('invalidemail');
$txt->login = get_string('login');
$txt->loginalready = get_string('loginalready');
$txt->ok = get_string('ok');
$txt->passwordextlink = get_string('passwordextlink');
$txt->passwordnohelp = get_string('passwordnohelp');
$txt->senddetails = get_string('senddetails');
$txt->username = get_string('username');
$txt->usernameemailmatch = get_string('usernameemailmatch');
$txt->usernamenotfound = get_string('usernamenotfound');
$txt->invalidurl = get_string('forgotteninvalidurl');
$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');
$strpasswordextlink = get_string('passwordextlink');
$strpasswordnohelp = get_string('passwordnohelp');
$strsecretalreadyused = get_string('secretalreadyused');
$strsenddetails = get_string('senddetails');
$strusername = get_string('username');
$strusernameemailmatch = get_string('usernameemailmatch');
$strusernamenotfound = get_string('usernamenotfound');
$sesskey = sesskey();
$errors = array();
$page = ''; // page to display
//******************************
// PROCESS ACTIONS
//******************************
// if you are logged in then you shouldn't be here!
if (isloggedin() && !isguest()) {
redirect( $CFG->wwwroot.'/index.php', $txt->loginalready, 5 );
redirect($CFG->wwwroot.'/index.php', $strloginalready, 5);
}
// changepassword link replaced by individual auth setting
$auth = $CFG->auth; // the 'default' authentication method
if (!empty($CFG->changepassword)) {
if (empty($CFG->{'auth_'.$auth.'_changepasswordurl'})) {
set_config('auth_'.$auth.'_changepasswordurl',$CFG->changepassword );
set_config('auth_'.$auth.'_changepasswordurl', $CFG->changepassword);
}
set_config('changepassword','');
}
// ACTION = FIND
if ($param->action=='find' and confirm_sesskey()) {
// find the user in the database
set_config('changepassword', '');
}
$mform = new forgot_password_form('forgot_password.php');
if ($action == 'find' and $param = $mform->data_submitted()) {
///=====================
/// 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[] = $txt->usernamenotfound;
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[] = $txt->invalidemail;
}
elseif (count_records('user','email',$param->email) > 1) {
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;
// just clear everything - we drop through to message page
unset( $user );
unset( $email );
$errors = array();
}
elseif (!$mailuser = get_complete_user_data('email',$param->email)) {
$errors[] = $txt->emailnotfound;
} 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[] = $txt->usernameemailmatch;
$errors[] = $strusernameemailmatch;
}
$user = $mailuser;
$user = $mailuser;
}
// use email user if username not used or located
@ -109,51 +102,49 @@ if ($param->action=='find' and confirm_sesskey()) {
$user = $mailuser;
}
}
// if user located (and no errors) take the appropriate action
if (!empty($user) and (count($errors)==0)) {
if (empty($errors) and !empty($user)) {
// check this user isn't 'unconfirmed'
if (empty($user->confirmed)) {
$errors[] = $txt->confirmednot;
}
else {
$errors[] = $strconfirmednot;
} else {
// what to do depends on the authentication method
$authmethod = $user->auth;
if (is_internal_auth( $authmethod ) or !empty($CFG->{'auth_'.$authmethod.'_stdchangepassword'})) {
if (is_internal_auth($authmethod) or !empty($CFG->{'auth_'.$authmethod.'_stdchangepassword'})) {
// handle internal authentication
// set 'secret' string
$user->secret = random_string( 15 );
if (!set_field('user','secret',$user->secret,'id',$user->id)) {
error( 'error setting user 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' );
error('error sending password change confirmation email');
}
// display confirm message
$page = 'emailconfirm';
}
else {
} else {
// handle some 'external' authentication
// if help text defined then we are going to display another page
$txt->extmessage = '';
$strextmessage = '';
$continue = false;
if (!empty( $CFG->{'auth_'.$authmethod.'_changepasswordhelp'} )) {
$txt->extmessage = $CFG->{'auth_'.$authmethod.'_changepasswordhelp'}.'<br /><br />';
if (!empty($CFG->{'auth_'.$authmethod.'_changepasswordhelp'})) {
$strextmessage = $CFG->{'auth_'.$authmethod.'_changepasswordhelp'}.'<br /><br />';
}
// if url defined then add that to the message (with a standard message)
if (!empty( $CFG->{'auth_'.$authmethod.'_changepasswordurl'} )) {
$txt->extmessage .= $txt->passwordextlink . '<br /><br />';
if (!empty($CFG->{'auth_'.$authmethod.'_changepasswordurl'})) {
$strextmessage .= $strpasswordextlink . '<br /><br />';
$link = $CFG->{'auth_'.$authmethod.'_changepasswordurl'};
$txt->extmessage .= "<a href=\"$link\">$link</a>";
$strextmessage .= "<a href=\"$link\">$link</a>";
}
// if nothing to display, just do message that we can't help
if (empty($txt->extmessage)) {
$txt->extmessage = $txt->passwordextlink;
if (empty($strextmessage)) {
$strextmessage = $strpasswordextlink;
$continue = true;
}
$page = 'external';
@ -161,46 +152,61 @@ if ($param->action=='find' and confirm_sesskey()) {
}
}
// nothing supplied - error
if (empty($param->username) and empty($param->email)) {
$errors[] = 'no email or username';
}
if ($page != 'external' and !empty($CFG->protectusernames)) {
// do not give any hints about usernames or email!
$errors = array();
$page = 'emailmaybeconfirmed';
}
}
// ACTION = AUTHENTICATE
if (!empty($param->p) and !empty($param->s)) {
// nothing supplied - show error in any case
if (empty($param->username) and empty($param->email)) {
$errors[] = 'no email or username';
$page = '';
}
} else if ($p_secret !== false) {
///=====================
/// user clicked on link in email message
///=====================
update_login_count();
$user = get_complete_user_data('username',$param->s);
// make sure that url relates to a valid user
if (!empty($user) and $user->secret == $param->p) {
$user = get_complete_user_data('username', $p_username);
if (!empty($user) and $user->secret === '') {
$errors[] = $strsecretalreadyused;
} 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
if (isguest( $user->id )) {
// TODO: add change password capability so that we can prevent participants to change password
if ($user->username == 'guest' or has_capability('moodle/legacy:guest', $sitecontext, $user->id, false)) {
error('You cannot change the guest password');
}
// override email stop and mail new password
$user->emailstop = 0;
if (!reset_password_and_mail($user)) {
error( 'Error resetting password and mailing you' );
error('Error resetting password and mailing you');
}
// Clear secret so that it can not be used again
$user->secret = '';
if (!set_field('user', 'secret', $user->secret, 'id', $user->id)) {
error('Error resetting user secret string');
}
reset_login_count();
$page = 'emailsent';
$changepasswordurl = "{$CFG->httpswwwroot}/login/change_password.php?action=forgot";
$changepasswordurl = "{$CFG->httpswwwroot}/login/change_password.php";
$a = new object();
$a->email = $user->email;
$a->link = $changepasswordurl;
$txt->emailpasswordsent = get_string( 'emailpasswordsent', '', $a );
$stremailpasswordsent = get_string('emailpasswordsent', '', $a);
} else {
$errors[] = $txt->invalidurl;
$errors[] = $strinvalidurl;
}
}
@ -209,90 +215,66 @@ if (!empty($param->p) and !empty($param->s)) {
//******************************
// DISPLAY PART
//******************************
print_header( $txt->forgotten, $txt->forgotten,
"<a href=\"{$CFG->wwwroot}/login/index.php\">{$txt->login}</a>->{$txt->forgotten}",
'form.email' );
if ($page=='emailmaybeconfirmed') {
print_header($strforgotten, $strforgotten,
"<a href=\"{$CFG->wwwroot}/login/index.php\">{$strlogin}</a>->{$strforgotten}",
'form.email');
if ($page == 'emailmaybeconfirmed') {
// Print general confirmation message
notice(get_string('emailpasswordconfirmmaybesent'),$CFG->wwwroot.'/index.php');
notice(get_string('emailpasswordconfirmmaybesent'), $CFG->wwwroot.'/index.php');
}
// check $page for appropriate page to display
if ($page=='emailconfirm') {
/// ---------------------------------------------
/// 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
$txt->emailpasswordconfirmsent = get_string( 'emailpasswordconfirmsent','',$protectedemail );
notice( $txt->emailpasswordconfirmsent,$CFG->wwwroot.'/index.php');
}
$stremailpasswordconfirmsent = get_string('emailpasswordconfirmsent', '', $protectedemail);
notice($stremailpasswordconfirmsent, $CFG->wwwroot.'/index.php');
elseif ($page=='external') {
} else if ($page == 'external') {
// display change password help text
print_simple_box( $txt->extmessage, 'center', '50%','','20','noticebox' );
print_simple_box($strextmessage, 'center', '50%', '', '20', 'noticebox');
// only print continue button if it makes sense
if ($continue) {
print_continue($CFG->wwwroot.'/index.php');
}
}
elseif ($page=='emailsent') {
} else if ($page == 'emailsent') {
// mail sent with new password
notice( $txt->emailpasswordsent, $changepasswordurl );
}
notice($stremailpasswordsent, $changepasswordurl);
elseif ($page=='duplicateemail') {
} else if ($page == 'duplicateemail') {
// email address appears more than once
notice( $txt->forgottenduplicate, $CFG->wwwroot.'/index.php');
}
notice($strforgottenduplicate, $CFG->wwwroot.'/index.php');
else {
} else {
echo '<br />';
print_simple_box_start('center','50%','','20');
print_simple_box_start('center', '50%', '', '20');
// display any errors
if (count($errors)) {
echo "<ul class=\"errors\">\n";
if (!empty($errors)) {
$s = $strerror;
$s .= '<ul class="errors">';
foreach ($errors as $error) {
echo " <li>$error</li>\n";
$s .= '<li>'.$error.'</li>';
}
echo "</ul>\n";
$s .= '</ul>';
notify($s, 'notifyproblem');
}
?>
<p><?php echo $txt->forgotteninstructions; ?></p>
<form action="forgot_password.php" method="post">
<input type="hidden" name="sesskey" value="<?php echo $sesskey; ?>" />
<input type="hidden" name="action" value="find" />
<table id="forgottenpassword" cellpadding="2">
<tr>
<td><label for="username"><?php echo $txt->username; ?></label></td>
<td><input type="text" name="username" id="username" size="25" /></td>
</tr>
<tr>
<td><label for="email"><?php echo $txt->email; ?></label></td>
<td><input type="text" name="email" id="email" size="25" /></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input type="submit" value="<?php echo $txt->ok; ?>" />
<input type="button" value="<?php echo $txt->cancel; ?>"
onclick="javascript: history.go(-1)" /></td>
</tr>
</table>
</form>
<?php
}
echo $strforgotteninstruct;
print_simple_box_end();
$mform->display();
print_footer();
?>

View File

@ -0,0 +1,30 @@
<?php //$Id$
require_once $CFG->libdir.'/formslib.php';
class forgot_password_form extends moodleform {
function definition() {
$mform =& $this->_form;
$renderer =& $mform->defaultRenderer();
$mform->addElement('header', '', get_string('passwordforgotten'), '');
$mform->addElement('text', 'username', get_string('username'));
$mform->setType('username', PARAM_RAW);
$mform->addElement('text', 'email', get_string('email'));
$mform->setType('email', PARAM_RAW);
// hidden params
$mform->addElement('hidden', 'action', 'find');
$mform->setType('action', PARAM_ALPHA);
// buttons
$mform->addelement('submit', 'submitbutton', get_string('ok'));
$renderer->addStopFieldsetElements('submitbutton');
}
}
?>