# This patch file was generated by NetBeans IDE # This patch can be applied using context Tools: Apply Diff Patch action on respective folder. # It uses platform neutral UTF-8 encoding. # Above lines and this line are ignored by the patching process. Index: contributions/modules/login_security/login_security.module --- contributions/modules/login_security/login_security.module Base (1.12.2.4) +++ contributions/modules/login_security/login_security.module Locally Modified (Based On 1.12.2.4) @@ -66,6 +66,23 @@ // can read the old timestamp. $form['#validate'] = array_merge(array('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("
".print_r($form,1)."
"); + // 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')) { @@ -280,7 +297,7 @@ login_user_block_ip($variables); } } - +/* // Check for host login attempts: Soft if ($variables['%soft_block_attempts'] >= 1) { if ($variables['%ip_current_count'] > $variables['%soft_block_attempts']) { @@ -289,10 +306,9 @@ $variables[$key] = theme('placeholder', $value); } form_set_error('submit', strtr(variable_get('login_security_host_soft_banned', LOGIN_SECURITY_HOST_SOFT_BANNED), $variables)); - drupal_goto(drupal_get_destination()); } } - +*/ // Check for user login attempts if ($variables['%user_block_attempts'] >= 1) { if ($variables['%user_current_count'] > $variables['%user_block_attempts']) { Index: contributions/modules/login_security/login_security.test --- contributions/modules/login_security/login_security.test Base (1.1.2.4) +++ contributions/modules/login_security/login_security.test Locally Modified (Based On 1.1.2.4) @@ -45,19 +45,22 @@ } } -class LoginSecurityFunctionalTest extends DrupalWebTestCase { +class LoginSecurityUserBlockingTest extends DrupalWebTestCase { public static function getInfo() { return array( - 'name' => t('Login Security functional'), - 'description' => t('Test Login Security\'s login restrictions.'), + 'name' => t('Login Security userblock functional'), + 'description' => t('Test Login Security\'s user-blocking restrictions and default messages.'), 'group' => t('Login Security') ); } function setUp() { parent::setUp('login_security'); + // Ensure the table has no entries + db_query("TRUNCATE TABLE {login_security_track}"); } + // Check if login is break somewhere function testLogin() { variable_set('login_security_user_wrong_count', 5); $normal_user = $this->drupalCreateUser(array('access content')); @@ -171,3 +174,87 @@ $this->isLoggedIn = TRUE; } } + +class LoginSecuritySoftBlockTest extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => t('Login Security Softblock functional'), + 'description' => t('Test Login Security\'s soft blocking restrictions.'), + 'group' => t('Login Security') + ); + } + + function setUp() { + parent::setUp('login_security'); + // Ensure the table has no entries + db_query("TRUNCATE TABLE {login_security_track}"); + } + + function testLogin() { + variable_set('login_security_user_wrong_count', 5); + $normal_user = $this->drupalCreateUser(array('access content')); + $this->drupalLogin($normal_user); + $this->assertNoText("You have used 1 out of 5 login attempts. After all 5 have been used, you will be unable to login.", t('Attempts available message displayed.')); + } + + function testSoftBlocking() { + + $login_attempts_limit = 2; + + // allow 2 attempts to login before being soft-blocking is enforced + variable_set('login_security_user_wrong_count', 0); + variable_set('login_security_host_wrong_count', 2); + // remove notices + variable_set('login_security_notice_attempts_available', 0); + + $normal_user = $this->drupalCreateUser(array('access content')); + $good_pass = $normal_user->pass_raw; + + // intentionally break the password to repeat invalid logins + $normal_user->pass_raw = user_password(); + + $site_name = variable_get('site_name', 'drupal'); + + // 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("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("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.. + 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->assertFieldByName('form_id', 'user_login', t('Login form found.')); + $this->assertNoFieldByName('op', 'Log in', t('Submit button not found.')); + + } + + function drupalLoginLite(stdClass $user) { + if ($this->isLoggedIn) { + $this->drupalLogout(); + } + + $edit = array( + 'name' => $user->name, + 'pass' => $user->pass_raw + ); + $this->drupalPost('user', $edit, t('Log in')); + + $this->isLoggedIn = TRUE; + } +} \ No newline at end of file