Commit a733022d authored by dvadym's avatar dvadym Committed by Commit bot

If we have credentials with the empty username and the user uses them for...

If we have credentials with the empty username and the user uses them for sign-in with non-empty username then delete no-username credentials. These no-username credentials most probably were stored on change password or reset forms, and we don't need them anymore.

BUG=359315

Review URL: https://codereview.chromium.org/1272613002

Cr-Commit-Position: refs/heads/master@{#342360}
parent 43e720b1
...@@ -289,9 +289,10 @@ void PasswordFormManager::Save() { ...@@ -289,9 +289,10 @@ void PasswordFormManager::Save() {
LogPasswordGenerationSubmissionEvent(PASSWORD_USED); LogPasswordGenerationSubmissionEvent(PASSWORD_USED);
} }
if (IsNewLogin()) if (IsNewLogin()) {
SaveAsNewLogin(true); SaveAsNewLogin(true);
else DeleteEmptyUsernameCredentials();
} else
UpdateLogin(); UpdateLogin();
} }
...@@ -996,6 +997,22 @@ int PasswordFormManager::ScoreResult(const PasswordForm& candidate) const { ...@@ -996,6 +997,22 @@ int PasswordFormManager::ScoreResult(const PasswordForm& candidate) const {
return score; return score;
} }
void PasswordFormManager::DeleteEmptyUsernameCredentials() {
if (best_matches_.empty() || pending_credentials_.username_value.empty())
return;
PasswordStore* password_store = client_->GetPasswordStore();
if (!password_store) {
NOTREACHED();
return;
}
for (auto iter = best_matches_.begin(); iter != best_matches_.end(); ++iter) {
PasswordForm* form = iter->second;
if (!form->IsPublicSuffixMatch() && form->username_value.empty() &&
form->password_value == pending_credentials_.password_value)
password_store->RemoveLogin(*form);
}
}
PasswordForm* PasswordFormManager::FindBestMatchForUpdatePassword( PasswordForm* PasswordFormManager::FindBestMatchForUpdatePassword(
const base::string16& password) const { const base::string16& password) const {
if (best_matches_.size() == 1) { if (best_matches_.size() == 1) {
......
...@@ -362,6 +362,12 @@ class PasswordFormManager : public PasswordStoreConsumer { ...@@ -362,6 +362,12 @@ class PasswordFormManager : public PasswordStoreConsumer {
// from password store. // from password store.
void CreatePendingCredentials(); void CreatePendingCredentials();
// If |pending_credentials_.username_value| is not empty, iterates over all
// forms from |best_matches_| and deletes from the password store all which
// are not PSL-matched, have an empty username, and a password equal to
// |pending_credentials_.password_value|.
void DeleteEmptyUsernameCredentials();
// If |best_matches| contains only one entry then return this entry. Otherwise // If |best_matches| contains only one entry then return this entry. Otherwise
// for empty |password| return nullptr and for non-empty |password| returns // for empty |password| return nullptr and for non-empty |password| returns
// the unique entry in |best_matches_| with the same password, if it exists, // the unique entry in |best_matches_| with the same password, if it exists,
......
...@@ -54,6 +54,10 @@ ACTION_P4(InvokeConsumer, form1, form2, form3, form4) { ...@@ -54,6 +54,10 @@ ACTION_P4(InvokeConsumer, form1, form2, form3, form4) {
arg0->OnGetPasswordStoreResults(result.Pass()); arg0->OnGetPasswordStoreResults(result.Pass());
} }
MATCHER_P(CheckUsername, username_value, "Username incorrect") {
return arg.username_value == username_value;
}
void RunAllPendingTasks() { void RunAllPendingTasks() {
base::RunLoop run_loop; base::RunLoop run_loop;
base::ThreadTaskRunnerHandle::Get()->PostTask( base::ThreadTaskRunnerHandle::Get()->PostTask(
...@@ -1750,4 +1754,175 @@ TEST_F(PasswordFormManagerTest, WipeStoreCopyIfOutdated_Outdated) { ...@@ -1750,4 +1754,175 @@ TEST_F(PasswordFormManagerTest, WipeStoreCopyIfOutdated_Outdated) {
1); 1);
} }
TEST_F(PasswordFormManagerTest, RemoveNoUsernameAccounts) {
TestPasswordManagerClient client_with_store(mock_store());
TestPasswordManager password_manager(&client_with_store);
PasswordFormManager form_manager(&password_manager, &client_with_store,
client_with_store.driver(), *observed_form(),
false);
PasswordForm saved_form = *saved_match();
saved_form.username_value.clear();
ScopedVector<PasswordForm> result;
result.push_back(new PasswordForm(saved_form));
form_manager.SimulateFetchMatchingLoginsFromPasswordStore();
form_manager.OnGetPasswordStoreResults(result.Pass());
PasswordForm submitted_form(*observed_form());
submitted_form.preferred = true;
submitted_form.username_value = saved_match()->username_value;
submitted_form.password_value = saved_match()->password_value;
saved_form.preferred = false;
EXPECT_CALL(*mock_store(),
AddLogin(CheckUsername(saved_match()->username_value)));
EXPECT_CALL(*mock_store(), RemoveLogin(saved_form));
form_manager.ProvisionallySave(
submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
form_manager.Save();
}
TEST_F(PasswordFormManagerTest, NotRemovePSLNoUsernameAccounts) {
TestPasswordManagerClient client_with_store(mock_store());
TestPasswordManager password_manager(&client_with_store);
PasswordFormManager form_manager(&password_manager, &client_with_store,
client_with_store.driver(), *observed_form(),
false);
PasswordForm saved_form = *saved_match();
saved_form.username_value.clear();
saved_form.original_signon_realm = "www.example.org";
ScopedVector<PasswordForm> result;
result.push_back(new PasswordForm(saved_form));
form_manager.SimulateFetchMatchingLoginsFromPasswordStore();
form_manager.OnGetPasswordStoreResults(result.Pass());
PasswordForm submitted_form(*observed_form());
submitted_form.preferred = true;
submitted_form.username_value = saved_match()->username_value;
submitted_form.password_value = saved_match()->password_value;
EXPECT_CALL(*mock_store(),
AddLogin(CheckUsername(saved_match()->username_value)));
EXPECT_CALL(*mock_store(), RemoveLogin(_)).Times(0);
form_manager.ProvisionallySave(
submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
form_manager.Save();
}
TEST_F(PasswordFormManagerTest, NotRemoveCredentialsWithUsername) {
TestPasswordManagerClient client_with_store(mock_store());
TestPasswordManager password_manager(&client_with_store);
PasswordFormManager form_manager(&password_manager, &client_with_store,
client_with_store.driver(), *observed_form(),
false);
PasswordForm saved_form = *saved_match();
ASSERT_FALSE(saved_form.username_value.empty());
ScopedVector<PasswordForm> result;
result.push_back(new PasswordForm(saved_form));
form_manager.SimulateFetchMatchingLoginsFromPasswordStore();
form_manager.OnGetPasswordStoreResults(result.Pass());
PasswordForm submitted_form(*observed_form());
submitted_form.preferred = true;
base::string16 username = saved_form.username_value + ASCIIToUTF16("1");
submitted_form.username_value = username;
submitted_form.password_value = saved_match()->password_value;
EXPECT_CALL(*mock_store(), AddLogin(CheckUsername(username)));
EXPECT_CALL(*mock_store(), RemoveLogin(_)).Times(0);
form_manager.ProvisionallySave(
submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
form_manager.Save();
}
TEST_F(PasswordFormManagerTest, NotRemoveCredentialsWithDiferrentPassword) {
TestPasswordManagerClient client_with_store(mock_store());
TestPasswordManager password_manager(&client_with_store);
PasswordFormManager form_manager(&password_manager, &client_with_store,
client_with_store.driver(), *observed_form(),
false);
PasswordForm saved_form = *saved_match();
saved_form.username_value.clear();
ScopedVector<PasswordForm> result;
result.push_back(new PasswordForm(saved_form));
form_manager.SimulateFetchMatchingLoginsFromPasswordStore();
form_manager.OnGetPasswordStoreResults(result.Pass());
PasswordForm submitted_form(*observed_form());
submitted_form.preferred = true;
submitted_form.username_value = saved_match()->username_value;
submitted_form.password_value = saved_form.password_value + ASCIIToUTF16("1");
EXPECT_CALL(*mock_store(),
AddLogin(CheckUsername(saved_match()->username_value)));
EXPECT_CALL(*mock_store(), RemoveLogin(_)).Times(0);
form_manager.ProvisionallySave(
submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
form_manager.Save();
}
TEST_F(PasswordFormManagerTest, SaveNoUsernameEvenIfWithUsernamePresent) {
TestPasswordManagerClient client_with_store(mock_store());
TestPasswordManager password_manager(&client_with_store);
PasswordFormManager form_manager(&password_manager, &client_with_store,
client_with_store.driver(), *observed_form(),
false);
PasswordForm* saved_form = saved_match();
ASSERT_FALSE(saved_match()->username_value.empty());
ScopedVector<PasswordForm> result;
result.push_back(new PasswordForm(*saved_form));
form_manager.SimulateFetchMatchingLoginsFromPasswordStore();
form_manager.OnGetPasswordStoreResults(result.Pass());
PasswordForm submitted_form(*observed_form());
submitted_form.preferred = true;
submitted_form.username_value.clear();
EXPECT_CALL(*mock_store(), AddLogin(CheckUsername(base::string16())));
EXPECT_CALL(*mock_store(), RemoveLogin(_)).Times(0);
form_manager.ProvisionallySave(
submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
form_manager.Save();
}
TEST_F(PasswordFormManagerTest, NotRemoveOnUpdate) {
TestPasswordManagerClient client_with_store(mock_store());
TestPasswordManager password_manager(&client_with_store);
PasswordFormManager form_manager(&password_manager, &client_with_store,
client_with_store.driver(), *observed_form(),
false);
ScopedVector<PasswordForm> result;
PasswordForm saved_form = *saved_match();
ASSERT_FALSE(saved_form.username_value.empty());
result.push_back(new PasswordForm(saved_form));
saved_form.username_value.clear();
saved_form.preferred = false;
result.push_back(new PasswordForm(saved_form));
form_manager.SimulateFetchMatchingLoginsFromPasswordStore();
form_manager.OnGetPasswordStoreResults(result.Pass());
PasswordForm submitted_form(*observed_form());
submitted_form.preferred = true;
submitted_form.username_value = saved_match()->username_value;
submitted_form.password_value = saved_form.password_value + ASCIIToUTF16("1");
EXPECT_CALL(*mock_store(),
UpdateLogin(CheckUsername(saved_match()->username_value)));
EXPECT_CALL(*mock_store(), RemoveLogin(_)).Times(0);
form_manager.ProvisionallySave(
submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
form_manager.Save();
}
} // namespace password_manager } // namespace password_manager
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment