function password_policy_cron in Password Policy 7
Same name and namespace in other branches
- 8.3 password_policy.module \password_policy_cron()
- 5 password_policy.module \password_policy_cron()
- 6 password_policy.module \password_policy_cron()
- 7.2 password_policy.module \password_policy_cron()
Implements hook_cron().
File
- ./
password_policy.module, line 537 - Allows enforcing restrictions on user passwords by defining policies.
Code
function password_policy_cron() {
// Short circuit if no policies are active that use expiration.
$expiration_policies = db_select('password_policy', 'p', array(
'target' => 'slave',
))
->condition('enabled', 1)
->condition('expiration', 0, '>')
->countQuery()
->execute()
->fetchField();
if ($expiration_policies == 0) {
return;
}
$accounts = array();
$warns = array();
$unblocks = array();
$pids = array();
// Get all users' last password change time. Don't touch blocked accounts.
$query = db_select('users', 'u', array(
'target' => 'slave',
));
$query
->leftJoin('password_policy_history', 'p', 'u.uid = p.uid');
$query
->leftJoin('password_policy_expiration', 'e', 'u.uid = e.uid');
$result = $query
->fields('u', array(
'uid',
'name',
'created',
))
->fields('p', array(
'created',
))
->fields('e', array(
'pid',
'unblocked',
'warning',
))
->condition('u.uid', 0, '>')
->condition('u.status', 1)
->orderBy('p.created')
->orderBy('e.warning')
->execute();
foreach ($result as $row) {
if ($row->uid == 1 && !variable_get('password_policy_admin', 1)) {
continue;
}
// Use account creation timestamp if there is no entry in password history
// table.
$accounts[$row->uid] = empty($row->p_created) ? $row->created : $row->p_created;
// Last time a warning was mailed out (if was). We need it because we send
// warnings only once a day, not on all cron runs.
$warns[$row->uid] = $row->warning;
// Last time user was unblocked (if was). We don't block this account again
// for some period of time.
$unblocks[$row->uid] = $row->unblocked;
// Unique password policy expirations ID.
$pids[$row->uid] = $row->pid;
// Usernames.
$names[$row->uid] = $row->name;
}
foreach ($accounts as $uid => $last_change) {
$roles = array(
DRUPAL_AUTHENTICATED_RID,
);
$result = db_select('users_roles', 'u', array(
'target' => 'slave',
))
->fields('u', array(
'rid',
))
->condition('uid', $uid)
->orderBy('u.rid')
->execute();
foreach ($result as $row) {
$roles[] = $row->rid;
}
$name = $names[$uid];
$dummy_account = (object) array(
'name' => $name,
'uid' => $uid,
);
$policy = _password_policy_load_active_policy($roles, $dummy_account);
if ($policy) {
$expiration = $policy['expiration'];
$warnings = !empty($policy['warning']) ? explode(',', $policy['warning']) : array();
if (!empty($expiration)) {
// Calculate expiration time.
$expiration_seconds = $expiration * (60 * 60 * 24);
$policy_start = $policy['created'];
if (variable_get('password_policy_begin', 0) == 1) {
$policy_start -= $expiration_seconds;
}
rsort($warnings, SORT_NUMERIC);
$time = _password_policy_get_request_time();
// Check expiration and warning days for each account.
if (!empty($warnings)) {
foreach ($warnings as $warning) {
// Loop through all configured warning send-out days. If today is
// the day, we send out the warning.
$warning_seconds = $warning * (60 * 60 * 24);
// Warning start time.
$start_period = max($policy_start, $last_change) + $expiration_seconds - $warning_seconds;
// Warning end time. We create a one day window for cron to run.
$end_period = $start_period + 60 * 60 * 24;
if ($warns[$uid] && $warns[$uid] > $start_period && $warns[$uid] < $end_period) {
// A warning was already mailed out.
continue;
}
if ($time > $start_period && $time < $end_period) {
// A warning falls in the one day window, so we send out the
// warning.
$account = user_load($uid, TRUE);
$message = drupal_mail('password_policy', 'warning', $account->mail, user_preferred_language($account), array(
'account' => $account,
'days_left' => $warning,
));
if ($message['result']) {
// The mail was sent out successfully.
watchdog('password_policy', 'Password expiration warning mailed to %username at %email.', array(
'%username' => $account->name,
'%email' => $account->mail,
));
}
if ($pids[$uid]) {
db_update('password_policy_expiration')
->fields(array(
'warning' => $time,
))
->condition('uid', $uid)
->execute();
}
else {
db_insert('password_policy_expiration')
->fields(array(
'uid' => $uid,
'warning' => $time,
))
->execute();
}
}
}
}
if ($time > max($policy_start, $last_change) + $expiration_seconds && $time > $unblocks[$uid] + 60 * 60 * 24 && variable_get('password_policy_block', 0) == 0) {
// Block expired accounts. Unblocked accounts are not blocked for 24h.
// One time login lasts for a 24h.
db_update('users')
->fields(array(
'status' => 0,
))
->condition('uid', $uid)
->execute();
if ($pids[$uid]) {
db_update('password_policy_expiration')
->fields(array(
'blocked' => $time,
))
->condition('uid', $uid)
->execute();
}
else {
db_insert('password_policy_expiration')
->fields(array(
'uid' => $uid,
'blocked' => $time,
))
->execute();
}
$account = user_load($uid, TRUE);
watchdog('password_policy', 'Password for user %name has expired.', array(
'%name' => $account->name,
), WATCHDOG_NOTICE, l(t('edit'), 'user/' . $account->uid . '/edit'));
}
}
}
}
}