You are here

function password_policy_cron in Password Policy 5

Same name and namespace in other branches
  1. 8.3 password_policy.module \password_policy_cron()
  2. 6 password_policy.module \password_policy_cron()
  3. 7.2 password_policy.module \password_policy_cron()
  4. 7 password_policy.module \password_policy_cron()

Implementation of hook_cron

File

./password_policy.module, line 853

Code

function password_policy_cron() {
  $constraint = password_policy_load_active_policy();
  if ($constraint) {
    $expiration = $constraint
      ->getExpiration();
    $warnings = explode(',', $constraint
      ->getWarning());
    if (!empty($expiration)) {
      $accounts = array();

      // Get all users' last password change time. We don't touch blocked accounts
      $result = db_query("SELECT u.*, u.created created_u, p.created created_p, e.warning warning, e.unblocked unblocked FROM {users} u LEFT JOIN {password_policy_users} p ON u.uid = p.uid LEFT JOIN {password_policy_expiration} e ON u.uid = e.uid WHERE u.uid > 0 AND u.status = 1 ORDER BY p.created ASC");
      while ($row = db_fetch_object($result)) {
        if ($row->uid == 1 && !variable_get('password_policy_admin', false)) {
          continue;
        }
        $accounts[$row->uid] = empty($row->created_p) ? $row->created_u : $row->created_p;
        $warns[$row->uid] = $row->warning;
        $unblocks[$row->uid] = $row->unblocked;
      }
      $expiration_seconds = $expiration * 60 * 60 * 24;
      $policy_enabled = _password_policy_enabled($expiration_seconds);
      rsort($warnings, SORT_NUMERIC);
      $time = time();
      foreach ($accounts as $uid => $last_change) {
        foreach ($warnings as $warning) {
          if (!empty($warning)) {
            $warning_seconds = $warning * 60 * 60 * 24;
            $start_period = max($policy_enabled, $last_change) + $expiration_seconds - $warning_seconds;
            $end_period = $start_period + 60 * 60 * 24;
            if ($warns[$uid] > $start_period && $warns[$uid] < $end_period) {

              // a warning was already mailed out
              continue;
            }
            if ($time > $start_period && $time < $end_period) {

              // we're sending a warning
              global $base_url;
              $from = variable_get('site_mail', ini_get('sendmail_from'));
              $account = user_load(array(
                'uid' => $uid,
              ));
              $variables = array(
                '%username' => $account->name,
                '%site' => variable_get('site_name', 'drupal'),
                '%uri' => $base_url,
                '%uri_brief' => substr($base_url, strlen('http://')),
                '%mailto' => $account->mail,
                '%date' => format_date(time()),
                '%login_uri' => url('user', NULL, NULL, TRUE),
                '%edit_uri' => url('user/' . $account->uid . '/edit', NULL, NULL, TRUE),
                '%days' => $warning,
              );
              $subject = _password_policy_mail_text('warning_subject', $variables);
              $body = _password_policy_mail_text('warning_body', $variables);
              $headers = array(
                'From' => $from,
                'Reply-to' => $from,
                'X-Mailer' => 'Drupal',
                'Return-path' => $from,
                'Errors-to' => $from,
              );
              $mail_success = drupal_mail('password-policy-cron-warning', $account->mail, $subject, $body, $from, $headers);
              if ($mail_success) {
                watchdog('password_policy', t('Password expiration warning mailed to %username at %email.', array(
                  '%username' => $account->name,
                  '%email' => $account->mail,
                )));
              }
              else {
                watchdog('password_policy', t('Error mailing password expiration warning to %username at %email.', array(
                  '%username' => $account->name,
                  '%email' => $account->mail,
                )));
              }
              if (!empty($warns[$uid])) {
                db_query("UPDATE {password_policy_expiration} SET warning = %d WHERE uid = %d", $time, $uid);
              }
              else {
                db_query("INSERT INTO {password_policy_expiration} (uid, warning) VALUES (%d, %d)", $uid, $time);
              }
            }
          }
        }

        // Block expired accounts. Unblocked accounts are not blocked for 24h.
        if ($time > max($policy_enabled, $last_change) + $expiration_seconds && $time > $unblocks[$uid] + 60 * 60 * 24 && variable_get('password_policy_block', 0) == 0) {
          db_query("UPDATE {users} SET status = '0' WHERE uid = '%d'", $uid);
          if (!empty($warns[$uid])) {
            db_query("UPDATE {password_policy_expiration} SET blocked = %d WHERE uid = %d", $time, $uid);
          }
          else {
            db_query("INSERT INTO {password_policy_expiration} (uid, blocked) VALUES (%d, %d)", $uid, $time);
          }
          $account = user_load(array(
            'uid' => $uid,
          ));
          watchdog('password_policy', t('Password for user %name has expired.', array(
            '%name' => $account->name,
          )), WATCHDOG_NOTICE, l(t('edit'), "user/{$account->uid}/edit"));
        }
      }
    }
  }
}