Commit e2b256dc authored by Dries's avatar Dries

- Patch #18719 by Jose: reworked the 'request new password' functionality.

parent 45c5344f
......@@ -2,6 +2,8 @@ Drupal x.x.x, xxxx-xx-xx (Development version)
------------------------
- added free tagging support (folksonomies).
- added a site-wide contact form.
- reworked the 'request new password' functionality.
- profiles:
* added a block to display author information along with posts.
* added support for private profile fields.
......
......@@ -705,6 +705,7 @@ CREATE TABLE users (
signature varchar(255) NOT NULL default '',
created int(11) NOT NULL default '0',
changed int(11) NOT NULL default '0',
login int(11) NOT NULL default '0',
status tinyint(4) NOT NULL default '0',
timezone varchar(8) default NULL,
language varchar(12) NOT NULL default '',
......
......@@ -702,6 +702,7 @@ CREATE TABLE users (
signature varchar(255) NOT NULL default '',
created integer NOT NULL default '0',
changed integer NOT NULL default '0',
login integer NOT NULL default '0',
status smallint NOT NULL default '0',
timezone varchar(8) default NULL,
language varchar(12) NOT NULL default '',
......
......@@ -109,7 +109,7 @@
"2005-04-10" => "update_130",
"2005-04-11" => "update_131",
"2005-04-14" => "update_132",
"2005-04-20" => "update_133"
"2005-04-24" => "update_133"
);
function update_32() {
......@@ -2407,14 +2407,24 @@ function update_132() {
}
function update_133() {
$ret[] = update_sql("CREATE TABLE contact (
$ret[] = update_sql("CREATE TABLE {contact} (
subject varchar(255) NOT NULL default '',
recipients longtext NOT NULL default '',
reply longtext NOT NULL default ''
)");
if ($GLOBALS['db_type'] == 'mysql') {
$ret[] = update_sql("ALTER TABLE {users} ADD login int(11) NOT NULL default '0'");
}
elseif ($GLOBALS['db_type'] == 'pgsql') {
$ret[] = update_sql("ALTER TABLE {users} ADD login integer");
$ret[] = update_sql("ALTER TABLE {users} ALTER COLUMN login SET NOT NULL");
$ret[] = update_sql("ALTER TABLE {users} ALTER COLUMN login SET DEFAULT '0'");
}
return $ret;
}
function update_sql($sql) {
$edit = $_POST["edit"];
$result = db_query($sql);
......
......@@ -224,7 +224,7 @@ function contact_mail_page() {
if (isset($_POST['edit'])) {
$edit = $_POST['edit'];
}
if ($edit) {
// Validate the fields:
if (!$edit['name']) {
......@@ -236,11 +236,11 @@ function contact_mail_page() {
if (!$edit['message']) {
form_set_error('message', t('You must enter a message.'));
}
if (!form_get_errors()) {
// Prepare the sender:
$from = $edit['mail'];
// Compose the body:
$message[] = t("%name sent a message using the contact form at %form:", array('%name' => $edit['name'], '%form' => url($_GET['q'], NULL, NULL, TRUE)));
$message[] = $edit['message'];
......@@ -282,7 +282,7 @@ function contact_mail_page() {
$edit['name'] = $user->name;
$edit['mail'] = $user->mail;
}
$result = db_query('SELECT subject FROM contact ORDER BY subject');
while ($subject = db_fetch_object($result)) {
$subjects[$subject->subject] = $subject->subject;
......
......@@ -224,7 +224,7 @@ function contact_mail_page() {
if (isset($_POST['edit'])) {
$edit = $_POST['edit'];
}
if ($edit) {
// Validate the fields:
if (!$edit['name']) {
......@@ -236,11 +236,11 @@ function contact_mail_page() {
if (!$edit['message']) {
form_set_error('message', t('You must enter a message.'));
}
if (!form_get_errors()) {
// Prepare the sender:
$from = $edit['mail'];
// Compose the body:
$message[] = t("%name sent a message using the contact form at %form:", array('%name' => $edit['name'], '%form' => url($_GET['q'], NULL, NULL, TRUE)));
$message[] = $edit['message'];
......@@ -282,7 +282,7 @@ function contact_mail_page() {
$edit['name'] = $user->name;
$edit['mail'] = $user->mail;
}
$result = db_query('SELECT subject FROM contact ORDER BY subject');
while ($subject = db_fetch_object($result)) {
$subjects[$subject->subject] = $subject->subject;
......
......@@ -392,7 +392,7 @@ function user_fields() {
}
else {
// Make sure we return the default fields at least
$fields = array('uid', 'name', 'pass', 'mail', 'picture', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'changed', 'status', 'timezone', 'language', 'init', 'data');
$fields = array('uid', 'name', 'pass', 'mail', 'picture', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'changed', 'login', 'status', 'timezone', 'language', 'init', 'data');
}
}
......@@ -644,6 +644,8 @@ function user_menu($may_cache) {
'callback' => 'user_page', 'access' => $user->uid == 0 && variable_get('user_register', 1), 'type' => MENU_LOCAL_TASK);
$items[] = array('path' => 'user/password', 'title' => t('request new password'),
'callback' => 'user_pass', 'access' => $user->uid == 0, 'type' => MENU_LOCAL_TASK);
$items[] = array('path' => 'user/reset', 'title' => t('reset password'),
'callback' => 'user_pass_reset', 'access' => $user->uid == 0, 'type' => MENU_CALLBACK);
$items[] = array('path' => 'user/help', 'title' => t('help'),
'callback' => 'user_help_page', 'type' => MENU_CALLBACK);
......@@ -809,7 +811,7 @@ function user_login($edit = array(), $msg = '') {
watchdog('user', t('Session opened for %name.', array('%name' => theme('placeholder', $user->name))));
// Update the user table timestamp noting user has logged in.
db_query("UPDATE {users} SET changed = '%d' WHERE uid = '%s'", time(), $user->uid);
db_query("UPDATE {users} SET login = '%d' WHERE uid = '%s'", time(), $user->uid);
user_module_invoke('login', $edit, $user);
......@@ -922,31 +924,27 @@ function user_pass() {
}
if ($account) {
$from = variable_get('site_mail', ini_get('sendmail_from'));
$pass = user_password();
// Save new password:
user_save($account, array('pass' => $pass));
// Mail new password:
$variables = array('%username' => $account->name, '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $account->mail, '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE));
// Mail one time login URL and instructions.
$variables = array('%username' => $account->name, '%site' => variable_get('site_name', 'drupal'), '%login_url' => user_pass_reset_url($account), '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $account->mail, '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE));
$subject = _user_mail_text('pass_subject', $variables);
$body = _user_mail_text('pass_body', $variables);
$headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from";
$mail_success = user_mail($account->mail, $subject, $body, $headers);
if ($mail_success) {
watchdog('user', t('Password mailed to %name at %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', $account->mail))));
drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.'));
watchdog('user', t('Password reset instructions mailed to %name at %email.', array('%name' => '<em>'. $account->name .'</em>', '%email' => '<em>'. $account->mail .'</em>')));
drupal_set_message(t('Further instructions have been sent to your e-mail address.'));
}
else {
watchdog('user', t('Error mailing password to %name at %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', $account->mail))), WATCHDOG_ERROR);
watchdog('user', t('Error mailing password reset instructions to %name at %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', $account->mail))), WATCHDOG_ERROR);
drupal_set_message(t('Unable to send mail. Please contact the site admin.'));
}
drupal_goto('user');
}
else {
if ($edit) {
drupal_set_message(t('You must provider either a username or e-mail address.'), 'error');
drupal_set_message(t('You must provide either a username or e-mail address.'), 'error');
}
// Display form:
$output = '<p>'. t('Enter your username <strong><em>or</em></strong> your e-mail address.') .'</p>';
......@@ -957,6 +955,50 @@ function user_pass() {
}
}
/**
* Menu callback; process one time login URL, and redirects to the user page on success.
*/
function user_pass_reset($uid, $timestamp, $hashed_pass) {
global $user;
// Time out, in seconds, until login URL expires. 24 hours = 86400 seconds.
$timeout = 86400;
$current = time();
// Some redundant checks for extra security ?
if ($timestamp < $current && is_numeric($uid) && $account = user_load(array('uid' => $uid, 'status' => 1)) ) {
// No time out for first time login.
if ($account->login && $current - $timestamp > $timeout) {
drupal_set_message(t('You have tried to use a one time login URL which has expired. Please request a new one using the form below.'));
drupal_goto('user/password');
}
if ($account->uid && !$user->uid && !empty($account) && $timestamp > $account->login && $timestamp < $current &&
$hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login)) {
watchdog('user', t('One time login URL used for %name with timestamp %timestamp.', array('%name' => "<em>$account->name</em>", '%timestamp' => $timestamp)));
// Update the user table noting user has logged in.
// And this also makes this hashed password a one-time-only login.
db_query("UPDATE {users} SET login = '%d' WHERE uid = %d", time(), $account->uid);
// Now we can set the new user.
$user = $account;
// And proceed with normal login, going to user page.
user_module_invoke('login', $edit, $user);
drupal_set_message(t("You have used a one-time login, which won't be valid anymore."));
drupal_set_message(t('Please change your password.'));
drupal_goto('user/'. $user->uid .'/edit');
}
}
// Deny access, no more clues.
// Everything will be in the watchdog's URL for the administrator to check.
drupal_access_denied();
}
function user_pass_reset_url($account){
$timestamp = time();
return url("user/reset/$account->uid/$timestamp/".user_pass_rehash($account->pass, $timestamp, $account->login), NULL, NULL, TRUE);
}
function user_pass_rehash($password, $timestamp, $login){
return md5($timestamp . $password . $login);
}
function user_register($edit = array()) {
global $user, $base_url;
......@@ -977,7 +1019,7 @@ function user_register($edit = array()) {
$account = user_save('', array_merge(array('name' => $edit['name'], 'pass' => $pass, 'init' => $edit['mail'], 'mail' => $edit['mail'], 'roles' => array(_user_authenticated_id()), 'status' => (variable_get('user_register', 1) == 1 ? 1 : 0)), $edit));
watchdog('user', t('New user: %name %email.', array('%name' => theme('placeholder', $edit['name']), '%email' => theme('placeholder', '<'. $edit['mail'] .'>'))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
$variables = array('%username' => $edit['name'], '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $edit['mail'], '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE));
$variables = array('%username' => $edit['name'], '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $edit['mail'], '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE), '%login_url' => user_pass_reset_url($account));
// The first user may login immediately, and receives a customized welcome e-mail.
if ($account->uid == 1) {
......@@ -1256,15 +1298,15 @@ function _user_mail_text($messageid, $variables = array()) {
case 'welcome_subject':
return t('Account details for %username at %site', $variables);
case 'welcome_body':
return t("%username,\n\nThank you for registering at %site. You may now log in to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at %edit_uri\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drupal.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team", $variables);
return t("%username,\n\nThank you for registering at %site. You may now log in to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n%login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to %edit_uri so you can change your password.\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drop.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team", $variables);
case 'approval_subject':
return t('Account details for %username at %site (pending admin approval)', $variables);
case 'approval_body':
return t("%username,\n\nThank you for registering at %site. Your application for an account is currently pending approval. Once it has been granted, you may log in to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at %edit_uri\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drupal.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team", $variables);
return t("%username,\n\nThank you for registering at %site. Your application for an account is currently pending approval. Once it has been granted, you may log in to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n%login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you may wish to change your password at %edit_uri\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drop.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team", $variables);
case 'pass_subject':
return t('Replacement login information for %username at %site', $variables);
case 'pass_body':
return t("%username,\n\nHere is your new password for %site. You may now login to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at %edit_uri", $variables);
return t("%username,\n\nA request to reset the password for your account has been made at %site.\n\nYou may now log in to %uri_brief clicking on this link or copying and pasting it in your browser:\n\n%login_url\n\nThis is a one-time login, so it can be used only once. It expires after one day and nothing will happen if it's not used.\n\nAfter logging in, you will be redirected to %edit_uri so you can change your password.", $variables);
}
}
}
......@@ -1276,12 +1318,12 @@ function user_configure_settings() {
$output = form_group(t('User registration settings'), $group);
// User e-mail settings.
$group = form_textfield(t('Subject of welcome e-mail'), 'user_mail_welcome_subject', _user_mail_text('welcome_subject'), 70, 180, t('Customize the subject of your welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri.');
$group .= form_textarea(t('Body of welcome e-mail'), 'user_mail_welcome_body', _user_mail_text('welcome_body'), 70, 10, t('Customize the body of the welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.');
$group .= form_textfield(t('Subject of welcome e-mail (awaiting admin approval)'), 'user_mail_approval_subject', _user_mail_text('approval_subject'), 70, 180, t('Customize the subject of your awaiting approval welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri.');
$group .= form_textarea(t('Body of welcome e-mail (awaiting admin approval)'), 'user_mail_approval_body', _user_mail_text('approval_body'), 70, 10, t('Customize the body of the awaiting approval welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.');
$group .= form_textfield(t('Subject of password recovery e-mail'), 'user_mail_pass_subject', _user_mail_text('pass_subject'), 70, 180, t('Customize the Subject of your forgotten password e-mail.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri.');
$group .= form_textarea(t('Body of password recovery e-mail'), 'user_mail_pass_body', _user_mail_text('pass_body'), 70, 10, t('Customize the body of the forgotten password e-mail.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.');
$group = form_textfield(t('Subject of welcome e-mail'), 'user_mail_welcome_subject', _user_mail_text('welcome_subject'), 70, 180, t('Customize the subject of your welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri, %login_url.');
$group .= form_textarea(t('Body of welcome e-mail'), 'user_mail_welcome_body', _user_mail_text('welcome_body'), 70, 10, t('Customize the body of the welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri, %login_url.');
$group .= form_textfield(t('Subject of welcome e-mail (awaiting admin approval)'), 'user_mail_approval_subject', _user_mail_text('approval_subject'), 70, 180, t('Customize the subject of your awaiting approval welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri, %login_url.');
$group .= form_textarea(t('Body of welcome e-mail (awaiting admin approval)'), 'user_mail_approval_body', _user_mail_text('approval_body'), 70, 10, t('Customize the body of the awaiting approval welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri, %login_url.');
$group .= form_textfield(t('Subject of password recovery e-mail'), 'user_mail_pass_subject', _user_mail_text('pass_subject'), 70, 180, t('Customize the Subject of your forgotten password e-mail.') .' '. t('Available variables are:') .' %username, %site, %login_url, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri.');
$group .= form_textarea(t('Body of password recovery e-mail'), 'user_mail_pass_body', _user_mail_text('pass_body'), 70, 10, t('Customize the body of the forgotten password e-mail.') .' '. t('Available variables are:') .' %username, %site, %login_url, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.');
$output .= form_group(t('User email settings'), $group);
// Picture settings.
......@@ -1626,10 +1668,10 @@ function user_admin_account() {
array('data' => t('Username'), 'field' => 'u.name'),
array('data' => t('Status'), 'field' => 'u.status'),
array('data' => t('Roles')),
array('data' => t('Last access'), 'field' => 'u.changed', 'sort' => 'desc'),
array('data' => t('Last access'), 'field' => 'u.login', 'sort' => 'desc'),
t('Operations')
);
$sql = 'SELECT u.uid, u.name, u.status, u.changed FROM {users} u WHERE uid != 0';
$sql = 'SELECT u.uid, u.name, u.status, u.login, u.changed FROM {users} u WHERE uid != 0';
$sql .= tablesort_sql($header);
$result = pager_query($sql, 50);
......@@ -1644,6 +1686,7 @@ function user_admin_account() {
}
$rows[] = array($account->uid, format_name($account), $status[$account->status], implode(', ', $roles), format_date($account->changed, 'small'), l(t('edit'), "user/$account->uid/edit", array(), $destination));
}
$pager = theme('pager', NULL, 50, 0, tablesort_pager());
......
......@@ -392,7 +392,7 @@ function user_fields() {
}
else {
// Make sure we return the default fields at least
$fields = array('uid', 'name', 'pass', 'mail', 'picture', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'changed', 'status', 'timezone', 'language', 'init', 'data');
$fields = array('uid', 'name', 'pass', 'mail', 'picture', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'changed', 'login', 'status', 'timezone', 'language', 'init', 'data');
}
}
......@@ -644,6 +644,8 @@ function user_menu($may_cache) {
'callback' => 'user_page', 'access' => $user->uid == 0 && variable_get('user_register', 1), 'type' => MENU_LOCAL_TASK);
$items[] = array('path' => 'user/password', 'title' => t('request new password'),
'callback' => 'user_pass', 'access' => $user->uid == 0, 'type' => MENU_LOCAL_TASK);
$items[] = array('path' => 'user/reset', 'title' => t('reset password'),
'callback' => 'user_pass_reset', 'access' => $user->uid == 0, 'type' => MENU_CALLBACK);
$items[] = array('path' => 'user/help', 'title' => t('help'),
'callback' => 'user_help_page', 'type' => MENU_CALLBACK);
......@@ -809,7 +811,7 @@ function user_login($edit = array(), $msg = '') {
watchdog('user', t('Session opened for %name.', array('%name' => theme('placeholder', $user->name))));
// Update the user table timestamp noting user has logged in.
db_query("UPDATE {users} SET changed = '%d' WHERE uid = '%s'", time(), $user->uid);
db_query("UPDATE {users} SET login = '%d' WHERE uid = '%s'", time(), $user->uid);
user_module_invoke('login', $edit, $user);
......@@ -922,31 +924,27 @@ function user_pass() {
}
if ($account) {
$from = variable_get('site_mail', ini_get('sendmail_from'));
$pass = user_password();
// Save new password:
user_save($account, array('pass' => $pass));
// Mail new password:
$variables = array('%username' => $account->name, '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $account->mail, '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE));
// Mail one time login URL and instructions.
$variables = array('%username' => $account->name, '%site' => variable_get('site_name', 'drupal'), '%login_url' => user_pass_reset_url($account), '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $account->mail, '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE));
$subject = _user_mail_text('pass_subject', $variables);
$body = _user_mail_text('pass_body', $variables);
$headers = "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from";
$mail_success = user_mail($account->mail, $subject, $body, $headers);
if ($mail_success) {
watchdog('user', t('Password mailed to %name at %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', $account->mail))));
drupal_set_message(t('Your password and further instructions have been sent to your e-mail address.'));
watchdog('user', t('Password reset instructions mailed to %name at %email.', array('%name' => '<em>'. $account->name .'</em>', '%email' => '<em>'. $account->mail .'</em>')));
drupal_set_message(t('Further instructions have been sent to your e-mail address.'));
}
else {
watchdog('user', t('Error mailing password to %name at %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', $account->mail))), WATCHDOG_ERROR);
watchdog('user', t('Error mailing password reset instructions to %name at %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', $account->mail))), WATCHDOG_ERROR);
drupal_set_message(t('Unable to send mail. Please contact the site admin.'));
}
drupal_goto('user');
}
else {
if ($edit) {
drupal_set_message(t('You must provider either a username or e-mail address.'), 'error');
drupal_set_message(t('You must provide either a username or e-mail address.'), 'error');
}
// Display form:
$output = '<p>'. t('Enter your username <strong><em>or</em></strong> your e-mail address.') .'</p>';
......@@ -957,6 +955,50 @@ function user_pass() {
}
}
/**
* Menu callback; process one time login URL, and redirects to the user page on success.
*/
function user_pass_reset($uid, $timestamp, $hashed_pass) {
global $user;
// Time out, in seconds, until login URL expires. 24 hours = 86400 seconds.
$timeout = 86400;
$current = time();
// Some redundant checks for extra security ?
if ($timestamp < $current && is_numeric($uid) && $account = user_load(array('uid' => $uid, 'status' => 1)) ) {
// No time out for first time login.
if ($account->login && $current - $timestamp > $timeout) {
drupal_set_message(t('You have tried to use a one time login URL which has expired. Please request a new one using the form below.'));
drupal_goto('user/password');
}
if ($account->uid && !$user->uid && !empty($account) && $timestamp > $account->login && $timestamp < $current &&
$hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login)) {
watchdog('user', t('One time login URL used for %name with timestamp %timestamp.', array('%name' => "<em>$account->name</em>", '%timestamp' => $timestamp)));
// Update the user table noting user has logged in.
// And this also makes this hashed password a one-time-only login.
db_query("UPDATE {users} SET login = '%d' WHERE uid = %d", time(), $account->uid);
// Now we can set the new user.
$user = $account;
// And proceed with normal login, going to user page.
user_module_invoke('login', $edit, $user);
drupal_set_message(t("You have used a one-time login, which won't be valid anymore."));
drupal_set_message(t('Please change your password.'));
drupal_goto('user/'. $user->uid .'/edit');
}
}
// Deny access, no more clues.
// Everything will be in the watchdog's URL for the administrator to check.
drupal_access_denied();
}
function user_pass_reset_url($account){
$timestamp = time();
return url("user/reset/$account->uid/$timestamp/".user_pass_rehash($account->pass, $timestamp, $account->login), NULL, NULL, TRUE);
}
function user_pass_rehash($password, $timestamp, $login){
return md5($timestamp . $password . $login);
}
function user_register($edit = array()) {
global $user, $base_url;
......@@ -977,7 +1019,7 @@ function user_register($edit = array()) {
$account = user_save('', array_merge(array('name' => $edit['name'], 'pass' => $pass, 'init' => $edit['mail'], 'mail' => $edit['mail'], 'roles' => array(_user_authenticated_id()), 'status' => (variable_get('user_register', 1) == 1 ? 1 : 0)), $edit));
watchdog('user', t('New user: %name %email.', array('%name' => theme('placeholder', $edit['name']), '%email' => theme('placeholder', '<'. $edit['mail'] .'>'))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
$variables = array('%username' => $edit['name'], '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $edit['mail'], '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE));
$variables = array('%username' => $edit['name'], '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $edit['mail'], '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE), '%login_url' => user_pass_reset_url($account));
// The first user may login immediately, and receives a customized welcome e-mail.
if ($account->uid == 1) {
......@@ -1256,15 +1298,15 @@ function _user_mail_text($messageid, $variables = array()) {
case 'welcome_subject':
return t('Account details for %username at %site', $variables);
case 'welcome_body':
return t("%username,\n\nThank you for registering at %site. You may now log in to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at %edit_uri\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drupal.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team", $variables);
return t("%username,\n\nThank you for registering at %site. You may now log in to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n%login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you will be redirected to %edit_uri so you can change your password.\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drop.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team", $variables);
case 'approval_subject':
return t('Account details for %username at %site (pending admin approval)', $variables);
case 'approval_body':
return t("%username,\n\nThank you for registering at %site. Your application for an account is currently pending approval. Once it has been granted, you may log in to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at %edit_uri\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drupal.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team", $variables);
return t("%username,\n\nThank you for registering at %site. Your application for an account is currently pending approval. Once it has been granted, you may log in to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nYou may also log in by clicking on this link or copying and pasting it in your browser:\n\n%login_url\n\nThis is a one-time login, so it can be used only once.\n\nAfter logging in, you may wish to change your password at %edit_uri\n\nYour new %site membership also enables to you to login to other Drupal powered websites (e.g. http://www.drop.org/) without registering. Just use the following Drupal ID and password:\n\nDrupal ID: %username@%uri_brief\npassword: %password\n\n\n-- %site team", $variables);
case 'pass_subject':
return t('Replacement login information for %username at %site', $variables);
case 'pass_body':
return t("%username,\n\nHere is your new password for %site. You may now login to %login_uri using the following username and password:\n\nusername: %username\npassword: %password\n\nAfter logging in, you may wish to change your password at %edit_uri", $variables);
return t("%username,\n\nA request to reset the password for your account has been made at %site.\n\nYou may now log in to %uri_brief clicking on this link or copying and pasting it in your browser:\n\n%login_url\n\nThis is a one-time login, so it can be used only once. It expires after one day and nothing will happen if it's not used.\n\nAfter logging in, you will be redirected to %edit_uri so you can change your password.", $variables);
}
}
}
......@@ -1276,12 +1318,12 @@ function user_configure_settings() {
$output = form_group(t('User registration settings'), $group);
// User e-mail settings.
$group = form_textfield(t('Subject of welcome e-mail'), 'user_mail_welcome_subject', _user_mail_text('welcome_subject'), 70, 180, t('Customize the subject of your welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri.');
$group .= form_textarea(t('Body of welcome e-mail'), 'user_mail_welcome_body', _user_mail_text('welcome_body'), 70, 10, t('Customize the body of the welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.');
$group .= form_textfield(t('Subject of welcome e-mail (awaiting admin approval)'), 'user_mail_approval_subject', _user_mail_text('approval_subject'), 70, 180, t('Customize the subject of your awaiting approval welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri.');
$group .= form_textarea(t('Body of welcome e-mail (awaiting admin approval)'), 'user_mail_approval_body', _user_mail_text('approval_body'), 70, 10, t('Customize the body of the awaiting approval welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.');
$group .= form_textfield(t('Subject of password recovery e-mail'), 'user_mail_pass_subject', _user_mail_text('pass_subject'), 70, 180, t('Customize the Subject of your forgotten password e-mail.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri.');
$group .= form_textarea(t('Body of password recovery e-mail'), 'user_mail_pass_body', _user_mail_text('pass_body'), 70, 10, t('Customize the body of the forgotten password e-mail.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.');
$group = form_textfield(t('Subject of welcome e-mail'), 'user_mail_welcome_subject', _user_mail_text('welcome_subject'), 70, 180, t('Customize the subject of your welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri, %login_url.');
$group .= form_textarea(t('Body of welcome e-mail'), 'user_mail_welcome_body', _user_mail_text('welcome_body'), 70, 10, t('Customize the body of the welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri, %login_url.');
$group .= form_textfield(t('Subject of welcome e-mail (awaiting admin approval)'), 'user_mail_approval_subject', _user_mail_text('approval_subject'), 70, 180, t('Customize the subject of your awaiting approval welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri, %login_url.');
$group .= form_textarea(t('Body of welcome e-mail (awaiting admin approval)'), 'user_mail_approval_body', _user_mail_text('approval_body'), 70, 10, t('Customize the body of the awaiting approval welcome e-mail, which is sent to new members upon registering.') .' '. t('Available variables are:') .' %username, %site, %password, %uri, %uri_brief, %mailto, %login_uri, %edit_uri, %login_url.');
$group .= form_textfield(t('Subject of password recovery e-mail'), 'user_mail_pass_subject', _user_mail_text('pass_subject'), 70, 180, t('Customize the Subject of your forgotten password e-mail.') .' '. t('Available variables are:') .' %username, %site, %login_url, %uri, %uri_brief, %mailto, %date, %login_uri, %edit_uri.');
$group .= form_textarea(t('Body of password recovery e-mail'), 'user_mail_pass_body', _user_mail_text('pass_body'), 70, 10, t('Customize the body of the forgotten password e-mail.') .' '. t('Available variables are:') .' %username, %site, %login_url, %uri, %uri_brief, %mailto, %login_uri, %edit_uri.');
$output .= form_group(t('User email settings'), $group);
// Picture settings.
......@@ -1626,10 +1668,10 @@ function user_admin_account() {
array('data' => t('Username'), 'field' => 'u.name'),
array('data' => t('Status'), 'field' => 'u.status'),
array('data' => t('Roles')),
array('data' => t('Last access'), 'field' => 'u.changed', 'sort' => 'desc'),
array('data' => t('Last access'), 'field' => 'u.login', 'sort' => 'desc'),
t('Operations')
);
$sql = 'SELECT u.uid, u.name, u.status, u.changed FROM {users} u WHERE uid != 0';
$sql = 'SELECT u.uid, u.name, u.status, u.login, u.changed FROM {users} u WHERE uid != 0';
$sql .= tablesort_sql($header);
$result = pager_query($sql, 50);
......@@ -1644,6 +1686,7 @@ function user_admin_account() {
}
$rows[] = array($account->uid, format_name($account), $status[$account->status], implode(', ', $roles), format_date($account->changed, 'small'), l(t('edit'), "user/$account->uid/edit", array(), $destination));
}
$pager = theme('pager', NULL, 50, 0, tablesort_pager());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment