You are here

function security_questions_form_user_login_alter in Security Questions 6

Same name and namespace in other branches
  1. 6.2 security_questions.module \security_questions_form_user_login_alter()
  2. 7.2 security_questions.module \security_questions_form_user_login_alter()
  3. 7 security_questions.module \security_questions_form_user_login_alter()

Implements hook_form_FORM_ID_alter() for user_login().

File

./security_questions.module, line 685
Main module file for security_questions.

Code

function security_questions_form_user_login_alter(&$form, &$form_state) {

  // First, check to see if security_questions_user_login variable is set to TRUE
  $security_questions_user_login_enabled = variable_get('security_questions_user_login', TRUE);
  if ($security_questions_user_login_enabled) {

    // If the form has not yet been submitted, add our validation, and remove the
    // password field and default submit handler.
    $form_id = $form['#id'];

    // We need to unset the default submit handler if protection is after.
    // We will user out own password validation.
    $mode = variable_get('security_questions_protection_mode', 'before');
    if ($mode == 'after') {
      unset($form['#submit']);
    }
    if (empty($form_state['security_questions'])) {

      // If questions are before the password, unset the password field, and
      // default submit handler.
      if ($mode == 'before') {
        $form['#validate'] = array(
          'security_questions_user_login_validate_name',
        );
        unset($form['pass'], $form['#submit']);
      }
      else {
        $form['#validate'] = array(
          'security_questions_user_login_validate_both',
        );
        unset($form['#submit']);
      }
    }
    elseif (user_access('bypass security questions', $form_state['security_questions']['account'])) {

      // We just want to show the normal user login form here, but since we got
      // the username from user_login_block, we need to set it here.
      $form['name']['#value'] = $form_state['security_questions']['account']->name;
    }
    else {

      // Retrieve account from form_state (put there by our validation function).
      $account = $form_state['security_questions']['account'];

      // If we are using cookies, check for it.
      if (variable_get('security_questions_cookie', FALSE) && isset($_COOKIE['security_questions'])) {
        $cookie = $_COOKIE['security_questions'];
        $cookie = explode('-', $cookie);
        $cookie_uid = $cookie[3];

        // If the cookie uid matches the current account return.
        if ($account->uid == $cookie_uid) {
          return;
        }
      }

      // If the cookie wasn't found, lets present them with a checkbox if the
      // admin setting is turned on.
      if (variable_get('security_questions_cookie', FALSE)) {
        $form['security_questions_cookie'] = array(
          '#type' => 'checkbox',
          '#title' => t('Remember this computer?'),
        );
      }

      // Hide username.
      $form['name']['#type'] = 'hidden';
      $form['name']['#value'] = $form_state['values']['name'];

      // Check our protection mode. If questions are after, then we can hide the
      // password field.
      if ($mode == 'after') {
        $form['pass']['#type'] = 'hidden';
        $form['pass']['#value'] = $form_state['values']['pass'];
      }

      // Retrieve account from form_state (put there by our validation function).
      $account = $form_state['security_questions']['account'];

      // Get a random question for this user.
      $question = security_questions_get_random_question($account);

      // Get a count of how many questions the user has yet to answer.
      $required = security_questions_required_for_user($account);

      // If there is no question, hide the security question fields.
      // Can happen if module is implemented after users are already registered.
      // We will account for this after login.
      if ($question) {

        // Store question id for answer lookup during validation.
        $_SESSION['security_question'] = $question->security_question_id;

        // Show answer element.
        $form['security_question'] = array(
          '#type' => 'fieldset',
          '#title' => t('Security Question'),
          '#weight' => -2,
        );
        $form['security_question']['question'] = array(
          '#type' => 'item',
          '#value' => '<div>' . t(check_plain($question->security_question)) . '</div>',
        );
        $form['security_question']['security_answer'] = array(
          '#type' => 'textfield',
          '#title' => t('Answer'),
          '#required' => TRUE,
        );

        // If the user has not answered enough questions, force them to answer
        // the remaining number of questions needed.
        if ($required > 0) {
          $form_id = 'user_login';
          $form_state['build_info'] = array(
            'args' => array(
              $account,
              $required,
              $form_id,
            ),
          );

          // Merge in our answer form.
          $form['security_questions'] = drupal_retrieve_form('security_questions_user_answer_form', $form_state);
          $form['security_questions'] += array(
            '#weight' => -1,
          );
          array_push($form['#submit'], 'security_questions_user_answer_form_submit');
        }

        // If protection is after, then we have already validated user credentials,
        // so we can unset default validations, and add our own.
        if ($mode == 'after') {
          unset($form['#validate']);
        }

        //$form['#validate'][] = 'security_questions_user_answer_form_validate';
        if (is_array($form['#validate'])) {
          array_unshift($form['#validate'], 'security_questions_user_login_validate_answer');
        }
        else {
          $form['#validate'][] = 'security_questions_user_login_validate_answer';
        }
      }
      else {
        $form_state['build_info'] = array(
          'args' => array(
            $account,
            $required,
            $form_id,
          ),
        );

        // Merge in our answer form.
        $form['security_questions'] = drupal_retrieve_form('security_questions_user_answer_form', $form_state);
        $form['security_questions'] += array(
          '#weight' => -1,
        );

        // Add our validation handler.
        $form['#validate'][] = 'security_questions_user_answer_form_validate';

        // We dont call the login answer validation because the user doesnt
        // have any answers in the database yet.
        // $form['#validate'][] = 'security_questions_user_login_validate_answer';
        // Add our submit handler.
        if ($mode == 'after') {
          $form['#submit'] = array(
            'security_questions_user_answer_form_submit',
          );
        }
        else {
          array_push($form['#submit'], 'security_questions_user_answer_form_submit');
        }
      }
    }
  }
}