You are here

force_password_change.module in Force Password Change 6.3

File

force_password_change.module
View source
<?php

/**
 * Implementation of hook_perm()
 */
function force_password_change_perm() {
  return array(
    'Administer force password change',
  );
}

/**
 * Implementation of hook_menu()
 */
function force_password_change_menu() {
  $menu['admin/user/force_password_change'] = array(
    'title' => 'Force password change',
    'description' => 'Allows users to change various password settings and/or force users in specified roles to change their password',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'force_password_change_settings',
    ),
    'access arguments' => array(
      'Administer force password change',
    ),
    'file' => 'force_password_change_pages.inc',
  );
  $menu['force_password_change/list/%'] = array(
    'title' => 'dummy title. Does not need translation',
    'description' => 'Password stats list for a various role',
    'page callback' => 'force_password_change_list',
    'page arguments' => array(
      2,
    ),
    'access arguments' => array(
      'Administer force password change',
    ),
    'file' => 'force_password_change_pages.inc',
    'type' => MENU_CALLBACK,
  );
  return $menu;
}

/**
 * Implementation of hook_init()
 */
function force_password_change_init() {
  global $user;
  $change_password_url = preg_replace('/!uid/', $user->uid, variable_get('change_password_url', 'user/!uid/edit'));
  if ($user->uid && $_GET['q'] != $change_password_url && $_GET['q'] != drupal_get_path_alias('logout')) {
    $redirect = FALSE;
    if (variable_get('force_password_change_login_or_init', 0)) {
      $pending_users = variable_get('force_password_change_pending_login_users', array());
      if (isset($pending_users[$user->uid])) {
        $type = $pending_users[$user->uid]['type'];
        $destination = '';
        $redirect = TRUE;
      }
    }
    else {
      $pending_change = force_password_change_check();
      if (strlen($pending_change)) {
        $type = $pending_change;
        $destination = 'destination=' . $_GET['q'];
        $redirect = TRUE;
      }
    }
    if ($redirect) {
      if ($type == 1) {
        drupal_set_message(t('An administrator has required that you change your password. Please change your password to proceed.'), 'error', FALSE);
      }
      else {
        drupal_set_message(t('This site requires that you change your password every !time_period. Please change your password to proceed.', array(
          '!time_period' => $type,
        )));
      }
      drupal_goto($change_password_url, $destination);
    }
  }
}
function force_password_change_check() {
  global $user;
  $change_password_url = preg_replace('/!uid/', $user->uid, variable_get('change_password_url', 'user/!uid/edit'));
  if ($user->force_password_change) {
    return '1';
  }
  elseif (variable_get('expire_password', TRUE)) {
    $expiry_data = db_result(db_query_range('SELECT fpce.expiry ' . 'FROM {force_password_change_expiry} AS fpce ' . 'LEFT JOIN {users_roles} AS ur ' . 'ON ur.rid = fpce.rid ' . 'WHERE ur.uid = %d OR fpce.rid = 2 ' . 'ORDER BY fpce.weight ', $user->uid, 0, 1));
    if ($expiry_data) {
      $pass_change_data = db_fetch_array(db_query('SELECT fpcu.last_password_change, u.created ' . 'FROM {force_password_change_users} AS fpcu ' . 'JOIN {users} AS u ' . 'ON u.uid = fpcu.uid ' . 'WHERE u.uid = %d ', $user->uid));
      if ($pass_change_data['last_password_change'] != '' && time() - $expiry_data > $pass_change_data['last_password_change'] || $pass_change_data['last_password_change'] == '' && time() - $expiry_data > $pass_change_data['created']) {
        $expires = $expiry_data;
        $year = 60 * 60 * 24 * 365;
        if ($expires % $year === 0) {
          $time_period = $expires / $year;
          $time_period = $time_period > 1 ? $time_period . ' ' . t('years') : t('year');
        }
        else {
          $week = 60 * 60 * 24 * 7;
          if ($expires % $week === 0) {
            $time_period = $expires / $week;
            $time_period = $time_period > 1 ? $time_period . ' ' . t('weeks') : t('week');
          }
          else {
            $day = 60 * 60 * 24;
            if ($expires % $day === 0) {
              $time_period = $expires / $day;
              $time_period = $time_period > 1 ? $time_period . ' ' . t('days') : t('day');
            }
            else {
              $hour = 60 * 60;
              if ($expires % $hour === 0) {
                $time_period = $expires / $hour;
                $time_period = $time_period > 1 ? $time_period . ' ' . t('hours') : t('hour');
              }
            }
          }
        }
        db_query('UPDATE {users} SET force_password_change = 1 WHERE uid = %d', $user->uid);
        return $time_period;
      }
    }
  }
  return FALSE;
}

/**
 * Implementation of hook_user()
 */
function force_password_change_user($op, &$edit, &$account, $category = NULL) {
  global $user;
  switch ($op) {
    case 'login':
      if (variable_get('force_password_change_login_or_init', 0)) {
        $pending_change = force_password_change_check();
        if (strlen($pending_change)) {
          $pending_users = variable_get('force_password_change_pending_login_users', array());
          $pending_users[$account->uid] = array(
            'destination' => $_GET['q'],
            'type' => $pending_change,
          );
          variable_set('force_password_change_pending_login_users', $pending_users);
        }
      }
      break;
    case 'validate':
      if ($account->force_password_change && $account->uid == $user->uid) {
        if ($edit['pass'] == '') {
          form_set_error('password', t('You must choose a new password'));
        }
      }
      if (md5($edit['pass']) == $account->pass) {
        form_set_error('pass', t('You cannot use your current password. Please choose a different password.'));
      }
      break;
    case 'register':
      $form = array();
      if (!variable_get('first_time_login_password_change', FALSE)) {
        $form['force_password_change'] = array(
          '#type' => 'checkbox',
          '#title' => t('Force password change on first-time login'),
          '#description' => t('If this box is checked, the user will be forced to change their password on their first login.'),
        );
      }
      return $form;
      break;
    case 'update':
      if (trim($edit['pass']) != '' && $edit['pass'] != $account->pass) {
        db_query('UPDATE {force_password_change_users} SET last_password_change = %d WHERE uid = %d', time(), $account->uid);
      }
      if ($account->force_password_change && $user->uid == $account->uid && isset($edit['pending_force_password_change'])) {
        db_query('UPDATE {users} SET force_password_change = 0 WHERE uid = %d', $account->uid);
        $forced_uids = variable_get('force_password_change_first_time_uids', array());
        if (count($forced_uids)) {
          unset($forced_uids[$account->uid]);
          variable_set('force_password_change_first_time_uids', $forced_uids);
        }
        $pending_users = variable_get('force_password_change_pending_login_users', array());
        if (isset($pending_users[$account->uid])) {
          $destination = $pending_users[$account->uid]['destination'];
          unset($pending_users[$account->uid]);
          variable_set('force_password_change_pending_login_users', $pending_users);
          $_REQUEST['destination'] = $destination;
        }
      }
      if ($edit['force_password_change']) {
        db_query('UPDATE {users} SET force_password_change = 1 WHERE uid = %d', $account->uid);
        db_query('UPDATE {force_password_change_users} SET last_force = %d WHERE uid = %d', time(), $account->uid);
        unset($edit['force_password_change']);
      }
      break;
    case 'insert':
      db_query('INSERT INTO {force_password_change_users} (uid) VALUES (%d)', $account->uid);
      if (variable_get('first_time_login_password_change', 0)) {
        db_query('UPDATE {users} SET force_password_change = 1 WHERE uid = %d', $account->uid);
      }
      elseif ($edit['force_password_change']) {
        db_query('UPDATE {users} SET force_password_change = 1 WHERE uid = %d', $account->uid);
        $forced_uids = variable_get('force_password_change_first_time_uids', array());
        $forced_uids[$account->uid] = $account->uid;
        variable_set('force_password_change_first_time_uids', $forced_uids);
      }
      unset($edit['force_password_change']);
      break;
    case 'delete':
      db_query('DELETE FROM {force_password_change_users} WHERE uid = %d', $account->uid);
      break;
  }
}

/**
 * Implementation of hook_form_alter()
 */
function force_password_change_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_admin_new_role') {
    $form['#submit'][] = 'force_password_change_add_role';
    $form['#theme'][] = 'force_password_change_new_role_form';
  }
  elseif ($form_id == 'user_admin_role') {
    $form['force_password_change'] = array(
      '#type' => 'checkbox',
      '#title' => t('Force users in this role to change their password'),
      '#description' => t('Users who are not signed in will be required to change their password immediately upon sign in. Users who are currently signed in will be required to change their password upon their next page click, but after changing their password will be redirected back to the page they were attempting to access.') . '<br />' . t('Note: When you return to this page, this box will be unchecked. This is because this setting is a trigger, not a persistant state.'),
      '#weight' => -1,
    );
    $form['name']['#weight'] = -2;
    $form['#submit'][] = 'force_password_change_administer_role';
  }
  elseif ($form_id == 'user_profile_form') {
    global $user;
    if (user_access('Administer force password change', $user)) {
      $form['account']['name']['#weight'] = -2;
      $form['account']['mail']['#weight'] = -1;
      $form['account']['password']['#weight'] = -1;
      $form['account']['password']['pass'] = $form['account']['pass'];
      unset($form['account']['pass']);
      if ($user->uid != $form['_account']['#value']->uid) {
        $form['account']['password']['force_password_change'] = array(
          '#type' => 'checkbox',
          '#title' => t('Force this user to change their password'),
          '#description' => t('If this box is checked, the user will be forced to change their password. If the user is signed in, they will be forced to change their password on their next page load. If they are not signed in, they will be forced to change their password the next time they log in.') . '<br />' . t('Note: This box will be unchecked each time the page is loaded, as it is a trigger, not a persistent state.'),
        );
      }
      $force_password_data = db_fetch_array(db_query('SELECT last_password_change, last_force FROM {force_password_change_users} WHERE uid = %d', $form['_account']['#value']->uid));
      $password_stats = '<p><strong>' . t('Password Stats:') . '</strong></p>';
      $password_stats .= '<ul>';
      $password_stats .= '<li>' . t('User has a pending forced password change:') . ' ';
      $password_stats .= $form['_account']['#value']->force_password_change ? t('Yes') : t('No') . '</li>';
      $password_stats .= '<li>' . t("User was last forced to change their password on:") . ' ';
      if ($force_password_data['last_force'] != '') {
        $last_force = format_date($force_password_data['last_force'], 'small');
      }
      elseif (variable_get('first_time_login_password_change', FALSE) && $form['_account']['#value']->created > variable_get('force_password_change_installation_date', 0)) {
        $last_force = t('Their first login');
      }
      else {
        $forced_uids = variable_get('force_password_change_first_time_uids', array());
        if (count($forced_uids) && isset($forced_uids[$form['_account']['#value']->uid])) {
          $last_force = t('Their first login');
        }
        elseif ($force_password_data['last_password_change'] != '') {
          $last_force = t('Their first login');
        }
        else {
          $last_force = t('Never');
        }
      }
      $password_stats .= $last_force . '</li>';
      $password_stats .= '<li>' . t("User's password was last changed on:") . ' ';
      $password_stats .= $force_password_data['last_password_change'] != '' ? format_date($force_password_data['last_password_change'], 'small') : t('Never');
      $password_stats .= '</li>';
      $password_stats .= '</ul>';
      $form['account']['password']['password_stats'] = array(
        '#value' => $password_stats,
      );
    }
    $form['pending_force_password_change'] = array(
      '#type' => 'value',
      '#value' => $form['_account']['#value']->force_password_change,
    );
  }
  if ($form_id == 'user_register') {
    if ($form['account']) {
      $use_form =& $form['account'];
    }
    else {
      $use_form =& $form;
    }
    $use_form['name']['#weight'] = -2;
    $use_form['mail']['#weight'] = -1;
    $use_form['password']['#weight'] = -1;
    $use_form['password']['pass'] = $form['account']['pass'];
    $use_form['password']['force_password_change'] = $form['force_password_change'];
    unset($use_form['pass']);
    unset($form['force_password_change']);
  }
}

/**
 * Implementation of hook_theme()
 */
function force_password_change_theme() {
  return array(
    'force_password_change_new_role_form' => array(
      'arguments' => array(
        'form' => NULL,
      ),
      'file' => 'force_password_change_pages.inc',
    ),
    'force_password_change_settings' => array(
      'arguments' => array(
        'form' => NULL,
      ),
      'file' => 'force_password_change_pages.inc',
    ),
    'force_password_change_expiry' => array(
      'arguments' => array(
        'form' => NULL,
      ),
      'file' => 'force_password_change_pages.inc',
    ),
  );
}

/**
 * This function is called after a new role has been added to the system.
 * It creates a new row in the {force_password_change_roles} table for the role that has been created
 */
function force_password_change_add_role($form, &$form_state) {
  $rid = db_result(db_query('SELECT rid FROM {role} WHERE name = "%s"', $form_state['values']['name']));
  db_query('INSERT INTO {force_password_change_roles} (rid) VALUES (%d)', $rid);
}

/**
 * This function is called on the role edit page, and serves one of two functions:
 * 1) It deletes the relevant row from the {force_password_changes_roles} table for the role that has been deleted
 * Or
 * 2) Forces the users in that role to chage their password if the applicable checkbox is checked.
 */
function force_password_change_administer_role($form, &$form_state) {
  if ($form_state['values']['op'] == $form_state['values']['delete']) {
    db_query('DELETE FROM {force_password_change_roles} WHERE rid = %d', $form_state['values']['rid']);
  }
  elseif ($form_state['values']['op'] == $form_state['values']['submit'] && $form_state['values']['force_password_change']) {
    $uids = array();
    $db_uids = db_query('SELECT uid ' . 'FROM {users_roles} ' . 'WHERE rid = %d', $form_state['values']['rid']);
    while ($uid = db_fetch_array($db_uids)) {
      $uids[] = $uid['uid'];
    }
    $uid_list = implode(', ', $uids);
    if (strlen($uid_list)) {
      db_query('UPDATE {users} ' . 'SET force_password_change = 1 ' . 'WHERE uid IN (%s)', $uid_list);
      db_query('UPDATE {force_password_change_users} ' . 'SET last_force = %d ' . 'WHERE uid IN (%s)', time(), $uid_list);
    }
    db_query('UPDATE {force_password_change_roles} ' . 'SET last_force = %d ' . 'WHERE rid = %d ', time(), $form_state['values']['rid']);
    drupal_set_message(t('Users in this role will be required to immediately change their password'));
  }
}

Functions

Namesort descending Description
force_password_change_add_role This function is called after a new role has been added to the system. It creates a new row in the {force_password_change_roles} table for the role that has been created
force_password_change_administer_role This function is called on the role edit page, and serves one of two functions: 1) It deletes the relevant row from the {force_password_changes_roles} table for the role that has been deleted Or 2) Forces the users in that role to chage their password…
force_password_change_check
force_password_change_form_alter Implementation of hook_form_alter()
force_password_change_init Implementation of hook_init()
force_password_change_menu Implementation of hook_menu()
force_password_change_perm Implementation of hook_perm()
force_password_change_theme Implementation of hook_theme()
force_password_change_user Implementation of hook_user()