The final validation handler on the login form.
Sets a form error if user has not been authenticated, or if too many logins have been attempted. This validation function should always be the last one.
function user_login_final_validate($form, &$form_state) {
$flood_config = config('user.flood');
if (empty($form_state['uid'])) {
// Always register an IP-based failed login event.
drupal_container()
->get('flood')
->register('user.failed_login_ip', $flood_config
->get('ip_window'));
// Register a per-user failed login event.
if (isset($form_state['flood_control_user_identifier'])) {
drupal_container()
->get('flood')
->register('user.failed_login_user', $flood_config
->get('user_window'), $form_state['flood_control_user_identifier']);
}
if (isset($form_state['flood_control_triggered'])) {
if ($form_state['flood_control_triggered'] == 'user') {
form_set_error('name', format_plural($flood_config
->get('user_limit'), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array(
'@url' => url('user/password'),
)));
}
else {
// We did not find a uid, so the limit is IP-based.
form_set_error('name', t('Sorry, too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array(
'@url' => url('user/password'),
)));
}
}
else {
form_set_error('name', t('Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>', array(
'@password' => url('user/password'),
)));
watchdog('user', 'Login attempt failed for %user.', array(
'%user' => $form_state['values']['name'],
));
}
}
elseif (isset($form_state['flood_control_user_identifier'])) {
// Clear past failures for this user so as not to block a user who might
// log in and out more than once in an hour.
drupal_container()
->get('flood')
->clear('user.failed_login_user', $form_state['flood_control_user_identifier']);
}
}