View source
<?php
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RedirectResponse;
function force_password_change_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if ($form_id == 'user_role_form') {
if (\Drupal::config('force_password_change.settings')
->get('check_login_only')) {
$description = t('Users will be required to change their password upon their next login.');
}
else {
$description = t('Users who are not signed in will be required to change their password immediately upon login. Users who are currently signed in will be required to change their password upon their next page click, and after changing their password will be redirected back to the page they were attempting to access.');
}
$form['force_password_change'] = array(
'#type' => 'checkbox',
'#title' => t('Force users in this role to change their password'),
'#description' => $description . '<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.'),
);
$form['actions']['submit']['#submit'][] = 'force_password_change_edit_role';
}
elseif ($form_id == 'user_role_delete_form') {
$role = \Drupal::routeMatch()
->getParameter('user_role');
$form['rid'] = array(
'#type' => 'value',
'#value' => $role
->id(),
);
$form['actions']['submit']['#submit'][] = 'force_password_change_delete_role';
}
elseif ($form_id == 'user_form') {
$account = \Drupal::routeMatch()
->getParameter('user');
$current_user = \Drupal::currentUser();
if ($current_user
->hasPermission('administer force password change')) {
if (isset($form['account'])) {
$use_form =& $form['account'];
}
else {
$use_form =& $form;
}
$use_form['name']['#weight'] = -10;
$use_form['mail']['#weight'] = -9;
$use_form['password'] = array(
'#type' => 'fieldset',
'#title' => t('Password'),
'#weight' => -1,
);
$use_form['password']['pass'] = $use_form['pass'];
if (isset($use_form['pass'])) {
unset($use_form['pass']);
}
if (\Drupal::config('force_password_change.settings')
->get('check_login_only')) {
$description = t('If this box is checked, the user will be forced to change their password upon their next login.');
}
else {
$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.');
}
$use_form['password']['force_password_change'] = array(
'#type' => 'checkbox',
'#title' => t('Force this user to change their password'),
'#access' => $current_user
->hasPermission('administer force password change'),
'#description' => $description . '<br />' . t('Note: This box will be unchecked each time the page is loaded, as it is a trigger, not a persistent state.'),
);
$last_force_time = \Drupal::service('user.data')
->get('force_password_change', $account
->id(), 'last_force');
if ($last_force_time) {
$last_force = \Drupal::service('date.formatter')
->format($last_force_time, 'short');
}
elseif (\Drupal::config('force_password_change.settings')
->get('first_time_login_password_change') && $account
->getCreatedTime() > \Drupal::config('force_password_change.settings')
->get('installation_date')) {
$last_force = t('Their first login');
}
else {
$forced_uids = \Drupal::service('force_password_change.service')
->getFirstTimeLoginUids();
if (count($forced_uids) && isset($forced_uids[$account
->id()])) {
$last_force = t('First login');
}
else {
$last_force = t('Never');
}
}
$items[] = t('User has a pending forced password change: @pending', [
'@pending' => \Drupal::service('user.data')
->get('force_password_change', $account
->id(), 'force_password_change') ? t('Yes') : t('No'),
]);
$items[] = t('User was last forced to change their password on: @last_force', [
'@last_force' => $last_force,
]);
$last_change_time = \Drupal::service('user.data')
->get('force_password_change', $account
->id(), 'last_change');
$items[] = t("User's password was last changed on: @last_change", [
'@last_change' => $last_change_time ? \Drupal::service('date.formatter')
->format($last_change_time, 'short') : t('Never'),
]);
$use_form['password']['password_stats'] = [
'header' => [
'#prefix' => '<p><strong>',
'#suffix' => '</strong></p>',
'#markup' => t('Password Stats:'),
],
'list' => [
'#theme' => 'item_list',
'#items' => $items,
],
];
}
$pass_reset = isset($_SESSION['pass_reset_' . $account
->id()]) && isset($_GET['pass-reset-token']) && $_GET['pass-reset-token'] == $_SESSION['pass_reset_' . $account
->id()];
$protected_values = [];
if (!$pass_reset) {
$protected_values['mail'] = $form['account']['mail']['#title'];
$protected_values['pass'] = t('Password');
$url = Url::fromRoute('user.pass', [], [
'attributes' => [
'title' => t('Request new password via e-mail.'),
],
]);
$request_link = Link::fromTextAndUrl(t('request a new password'), $url);
$request_new = new FormattableMarkup('@link', [
'@link' => $request_link
->toString(),
]);
$form['account']['current_pass']['#description'] = t('Enter your current password to change the %mail or %pass. If you do not know your current password, you can @request_new.', [
'%mail' => $protected_values['mail'],
'%pass' => $protected_values['pass'],
'@request_new' => $request_new,
]);
}
$form['pending_force_password_change'] = array(
'#type' => 'value',
'#value' => \Drupal::service('user.data')
->get('force_password_change', $account
->id(), 'force_password_change'),
);
$form['#validate'][] = 'force_password_change_validate_user';
$form['actions']['submit']['#submit'][] = 'force_password_change_update_user';
}
elseif ($form_id == 'user_register_form' && \Drupal::currentUser()
->id()) {
if (!\Drupal::config('force_password_change.settings')
->get('first_time_login_password_change')) {
if ($form['account']) {
$use_form =& $form['account'];
}
else {
$use_form =& $form;
}
$use_form['name']['#weight'] = -10;
$use_form['mail']['#weight'] = -9;
$use_form['password']['#weight'] = -8;
$use_form['password']['pass'] = $use_form['pass'];
unset($use_form['pass']);
$use_form['password']['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.'),
'#access' => \Drupal::currentUser()
->hasPermission('administer force password change'),
);
$form['actions']['submit']['#submit'][] = 'force_password_change_insert_user';
}
}
}
function force_password_change_user_login($account) {
if (\Drupal::config('force_password_change.settings')
->get('check_login_only')) {
if (\Drupal::service('force_password_change.service')
->checkForForce()) {
drupal_set_message(t('An administrator has required that you change your password. Please change your password to proceed.'));
$response = new RedirectResponse('/user/' . $account
->id() . '/edit');
return $response
->send();
}
}
}
function force_password_change_user_insert($account) {
$db = \Drupal::database();
if (\Drupal::config('force_password_change.settings')
->get('first_time_login_password_change')) {
$force_password_change_service = \Drupal::service('force_password_change.service');
$force_password_change_service
->forceUserPasswordChange($account
->id());
$force_password_change_service
->addFirstTimeLogin($account
->id());
}
}
function force_password_change_user_delete($account) {
$query = \Drupal::database()
->delete('force_password_change_uids')
->condition('uid', $account
->id())
->execute();
}
function force_password_change_validate_user(array &$form, FormStateInterface $form_state) {
$account = \Drupal::routeMatch()
->getParameter('user');
$current_user = \Drupal::currentUser();
if ($account
->id() == $current_user
->id() && \Drupal::service('user.data')
->get('force_password_change', $account
->id(), 'force_password_change')) {
if (!strlen($form_state
->getValue('pass'))) {
$form_state
->setErrorByName('pass', t('You must choose a new password'));
}
}
if (\Drupal::service('user.auth')
->authenticate($account
->getAccountName(), $form_state
->getValue('pass'))) {
$form_state
->setErrorByName('pass', t('You cannot use your current password. Please choose a different password.'));
}
}
function force_password_change_update_user(array &$form, FormStateInterface $form_state) {
$uid = $form_state
->getValue('uid');
$current_user = \Drupal::currentUser();
$user_data_service = \Drupal::service('user.data');
$db = \Drupal::database();
$current_pass = $form_state
->getValue('current_pass');
if ($current_pass && $current_pass != $form_state
->getValue('pass')) {
\Drupal::service('force_password_change.service')
->setChangedTimeForUser($uid);
if ($current_user
->id() == $uid && $user_data_service
->get('force_password_change', $uid, 'pending_force')) {
$force_password_change_service = \Drupal::service('force_password_change.service');
$force_password_change_service
->removePendingForce($uid);
$force_password_change_service
->removeFirstTimeLogin($uid);
}
}
if ($form_state
->getValue('force_password_change')) {
Drupal::service('force_password_change.service')
->forceUsersPasswordChange([
$uid,
]);
}
}
function force_password_change_insert_user(array $form, FormStateInterface $form_state) {
if ($form_state
->getValue('force_password_change')) {
$uid = $form_state
->getValue('uid');
$force_password_change_service = \Drupal::service('force_password_change.service');
$force_password_change_service
->forceUserPasswordChange($uid);
$force_password_change_service
->addFirstTimeLogin($uid);
drupal_set_message(t('%name will be required to change their password upon their first login', [
'%name' => $form_state
->getValue('name'),
]));
}
}
function force_password_change_delete_role(array $form, FormStateInterface $form_state) {
\Drupal::database()
->delete('force_password_change_roles')
->condition('rid', $form_state
->getValue('rid'))
->execute();
\Drupal::database()
->delete('force_password_change_expiry')
->condition('rid', $form_state
->getValue('rid'))
->execute();
}
function force_password_change_edit_role(array $form, FormStateInterface $form_state) {
$db = \Drupal::database();
$exists = $db
->query('SELECT 1 FROM {force_password_change_roles} WHERE rid = :rid', [
':rid' => $form_state
->getValue('id'),
])
->fetchField();
if (!$exists) {
$db
->insert('force_password_change_roles')
->fields([
'rid' => $form_state
->getValue('id'),
'last_force' => 0,
])
->execute();
}
if ($form_state
->getValue('force_password_change')) {
if ($form_state
->getValue('id') == 'authenticated') {
$sql = 'SELECT uid FROM {users} WHERE uid > 0';
$values = [];
}
else {
$sql = 'SELECT entity_id FROM {user__roles} WHERE roles_target_id = :rid ';
$values[':rid'] = $form_state
->getValue('id');
}
$uids = $db
->query($sql, $values)
->fetchCol();
if (count($uids)) {
\Drupal::service('force_password_change.service')
->forceUsersPasswordChange($uids);
}
$query = $db
->update('force_password_change_roles')
->fields([
'last_force' => REQUEST_TIME,
])
->condition('rid', $form_state
->getValue('id'))
->execute();
if (\Drupal::config('force_password_change.settings')
->get('check_login_only')) {
$description = t('User with the %role_name role will be required to change their password upon their next login.', [
'%role_name' => $form_state
->getValue('label'),
]);
}
else {
$description = t('Users in the %role_name role will be required to immediately change their password', [
'%role_name' => $form_state
->getValue('label'),
]);
}
drupal_set_message($description);
}
}
function force_password_change_entity_type_alter(array &$entity_types) {
$entity_types['user_role']
->setListBuilderClass('\\Drupal\\force_password_change\\Entity\\User\\ForcePasswordChangeRoleListBuilder');
}