1 user.pages.inc user_pass_reset($uid, $timestamp, $hashed_pass, $immediate_login = FALSE)

Menu callback; process one time login link and redirects to the user page on success.

Parameters

int $uid: User ID for the user who would like their password reset.

int $timestamp: Timestamp when the one-time password reset link was generated.

string $hashed_pass: Hashed version of the user's password using user_pass_rehash().

bool $immediate_login: Skip the change password form and just immediately log in.

File

core/modules/user/user.pages.inc, line 156
User page callback file for the user module.

Code

function user_pass_reset($uid, $timestamp, $hashed_pass, $immediate_login = FALSE) {
  global $user;

  // When processing the one-time login link, we have to make sure that a user
  // isn't already logged in.
  if ($user->uid) {
    // The existing user is already logged in. Log them out and reload the
    // current page so the password reset process can continue.
    if ($user->uid == $uid) {
      // Preserve the current destination (if any) and ensure the redirect goes
      // back to the current page; any custom destination set in
      // hook_user_logout() and intended for regular logouts would not be
      // appropriate here.
      $destination = array();
      if (isset($_GET['destination'])) {
        $destination = backdrop_get_destination();
      }
      user_logout_current_user();
      unset($_GET['destination']);
      backdrop_goto(current_path(), array('query' => backdrop_get_query_parameters() + $destination));
    }
    // A different user is already logged in on the computer.
    else {
      $reset_link_account = user_load($uid);
      $is_valid = FALSE;
      if (!empty($reset_link_account) && $timestamp >= $reset_link_account->login && $timestamp <= REQUEST_TIME) {
        if ($hashed_pass == user_pass_rehash($reset_link_account->pass, $timestamp, $reset_link_account->login, $reset_link_account->uid, $reset_link_account->mail)) {
          $is_valid = TRUE;
        }
      }
      if ($is_valid) {
        backdrop_set_message(t('You cannot use a password reset link while logged into the site. Please <a href="!logout">logout</a> and try using the link again.', 
        array('!logout' => url('user/logout'))), 'warning');
      }
      else {
        // Invalid one-time link specifies an unknown user.
        backdrop_set_message(t('The one-time login link you clicked is invalid.'), 'error');
      }
      backdrop_goto();
    }
  }
  else {
    // Time out, in seconds, until login URL expires.
    $timeout = config_get('system.core', 'user_password_reset_timeout');
    $current = REQUEST_TIME;
    // Some redundant checks for extra security ?
    $users = user_load_multiple(array($uid), array('status' => '1'));
    if ($timestamp <= $current && $account = reset($users)) {
      // No time out for first time login.
      if ($account->login && $current - $timestamp > $timeout) {
        backdrop_set_message(t('You have tried to use a reset password link that has expired. Please request a new one using the form below.'), 'error');
        backdrop_goto('user/password');
      }
      elseif ($account->uid && $timestamp >= $account->login && $timestamp <= $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid, $account->mail)) {
        if (config_get('user.flood', 'flood_uid_only')) {
          // Clear flood events based on the uid only if configured.
          $identifier = $account->uid;
        }
        else {
          // The default identifier is a combination of uid and IP address.
          $identifier = $account->uid . '-' . ip_address();
        }
        // Only clear the user specific flood events. We cannot clear the more
        // broad IP address flood events because that would open a
        // vulnerability where an attacker with a valid account could use that
        // to brute force other accounts.
        flood_clear_event('failed_login_attempt_user', $identifier);

        if ($immediate_login) {
          $user = $account;
          user_login_finalize();
          // Clear any password reset flood events for this user.
          flood_clear_event('pass_reset_user', $account->uid);
          backdrop_set_message(t('You have used your one-time log-in link and are now logged-in.'));
          watchdog('user', 'User %name used one-time password reset link at time %timestamp.', array('%name' => $account->name, '%timestamp' => format_date(REQUEST_TIME, 'long')));
          backdrop_goto();
        }
        else {
          return backdrop_get_form('user_pass_reset_form', $account);
        }
      }
      else {
        backdrop_set_message(t('You have tried to use a reset password link that has either been used or is no longer valid. Please request a new one using the form below.'), 'error');
        backdrop_goto('user/password');
      }
    }
    else {
      // Deny access, no more clues.
      // Everything will be in the watchdog's URL for the administrator to check.
      backdrop_access_denied();
      backdrop_exit();
    }
  }
}