<?php

/**
 * @file
 * Adds the password set form as an optional fields on the one click login.
 */

/**
 * Reset password. 
 */
function password_hustle_user_pass_reset($form, &$form_state, $uid, $timestamp, $hashed_pass, $action = NULL) {
  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 && !$uid) {
    // The existing user is already logged in.
    if ($user->uid == $uid) {
      drupal_set_message(t('You are logged in as %user. <a href="@user_edit">Change your password.</a>', array('%user' => $user->name, '@user_edit' => url("user/$user->uid/edit"))));
    }
    // A different user is already logged in on the computer.
    else {
      $reset_link_account = user_load($uid);
      if (!empty($reset_link_account)) {
        drupal_set_message(t('Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user. Please <a href="@logout">logout</a> and try using the link again.',
          array(
            '%other_user' => $user->name,
            '%resetting_user' => $reset_link_account->name,
            '@logout' => url('user/logout'),
          )
        ));
      }
      else {
        // Invalid one-time link specifies an unknown user.
        drupal_set_message(t('The one-time login link you clicked is invalid.'));
      }
    }
    drupal_goto();
  }
  elseif ($user->uid) {
    // && $uid because user came from a link so we log them out
    // The existing user is already logged in.
    module_invoke_all('user_logout', $user);
    // Destroy the current session, and reset $user to the anonymous user.
    session_destroy();
  }
  if (!$user->uid) {
    // Either there was no user or there isn't now
    // Time out, in seconds, until login URL expires. 24 hours = 86400 seconds.
    $timeout = 86400;
    $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) {
        drupal_set_message(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'));
        drupal_goto('user/password');
      }
      elseif ($account->uid && $timestamp >= $account->login && $timestamp <= $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid)) {

        // First stage is a confirmation form, then login.
        //$form['message'] = array(
        //  '#markup' => t('<p>This is a one-time login for %user_name and will expire on %expiration_date.</p><p>Click on this button to log in to the site and change your password.</p>',
        //  array('%user_name' => $account->name, '%expiration_date' => format_date($timestamp + $timeout))));
        $form['actions'] = array('#type' => 'actions');
        $form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Log in'));
        $form['message'] = array('#markup' => "<p></p>");
        $form['pass'] = array(
          '#type' => 'password_confirm',
          '#title' => t('Consider entering a password for easy logins in the future:'),
          '#size' => 25,
        );
        $form['#submit'][] = 'password_hustle_one_click_password_submit';
        return $form;
      }
      else {
        drupal_set_message(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'));
        drupal_goto('user/password');
      }
    }
    else {
      // Deny access, no more clues.
      // Everything will be in the watchdog's URL for the administrator
      // to check.
      drupal_access_denied();
    }
  }
}

/**
 * One click password submit.
 */
function password_hustle_one_click_password_submit($form, &$form_state) {
  global $user;
  $uid = arg(2);
  $timestamp = arg(3);
  $hashed_pass = arg(4);
  $action = NULL;
  
  // 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.
    module_invoke_all('user_logout', $user);
    // Destroy the current session, and reset $user to the anonymous user.
    session_destroy();
  }
  
  // Time out, in seconds, until login URL expires. 24 hours = 86400 seconds.
  $timeout = 86400;
  $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) {
      drupal_set_message(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'));
      drupal_goto('user/password');
    }
    elseif ($account->uid && $timestamp >= $account->login && $timestamp <= $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid)) {
      // First stage is a confirmation form, then login
      watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $account->name, '%timestamp' => $timestamp));
      // Set the new user.
      $userdata = array();
      $userdata['pass'] = $form['pass']['#value']['pass1'];
      $userdata['map'] = TRUE;
      $user = $account;
      user_save($account, $userdata, $category = 'account');
      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 log in.'));
      // user_login_finalize() also updates the login timestamp of the
      // user, which invalidates further use of the one-time login link.
      $form_state['redirect'] = '<front>';
    }
    else {
      drupal_set_message(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'));
      $form_state['redirect'] = 'user/password';
    }
  }
  else {
    // Deny access, no more clues.
    // Everything will be in the watchdog's URL for the administrator to check.
    drupal_access_denied();
  }
}

/**
 * Implements hook_menu_alter().
 */
function password_hustle_menu_alter(&$callbacks) {
  $callbacks['user/reset/%/%/%']['page arguments'] = array(
    'password_hustle_user_pass_reset',
    2,
    3,
    4,
  );
  unset($callbacks['user/reset/%/%/%']['file']);
}
