Index: login_security.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/login_security/login_security.module,v
retrieving revision 1.12.2.5
diff -u -r1.12.2.5 login_security.module
--- login_security.module	19 Jun 2009 14:19:28 -0000	1.12.2.5
+++ login_security.module	22 Jun 2009 20:03:51 -0000
@@ -64,25 +64,8 @@
       // Put login_security first or the capture of the previous login timestamp won't work
       // and core's validation will update to the current login instance before login_security
       // can read the old timestamp.
-      $form['#validate'] = array_merge(array('login_security_set_login_timestamp'), $form['#validate']);
+      $form['#validate'] = array_merge(array('login_security_soft_block_validate', 'login_security_set_login_timestamp'), $form['#validate']);
       $form['#validate'][] = 'login_security_validate';
-
-      // Change to do soft-blocking here, see issue: http://drupal.org/node/493164
-      // We alter the form here, and still show the message in the validation
-      $variables = _login_security_get_variables_by_name(check_plain($form['name']['#value']));
-      //drupal_set_message("<pre>".print_r($form,1)."</pre>");
-      // Check for host login attempts: Soft
-      if ($variables['%soft_block_attempts'] >= 1) {
-        if ($variables['%ip_current_count'] >= $variables['%soft_block_attempts']) {
-          //Alter current form, so user will not be able to submit it
-          // this loop is instead of doing t() because t() can only translate static strings, not variables.
-          foreach ($variables as $key => $value) {
-            $variables[$key] = theme('placeholder', $value);
-          }
-          form_set_error('submit', strtr(variable_get('login_security_host_soft_banned',  LOGIN_SECURITY_HOST_SOFT_BANNED), $variables));
-          unset($form['submit']);
-        }
-      }
       break;
     case 'user_admin_settings':
       if (user_access('administer users')) {
@@ -259,6 +242,25 @@
 }
 
 /**
+ * Temprarily deny validation to users with excess invalid login attempts.
+ *
+ * @url http://drupal.org/node/493164
+ */
+function login_security_soft_block_validate($form, &$form_state) {
+  $variables = _login_security_get_variables_by_name(check_plain($form['name']['#value']));
+  // Check for host login attempts: Soft
+  if ($variables['%soft_block_attempts'] >= 1) {
+    if ($variables['%ip_current_count'] >= $variables['%soft_block_attempts']) {
+      // this loop is instead of doing t() because t() can only translate static strings, not variables.
+      foreach ($variables as $key => $value) {
+        $variables[$key] = theme('placeholder', $value);
+      }
+      form_set_error('submit', strtr(variable_get('login_security_host_soft_banned',  LOGIN_SECURITY_HOST_SOFT_BANNED), $variables));
+    }
+  }
+}
+
+/**
  * Implementation of form validate. This functions does more than just validating, but it's main
  * Intention is to break the login form flow.
  *
Index: login_security.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/login_security/login_security.test,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 login_security.test
--- login_security.test	19 Jun 2009 14:19:28 -0000	1.1.2.5
+++ login_security.test	22 Jun 2009 20:03:52 -0000
@@ -87,7 +87,6 @@
 
     // drupalLogin() has assertions that we know will fail, so we must skip them with an alternate function
     $this->drupalLoginLite($normal_user);
-    $this->assertResponse(200, t('Login page reloaded.'));
     $this->assertText("You have used 1 out of $login_attempts_limit login attempts. After all $login_attempts_limit have been used, you will be unable to login.", t('Attempts available message displayed.'));
     $this->assertFieldByName('form_id', 'user_login', t('Login form found.'));
 
@@ -95,7 +94,6 @@
     variable_set('login_security_notice_attempts_available', 0);
 
     $this->drupalLoginLite($normal_user);
-    $this->assertResponse(200, t('Login page reloaded.'));
     $this->assertNoText("You have used 2 out of $login_attempts_limit login attempts. After all $login_attempts_limit have been used, you will be unable to login.", t('Attempts available message displayed.'));
     $this->assertFieldByName('form_id', 'user_login', t('Login form found.'));
 
@@ -103,7 +101,6 @@
     variable_set('login_security_notice_attempts_available', 1);
 
     $this->drupalLoginLite($normal_user);
-    $this->assertResponse(200, t('Login page reloaded.'));
     $this->assertText("The user {$normal_user->name} has been blocked due to failed login attempts.", t('Blocked message displayed.'));
     $this->assertText("You have used 3 out of $login_attempts_limit login attempts. After all $login_attempts_limit have been used, you will be unable to login.", t('Attempts available message displayed.'));
     $this->assertFieldByName('form_id', 'user_login', t('Login form found.'));
@@ -170,6 +167,7 @@
       'pass' => $user->pass_raw
     );
     $this->drupalPost('user', $edit, t('Log in'));
+    $this->assertResponse(200, t('Login page reloaded.'));
 
     $this->isLoggedIn = TRUE;
   }
@@ -217,31 +215,30 @@
 
     // drupalLogin() has assertions that we know will fail, so we must skip them with an alternate function
     $this->drupalLoginLite($normal_user);
-    $this->assertResponse(200, t('Login page reloaded.'));
-    $this->assertNoText("This host is not allowed to log in to $site_name. Please contact your site administrator.", t('host is not soft-blocked.'));
+    $this->assertNoText("This host is not allowed to log in", t('Soft-blocked notice does not display.'));
     $this->assertNoText("The user {$normal_user->name} has been blocked due to failed login attempts.", t('User is not blocked.'));
     $this->assertFieldByName('form_id', 'user_login', t('Login form found.'));
 
     // Second try
     $this->drupalLoginLite($normal_user);
-    $this->assertResponse(200, t('Login page reloaded.'));
-    $this->assertNoText("This host is not allowed to log in to $site_name. Please contact your site administrator.", t('host is not soft-blocked.'));
+    $this->assertNoText("This host is not allowed to log in", t('Soft-blocked notice does not display.'));
     $this->assertNoText("The user {$normal_user->name} has been blocked due to failed login attempts.", t('User is not blocked.'));
     $this->assertFieldByName('form_id', 'user_login', t('Login form found.'));
     $this->assertFieldByName('op', 'Log in', t('Submit button found.'));
 
-    // remove core messages..
+    // remove error messages
     variable_set('login_security_disable_core_login_error', 1);
 
-    // The soft-block trigger
-    // We can't do a drupal post here, submit button doesn't exist
-    $this->drupalGet('user');
-    $this->assertResponse(200, t('Login page reloaded.'));
-    $this->assertText("This host is not allowed to log in to $site_name. Please contact your site administrator.", t('host is not soft-blocked.'));
-    $this->assertFieldByName('form_id', 'user_login', t('Login form found.'));
+    $this->drupalLoginLite($normal_user);
+    $this->assertNoText("This host is not allowed to log in", t('Soft-block message does not display.'));
     $this->assertFieldByName('form_id', 'user_login', t('Login form found.'));
-    $this->assertNoFieldByName('op', 'Log in', t('Submit button not found.'));
 
+    // restore error messages
+    variable_set('login_security_disable_core_login_error', 0);
+
+    $this->drupalLoginLite($normal_user);
+    $this->assertText("This host is not allowed to log in", t('Soft-block message displays.'));
+    $this->assertFieldByName('form_id', 'user_login', t('Login form found.'));
   }
 
   function drupalLoginLite(stdClass $user) {
@@ -254,6 +251,7 @@
       'pass' => $user->pass_raw
     );
     $this->drupalPost('user', $edit, t('Log in'));
+    $this->assertResponse(200, t('Login page reloaded.'));
 
     $this->isLoggedIn = TRUE;
   }
