diff -u b/modules/user/user.module b/modules/user/user.module
--- b/modules/user/user.module
+++ b/modules/user/user.module
@@ -2226,11 +2226,13 @@
if ($form_state['flood_control_triggered'] == 'user') {
form_set_error('name', format_plural(variable_get('user_failed_login_user_limit', 5), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or request a new password.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', array('@url' => url('user/password'))));
watchdog('user', 'Flood control blocked login attempt for %user from %ip.', array('%user' => $form_state['values']['name'], '%ip' => ip_address()));
+ module_invoke_all('user_flood_control', ip_address(), $form_state['values']['name']);
}
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 request a new password.', array('@url' => url('user/password'))));
watchdog('user', 'Flood control blocked login attempt from %ip.', array('%ip' => ip_address()));
+ module_invoke_all('user_flood_control', ip_address());
}
// We cannot call drupal_access_denied() here as that can result in an
// infinite loop if the login form is rendered on the 403 page (e.g. in a
diff -u b/modules/user/user.test b/modules/user/user.test
--- b/modules/user/user.test
+++ b/modules/user/user.test
@@ -322,7 +322,7 @@
}
function setUp() {
- parent::setUp('user_session_test');
+ parent::setUp('user_session_test', 'user_flood_test');
}
/**
@@ -438,16 +438,12 @@
$this->drupalPost('user', $edit, t('Log in'));
$this->assertNoFieldByXPath("//input[@name='pass' and @value!='']", NULL, 'Password value attribute is blank.');
if (isset($flood_trigger)) {
- $this->assertResponse(403);
- $last_log = db_query_range('SELECT message FROM {watchdog} WHERE type = :type ORDER BY wid DESC', 0, 1, array(':type' => 'user'))->fetchField();
if ($flood_trigger == 'user') {
- $this->assertRaw(t('Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', array('@url' => url('user/password'), '@count' => variable_get('user_failed_login_user_limit', 5))));
- $this->assertEqual('Flood control blocked login attempt for %user from %ip.', $last_log, 'A watchdog message was logged for the login attempt blocked by flood control per user');
+ $this->assertRaw(format_plural(variable_get('user_failed_login_user_limit', 5), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or request a new password.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', array('@url' => url('user/password'))));
}
else {
// No uid, so the limit is IP-based.
$this->assertRaw(t('Sorry, too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or request a new password.', array('@url' => url('user/password'))));
- $this->assertEqual('Flood control blocked login attempt from %ip.', $last_log, 'A watchdog message was logged for the login attempt blocked by flood control per IP');
}
}
else {
@@ -457,12 +453,19 @@
$this->drupalPost('user', $edit, t('Log in'));
$this->assertNoFieldByXPath("//input[@name='pass' and @value!='']", NULL, 'Password value attribute is blank.');
if (isset($flood_trigger)) {
+ $this->assertResponse(403);
+ $user_log = db_query_range('SELECT message FROM {watchdog} WHERE type = :type ORDER BY wid DESC', 0, 1, array(':type' => 'user'))->fetchField();
+ $user_flood_test_log = db_query_range('SELECT message FROM {watchdog} WHERE type = :type ORDER BY wid DESC', 0, 1, array(':type' => 'user_flood_test'))->fetchField();
if ($flood_trigger == 'user') {
- $this->assertRaw(format_plural(variable_get('user_failed_login_user_limit', 5), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or request a new password.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', array('@url' => url('user/password'))));
+ $this->assertRaw(t('Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or request a new password.', array('@url' => url('user/password'), '@count' => variable_get('user_failed_login_user_limit', 5))));
+ $this->assertEqual('Flood control blocked login attempt for %user from %ip.', $user_log, 'A watchdog message was logged for the login attempt blocked by flood control per user');
+ $this->assertEqual('hook_user_flood_control was passed username %username and IP %ip.', $user_flood_test_log, 'hook_user_flood_control was invoked by flood control per user');
}
else {
// No uid, so the limit is IP-based.
$this->assertRaw(t('Sorry, too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or request a new password.', array('@url' => url('user/password'))));
+ $this->assertEqual('Flood control blocked login attempt from %ip.', $user_log, 'A watchdog message was logged for the login attempt blocked by flood control per IP');
+ $this->assertEqual('hook_user_flood_control was passed IP %ip.', $user_flood_test_log, 'hook_user_flood_control was invoked by flood control per IP');
}
}
else {
only in patch2:
unchanged:
--- /dev/null
+++ b/modules/user/tests/user_flood_test.info
@@ -0,0 +1,6 @@
+name = "User module flood control tests"
+description = "Support module for user flood control testing."
+package = Testing
+version = VERSION
+core = 7.x
+hidden = TRUE
only in patch2:
unchanged:
--- /dev/null
+++ b/modules/user/tests/user_flood_test.module
@@ -0,0 +1,18 @@
+ $username, '%ip' => $ip));
+ }
+ else {
+ watchdog('user_flood_test', 'hook_user_flood_control was passed IP %ip.', array('%ip' => $ip));
+ }
+}
only in patch2:
unchanged:
--- a/modules/user/tests/user_form_test.module
+++ b/modules/user/tests/user_form_test.module
@@ -35,7 +35,7 @@ function user_form_test_current_password($form, &$form_state, $account) {
'#description' => t('A field that would require a correct password to change.'),
'#required' => TRUE,
);
-
+
$form['current_pass'] = array(
'#type' => 'password',
'#title' => t('Current password'),