You are here

function password_policy_user in Password Policy 6

Same name and namespace in other branches
  1. 5 password_policy.module \password_policy_user()

Implements hook_user().

File

./password_policy.module, line 319
The password policy module allows you to enforce a specific level of password complexity for the user passwords on the system.

Code

function password_policy_user($op, &$edit, &$account, $category = NULL) {
  global $user;
  switch ($op) {
    case 'load':
      $account->force_password_change = _password_policy_is_password_change_forced($account->uid);
      break;
    case 'validate':
      global $user;
      if (isset($account->uid) && $account->force_password_change == 1) {

        // Admins can edit accounts without having to reset passwords.
        if ($edit['pass'] == '' && $user->uid == $account->uid) {
          form_set_error('pass', t('Your password has expired. You must change your password to proceed on the site.'));
        }
      }
      break;
    case 'insert':
      $force = isset($edit['force_password_change']) ? $edit['force_password_change'] : variable_get('password_policy_new_login_change', 0);
      db_query('INSERT INTO {password_policy_force_change} VALUES(%d, %d)', $account->uid, $force);
      if (array_key_exists('pass', $edit)) {

        // New users do not yet have an uid during the validation step, but
        // they do have at this insert step.  Store their first password in the
        // system for use with the history constraint (if used).
        if ($account->uid) {
          _password_policy_store_password($account->uid, $edit['pass']);
        }
      }
      break;
    case 'update':
      if (!empty($account->force_password_change) && array_key_exists('pass', $edit) && $user->uid == $account->uid) {
        db_query('UPDATE {password_policy_force_change} SET force_change = 0 WHERE uid = %d', $account->uid);
      }
      elseif (!empty($edit['force_password_change'])) {
        db_query('UPDATE {password_policy_force_change} SET force_change = 1 WHERE uid = %d', $account->uid);
        if ($user->uid != $account->uid) {
          drupal_set_message(t('@user will be required to change their password the next time they log in.', array(
            '@user' => $account->name,
          )));
        }
        if ($user->uid) {
          watchdog('password policy', '@user flagged to change password on next login by @admin.', array(
            '@user' => $account->name,
            '@admin' => $user->name,
          ), WATCHDOG_NOTICE);
        }
        else {

          // The user may be updated programmatically (e.g., via Drupal cron).
          // In this case, there is no administrator forcing the password
          // change.
          watchdog('password policy', '@user flagged to change password on next login.', array(
            '@user' => $account->name,
          ), WATCHDOG_NOTICE);
        }
      }
      elseif (isset($edit['force_password_change'])) {
        db_query('UPDATE {password_policy_force_change} SET force_change = 0 WHERE uid = %d', $account->uid);
      }
      if (isset($edit['status']) && $edit['status'] != $account->status && $edit['status'] == 1) {

        // Account is being unblocked.
        db_query('UPDATE {password_policy_expiration} SET unblocked = %d WHERE uid = %d', time(), $account->uid);
      }
      break;
    case 'after_update':

      // Store hash of newly set password
      if (array_key_exists('pass', $edit)) {
        _password_policy_store_password($account->uid, $edit['pass']);
      }
      break;
    case 'login':
      $roles = is_array($account->roles) ? array_keys($account->roles) : array();
      $policy = _password_policy_load_active_policy($roles);

      // A value $edit['name'] is NULL for a one time login
      if ($policy && (!empty($account->uid) && $account->uid > 1 || variable_get('password_policy_admin', 0)) && !empty($edit['name'])) {

        // Calculate expiration and warning times.
        $expiration = $policy['expiration'];
        $warning = max(explode(',', $policy['warning']));
        $expiration_seconds = $expiration * 60 * 60 * 24;
        $warning_seconds = $warning * 60 * 60 * 24;

        // The policy was enabled
        $policy_start = $policy['created'];
        if (variable_get('password_policy_begin', 0) == 1) {
          $policy_start -= $expiration_seconds;
        }
        if (!empty($expiration)) {

          // Account expiration is active.
          // Get the last password change time.
          $result = db_query_range("SELECT * FROM {password_policy_history} WHERE uid = %d ORDER BY created DESC", $account->uid, 0, 1);
          if ($row = db_fetch_object($result)) {
            $last_change = $row->created;
          }
          else {

            // User has not changed their password since this module was
            // enabled.
            $last_change = $account->created;
          }
          $time = time();
          if ($time > max($policy_start, $last_change) + $expiration_seconds) {
            if (variable_get('password_policy_block', 0) == 0) {

              // User is blocked immediately and cannot change their password
              // after expiration.
              _password_policy_block_account($account);
            }
            else {

              // Redirect user and let password force change handle.
              db_query('UPDATE {password_policy_force_change} SET force_change=%d WHERE uid=%d', 1, $account->uid);
              _password_policy_set_password_change_forced_message();
              _password_policy_go_to_password_change_page();
            }
          }
          elseif ($time > max($policy_start, $last_change) + $expiration_seconds - $warning_seconds) {

            // The warning is shown on login and the user is transferred to the
            // password change page.
            $days_left = ceil((max($policy_start, $last_change) + $expiration_seconds - $time) / (60 * 60 * 24));
            drupal_set_message(format_plural($days_left, 'Your password will expire in less than one day. Please change it.', 'Your password will expire in less than @count days. Please change it.'));
            $destination = drupal_get_destination();
            unset($_REQUEST['destination']);
            drupal_goto('user/' . $account->uid . '/edit' . (module_exists('password_policy_password_tab') ? '/password' : ''), $destination);
          }
        }
      }
      break;
    case 'delete':
      db_query("DELETE FROM {password_policy_history} WHERE uid = %d", $account->uid);
      db_query("DELETE FROM {password_policy_expiration} WHERE uid = %d", $account->uid);
      db_query("DELETE FROM {password_policy_force_change} WHERE uid = %d", $account->uid);
      break;
    case 'register':
    case 'form':

      // Force Password Change on user account.
      if (($category == 'account' || $op == 'register') && user_access('force password change')) {
        if ($category == 'account') {
          $force_change = db_result(db_query_range('SELECT force_change FROM {password_policy_force_change} WHERE uid=%d', $account->uid, 0, 1));
        }
        else {
          $force_change = variable_get('password_policy_new_login_change', 0);
        }
        $form['password_policy'] = array(
          '#type' => 'fieldset',
          '#title' => t('Password settings'),
        );
        $form['password_policy']['force_password_change'] = array(
          '#type' => 'checkbox',
          '#title' => t('Force password change on next login'),
          '#description' => t('If already logged in, the user will be forced to change their password upon their next page request.'),
          '#default_value' => $force_change,
        );
        return $form;
      }
      break;
  }
}