diff --git modules/user/user.module modules/user/user.module index 8c315c4..dca1baf 100644 --- modules/user/user.module +++ modules/user/user.module @@ -941,6 +941,29 @@ function user_account_form(&$form, &$form_state) { '#size' => 25, '#description' => t('To change the current user password, enter the new password in both fields.'), ); + $pass_reset = isset($_SESSION['pass_reset_'. $account->uid]); + $protected_values = array(); + $protected_names = ''; + // The user may only change their own password without their current + // password and only if they logged in via a one-time login link. + $not_my_account = ($user->uid != $account->uid); + if ($not_my_account || !$pass_reset) { + $protected_values['mail'] = $form['account']['mail']['#title']; + $protected_values['pass'] = t('Password'); + $protected_names = t('%mail or %pass', array('%mail' => $protected_values['mail'], '%pass' => $protected_values['pass'])); + } + $form['account']['current_pass_required_values'] = array( + '#type' => 'value', + '#value' => $protected_values, + ); + $form['account']['current_pass'] = array( + '#type' => 'password', + '#title' => $not_my_account ? t('Your own current password') : t('Current password'), + '#size' => 25, + '#access' => (bool) $protected_values, + '#description' => t('Enter your current password to change the !protected_names.', array('!protected_names' => $protected_names)), + ); + $form['#validate'][] = 'user_validate_current_pass'; } elseif (!variable_get('user_email_verification', TRUE) || $admin) { $form['account']['pass'] = array( @@ -1037,6 +1060,29 @@ function user_account_form(&$form, &$form_state) { } /** + * Form validation handler for the current password on the user_account_form(). + */ +function user_validate_current_pass(&$form, &$form_state) { + global $user; + + $account = $form['#user']; + foreach ($form_state['values']['current_pass_required_values'] as $key => $name) { + // This validation only works for required textfields (like mail) or + // form values like password_confirm that have their own validation. + if ((strlen(trim($form_state['values'][$key])) > 0) && ($form_state['values'][$key] != $account->$key)) { + require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc'); + $current_pass_failed = empty($form_state['values']['current_pass']) || !user_check_password($form_state['values']['current_pass'], $user); + if ($current_pass_failed) { + form_set_error('current_pass', t("Your current password is missing or incorrect; it's required to change the %name.", array('%name' => $name))); + form_set_error($key); + } + // We only need to check the password once. + break; + } + } +} + +/** * Form validation handler for user_account_form(). */ function user_account_form_validate($form, &$form_state) { @@ -3081,7 +3127,6 @@ function user_block_user_action(&$object, $context = array()) { * @ingroup forms * @see user_account_form() * @see user_account_form_validate() - * @see user_account_form_submit() * @see user_register_submit() */ function user_register_form($form, &$form_state) { diff --git modules/user/user.pages.inc modules/user/user.pages.inc index 87ac1a5..9cf0eee 100644 --- modules/user/user.pages.inc +++ modules/user/user.pages.inc @@ -120,6 +120,8 @@ function user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $a // user, which invalidates further use of the one-time login link. user_login_finalize(); drupal_set_message(t('You have just used your one-time login link. It is no longer necessary to use this link to login. Please change your password.')); + // Let user's password be changed without current password check. + $_SESSION['pass_reset_'. $user->uid] = TRUE; drupal_goto('user/' . $user->uid . '/edit'); } else { @@ -215,7 +217,6 @@ function template_preprocess_user_profile_category(&$variables) { * @ingroup forms * @see user_account_form() * @see user_account_form_validate() - * @see user_account_form_submit() * @see user_profile_form_validate() * @see user_profile_form_submit() * @see user_cancel_confirm_form_submit() @@ -279,6 +280,10 @@ function user_profile_form_submit($form, &$form_state) { user_save($account, $edit, $category); $form_state['values']['uid'] = $account->uid; + if ($category == 'account' && !empty($edit['pass'])) { + // Remove the password reset tag since a new password was saved. + unset($_SESSION['pass_reset_'. $account->uid]); + } // Clear the page cache because pages can contain usernames and/or profile information: cache_clear_all();