diff --git a/constraints/constraint_username.inc b/constraints/constraint_username.inc index 7b3ef5d..cac25e3 100644 --- a/constraints/constraint_username.inc +++ b/constraints/constraint_username.inc @@ -11,14 +11,19 @@ * Description of the constraint. */ function password_policy_constraint_username_description() { - return array('name' => t('Username'), 'description' => t('Password must differ from the username. Put any positive number to enforce this policy.')); + return array('name' => t('Username'), 'description' => t('Password must differ from the username. Enter 1 to disallow passwords that exactly match the username (case insensitive). Enter 2 to disallow passwords that contain the username (case insensitive).')); } /** * Error message of the constraint. */ function password_policy_constraint_username_error($constraint) { - return t('Password must differ from the username.'); + if ($constraint == 1) { + return t('Password must differ from the username.'); + } + else { + return t('Password must not contain the username.'); + } } /** @@ -26,7 +31,14 @@ function password_policy_constraint_username_error($constraint) { */ function password_policy_constraint_username_validate($password, $constraint, $uid) { $account = user_load($uid); - return drupal_strtolower($account->name) != drupal_strtolower($password); + $username_lowercase = drupal_strtolower($account->name); + $password_lowercase = drupal_strtolower($password); + if ($constraint == 1) { + return $username_lowercase != $password_lowercase; + } + else { + return strpos($username_lowercase, $password_lowercase) === FALSE; + } } /** @@ -34,9 +46,16 @@ function password_policy_constraint_username_validate($password, $constraint, $u */ function password_policy_constraint_username_js($constraint, $uid) { $account = user_load($uid); + $username_lowercase = drupal_strtolower($account->name); + if ($constraint == 1) { + $condition_js = "password_lowercase == $username_lowercase"; + } + else { + $condition_js = "password_lowercase.indexOf('$username_lowercase') != -1"; + } $s = ''; - $s .= " var username='". $account->name ."';\n"; - $s .= " if (username.toLowerCase() == value.toLowerCase()) {\n"; + $s .= " var password_lowercase=value.toLowerCase();"; + $s .= " if ($condition_js) {\n"; $s .= " strength=\"low\";\n"; $s .= " msg.push(translate.constraint_username);\n"; $s .= " }\n"; diff --git a/password_policy.install b/password_policy.install index e1e3e43..acb78b6 100644 --- a/password_policy.install +++ b/password_policy.install @@ -283,3 +283,25 @@ function password_policy_update_7000() { db_drop_unique_key('password_policy_role', 'name'); } +/** + * Change any existing username constraint values to '1', which indicates + * the username cannot exactly match the password. 7.x-1.0 and earlier did + * not have different behaviors for different username constraint values. + */ +function password_policy_update_7100() { + $result = db_query("SELECT pid, policy FROM {password_policy}"); + foreach ($result as $row) { + $pid = $row->pid; + $policy = unserialize($row->policy); + if (array_key_exists('username', $policy)) { + $policy['username'] = '1'; + db_update('password_policy') + ->fields(array( + 'policy' => serialize($policy) + )) + ->condition('pid', $pid, '=') + ->execute(); + } + } +} + diff --git a/tests/password_policy.test b/tests/password_policy.test index 8ae746d..4f8d2da 100644 --- a/tests/password_policy.test +++ b/tests/password_policy.test @@ -140,11 +140,19 @@ class PasswordPolicyTest extends DrupalWebTestCase { function testUsernameConstraint() { module_load_include('inc', 'password_policy', 'constraints/constraint_username'); $user = $this->drupalCreateUser(); - $name = $this->randomName(); - $result = password_policy_constraint_username_validate($name, '', $user->uid); - $this->assertTrue($result, 'Random string in the username constraint'); - $result = password_policy_constraint_username_validate($user->name, '', $user->uid); - $this->assertFalse($result, 'Username in the username constraint'); + $username = $user->name; + $random_name = $this->randomName(); + $constraint = 1; + $result = password_policy_constraint_username_validate($random_name, $constraint, $user->uid); + $this->assertTrue($result, 'Random string in the username constraint with param 1'); + $result = password_policy_constraint_username_validate($username, $constraint, $user->uid); + $this->assertFalse($result, 'Username in the username constraint with param 1'); + $constraint = 2; + $name_containing_username = 'foo' . $username . 'bar'; + $result = password_policy_constraint_username_validate($random_name, $constraint, $user->uid); + $this->assertTrue($result, 'Random string in the username constraint with param 2'); + $result = password_policy_constraint_username_validate($name_containing_username, $constraint, $user->uid); + $this->assertFalse($result, 'String containing username in the username constraint with param 2'); } function testDelayConstraint() {