Commit 9401da7c authored by Vasilii Sukhanov's avatar Vasilii Sukhanov Committed by Commit Bot

Change interface of FormSaver::Update.

This is a follow up to r649499. The Update method now matches Save() method.
The replacement logic is now in UpdateReplace().

Bug: 936011,831123
Change-Id: I59d65fe77ef3b386e80ba890e140370d190555c9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1596456
Commit-Queue: Vasilii Sukhanov <vasilii@chromium.org>
Reviewed-by: default avatarDominic Battré <battre@chromium.org>
Cr-Commit-Position: refs/heads/master@{#657675}
parent 942cd543
......@@ -13,6 +13,7 @@
#include "base/optional.h"
#include "base/strings/string16.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/password_store.h"
namespace password_manager {
......@@ -24,8 +25,10 @@ class FormSaver {
virtual ~FormSaver() = default;
// Configures the |observed| form to become a blacklist entry and saves it.
virtual void PermanentlyBlacklist(autofill::PasswordForm* observed) = 0;
// Blacklist the origin described by |digest|. Returns the PasswordForm pushed
// to the store.
virtual autofill::PasswordForm PermanentlyBlacklist(
PasswordStore::FormDigest digest) WARN_UNUSED_RESULT = 0;
// Saves the |pending| form.
// |matches| are relevant credentials for the site. After saving |pending|,
......@@ -35,21 +38,29 @@ class FormSaver {
// - empty-username credentials with the same password are removed.
// - if |old_password| is provided, the old credentials with the same username
// and the old password are updated to the new password.
virtual void Save(const autofill::PasswordForm& pending,
virtual void Save(autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) = 0;
// Updates the |pending| form and updates the stored preference on
// |best_matches|. If |old_primary_key| is given, uses it for saving
// |pending|. It also updates the password store with all
// |credentials_to_update|.
// TODO(crbug/831123): it's a convoluted interface, switch to the one for Save
virtual void Update(
const autofill::PasswordForm& pending,
const std::map<base::string16, const autofill::PasswordForm*>&
best_matches,
const std::vector<autofill::PasswordForm>* credentials_to_update,
const autofill::PasswordForm* old_primary_key) = 0;
// Updates the saved credential in the password store sharing the same key as
// the |pending| form.
// The algorithm for handling |matches| and |old_password| is the same as
// above.
virtual void Update(autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) = 0;
// If any of the primary key fields (signon_realm, origin, username_element,
// username_value, password_element) are updated, then the this version of
// the Update method must be used, which takes |old_primary_key|, i.e., the
// old values for the primary key fields (the rest of the fields are ignored).
// The algorithm for handling |matches| and |old_password| is the same as
// above.
virtual void UpdateReplace(
autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password,
const autofill::PasswordForm& old_unique_key) = 0;
// Removes |form| from the password store.
virtual void Remove(const autofill::PasswordForm& form) = 0;
......
......@@ -42,40 +42,25 @@ void SanitizeFormData(FormData* form) {
}
}
} // namespace
FormSaverImpl::FormSaverImpl(PasswordStore* store) : store_(store) {
DCHECK(store);
}
FormSaverImpl::~FormSaverImpl() = default;
void FormSaverImpl::PermanentlyBlacklist(PasswordForm* observed) {
*observed = password_manager_util::MakeNormalizedBlacklistedForm(
PasswordStore::FormDigest(*observed));
observed->date_created = base::Time::Now();
store_->AddLogin(*observed);
}
void FormSaverImpl::Save(const PasswordForm& pending,
const std::vector<const PasswordForm*>& matches,
const base::string16& old_password) {
// Do the clean up of |matches| after |pending| was just pushed to the store.
void PostProcessMatches(const PasswordForm& pending,
const std::vector<const PasswordForm*>& matches,
const base::string16& old_password,
PasswordStore* store) {
DCHECK(!pending.blacklisted_by_user);
PasswordForm sanitized_pending(pending);
SanitizeFormData(&sanitized_pending.form_data);
store_->AddLogin(sanitized_pending);
// Update existing matches in the password store.
for (const auto* match : matches) {
DCHECK(pending.preferred);
if (match->IsFederatedCredential())
if (match->IsFederatedCredential() ||
ArePasswordFormUniqueKeyEqual(pending, *match))
continue;
// Delete obsolete empty username credentials.
const bool same_password = match->password_value == pending.password_value;
const bool username_was_added =
match->username_value.empty() && !pending.username_value.empty();
if (same_password && username_was_added && !match->is_public_suffix_match) {
store_->RemoveLogin(*match);
store->RemoveLogin(*match);
continue;
}
base::Optional<PasswordForm> form_to_update;
......@@ -95,72 +80,64 @@ void FormSaverImpl::Save(const PasswordForm& pending,
}
if (form_to_update) {
SanitizeFormData(&form_to_update->form_data);
store_->UpdateLogin(std::move(*form_to_update));
store->UpdateLogin(std::move(*form_to_update));
}
}
}
void FormSaverImpl::Update(
const PasswordForm& pending,
const std::map<base::string16, const PasswordForm*>& best_matches,
const std::vector<PasswordForm>* credentials_to_update,
const PasswordForm* old_primary_key) {
DCHECK(!pending.blacklisted_by_user);
} // namespace
if (!best_matches.empty()) {
DCHECK(pending.preferred);
UpdatePreferredLoginState(pending.username_value, best_matches);
}
PasswordForm sanitized_pending(pending);
SanitizeFormData(&sanitized_pending.form_data);
if (old_primary_key)
store_->UpdateLoginWithPrimaryKey(sanitized_pending, *old_primary_key);
else
store_->UpdateLogin(sanitized_pending);
if (credentials_to_update) {
for (const PasswordForm& credential : *credentials_to_update) {
store_->UpdateLogin(credential);
}
}
FormSaverImpl::FormSaverImpl(PasswordStore* store) : store_(store) {
DCHECK(store);
}
void FormSaverImpl::Remove(const PasswordForm& form) {
store_->RemoveLogin(form);
FormSaverImpl::~FormSaverImpl() = default;
PasswordForm FormSaverImpl::PermanentlyBlacklist(
PasswordStore::FormDigest digest) {
PasswordForm blacklisted =
password_manager_util::MakeNormalizedBlacklistedForm(std::move(digest));
blacklisted.date_created = base::Time::Now();
store_->AddLogin(blacklisted);
return blacklisted;
}
std::unique_ptr<FormSaver> FormSaverImpl::Clone() {
return std::make_unique<FormSaverImpl>(store_);
void FormSaverImpl::Save(PasswordForm pending,
const std::vector<const PasswordForm*>& matches,
const base::string16& old_password) {
SanitizeFormData(&pending.form_data);
store_->AddLogin(pending);
// Update existing matches in the password store.
PostProcessMatches(pending, matches, old_password, store_);
}
void FormSaverImpl::UpdatePreferredLoginState(
const base::string16& preferred_username,
const std::map<base::string16, const PasswordForm*>& best_matches) {
for (const auto& key_value_pair : best_matches) {
const PasswordForm& form = *key_value_pair.second;
if (form.preferred && !form.is_public_suffix_match &&
form.username_value != preferred_username) {
// This wasn't the selected login but it used to be preferred.
PasswordForm update(form);
SanitizeFormData(&update.form_data);
update.preferred = false;
store_->UpdateLogin(update);
}
}
void FormSaverImpl::Update(
autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) {
SanitizeFormData(&pending.form_data);
store_->UpdateLogin(pending);
// Update existing matches in the password store.
PostProcessMatches(pending, matches, old_password, store_);
}
void FormSaverImpl::DeleteEmptyUsernameCredentials(
const PasswordForm& pending,
const std::map<base::string16, const PasswordForm*>& best_matches) {
DCHECK(!pending.username_value.empty());
void FormSaverImpl::UpdateReplace(
autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password,
const autofill::PasswordForm& old_unique_key) {
SanitizeFormData(&pending.form_data);
store_->UpdateLoginWithPrimaryKey(pending, old_unique_key);
// Update existing matches in the password store.
PostProcessMatches(pending, matches, old_password, store_);
}
for (const auto& match : best_matches) {
const PasswordForm* form = match.second;
if (!form->is_public_suffix_match && form->username_value.empty() &&
form->password_value == pending.password_value) {
store_->RemoveLogin(*form);
}
}
void FormSaverImpl::Remove(const PasswordForm& form) {
store_->RemoveLogin(form);
}
std::unique_ptr<FormSaver> FormSaverImpl::Clone() {
return std::make_unique<FormSaverImpl>(store_);
}
} // namespace password_manager
......@@ -24,34 +24,22 @@ class FormSaverImpl : public FormSaver {
~FormSaverImpl() override;
// FormSaver:
void PermanentlyBlacklist(autofill::PasswordForm* observed) override;
void Save(const autofill::PasswordForm& pending,
autofill::PasswordForm PermanentlyBlacklist(
PasswordStore::FormDigest digest) override WARN_UNUSED_RESULT;
void Save(autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) override;
void Update(const autofill::PasswordForm& pending,
const std::map<base::string16, const autofill::PasswordForm*>&
best_matches,
const std::vector<autofill::PasswordForm>* credentials_to_update,
const autofill::PasswordForm* old_primary_key) override;
void Update(autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) override;
void UpdateReplace(autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password,
const autofill::PasswordForm& old_unique_key) override;
void Remove(const autofill::PasswordForm& form) override;
std::unique_ptr<FormSaver> Clone() override;
private:
// Marks all of |best_matches| as not preferred unless the username is
// |preferred_username| or the credential is PSL matched.
void UpdatePreferredLoginState(
const base::string16& preferred_username,
const std::map<base::string16, const autofill::PasswordForm*>&
best_matches);
// Iterates over all |best_matches| and deletes from the password store all
// which are not PSL-matched, have an empty username, and a password equal to
// |pending.password_value|.
void DeleteEmptyUsernameCredentials(
const autofill::PasswordForm& pending,
const std::map<base::string16, const autofill::PasswordForm*>&
best_matches);
// The class is stateless. Don't introduce it. The methods are utilities for
// common tasks on the password store. The state should belong to either a
// form handler or origin handler which could embed FormSaver.
......
......@@ -267,21 +267,10 @@ void NewPasswordFormManager::Save() {
pending_credentials_.date_created = base::Time::Now();
votes_uploader_.SendVotesOnSave(observed_form_, *parsed_submitted_form_,
best_matches_, &pending_credentials_);
base::string16 old_password;
if (password_overridden_) {
// |pending_credentials_| contains not only a new credential that is to be
// stored, but it also implies that existing credentials in the store need
// to get the password updated.
const PasswordForm* saved_form =
password_manager_util::GetMatchForUpdating(*parsed_submitted_form_,
best_matches_);
DCHECK(saved_form);
old_password = saved_form->password_value;
}
SavePendingToStore(false /*update*/, old_password);
SavePendingToStore(false /*update*/);
} else {
ProcessUpdate();
SavePendingToStore(true /*update*/, base::string16());
SavePendingToStore(true /*update*/);
}
if (pending_credentials_.times_used == 1 &&
......@@ -311,7 +300,7 @@ void NewPasswordFormManager::Update(const PasswordForm& credentials_to_update) {
pending_credentials_.preferred = true;
is_new_login_ = false;
ProcessUpdate();
SavePendingToStore(true /*update*/, base::string16());
SavePendingToStore(true /*update*/);
client_->UpdateFormManagers();
}
......@@ -406,7 +395,8 @@ void NewPasswordFormManager::PermanentlyBlacklist() {
}
blacklisted_matches_.push_back(new_blacklisted_.get());
}
form_saver_->PermanentlyBlacklist(new_blacklisted_.get());
*new_blacklisted_ = form_saver_->PermanentlyBlacklist(
PasswordStore::FormDigest(*new_blacklisted_));
}
void NewPasswordFormManager::OnPasswordsRevealed() {
......@@ -988,29 +978,6 @@ void NewPasswordFormManager::FillHttpAuth() {
client_->AutofillHttpAuth(best_matches_, *preferred_match_);
}
std::vector<PasswordForm> NewPasswordFormManager::FindOtherCredentialsToUpdate()
const {
std::vector<autofill::PasswordForm> credentials_to_update;
if (!pending_credentials_.federation_origin.opaque())
return credentials_to_update;
auto updated_password_it =
best_matches_.find(pending_credentials_.username_value);
DCHECK(best_matches_.end() != updated_password_it);
const base::string16& old_password =
updated_password_it->second->password_value;
for (auto* not_best_match : not_best_matches_) {
if (not_best_match->username_value == pending_credentials_.username_value &&
not_best_match->password_value == old_password) {
credentials_to_update.push_back(*not_best_match);
credentials_to_update.back().password_value =
pending_credentials_.password_value;
}
}
return credentials_to_update;
}
std::unique_ptr<PasswordForm> NewPasswordFormManager::ParseFormAndMakeLogging(
const FormData& form,
FormDataParser::Mode mode) {
......@@ -1108,17 +1075,18 @@ std::vector<const PasswordForm*> NewPasswordFormManager::GetAllMatches() const {
return result;
}
void NewPasswordFormManager::SavePendingToStore(
bool update,
const base::string16& old_password) {
void NewPasswordFormManager::SavePendingToStore(bool update) {
const PasswordForm* saved_form = password_manager_util::GetMatchForUpdating(
*parsed_submitted_form_, best_matches_);
if (update || password_overridden_)
DCHECK(saved_form);
base::string16 old_password =
saved_form ? saved_form->password_value : base::string16();
if (HasGeneratedPassword()) {
generation_state_->CommitGeneratedPassword(pending_credentials_,
best_matches_, nullptr);
GetAllMatches(), old_password);
} else if (update) {
std::vector<PasswordForm> credentials_to_update =
FindOtherCredentialsToUpdate();
form_saver_->Update(pending_credentials_, best_matches_,
&credentials_to_update, nullptr);
form_saver_->Update(pending_credentials_, GetAllMatches(), old_password);
} else {
form_saver_->Save(pending_credentials_, GetAllMatches(), old_password);
}
......
......@@ -250,13 +250,6 @@ class NewPasswordFormManager : public PasswordFormManagerInterface,
// Sends fill data to the http auth popup.
void FillHttpAuth();
// Goes through |not_best_matches_|, updates the password of those which share
// the old password and username with |pending_credentials_| to the new
// password of |pending_credentials_|, and returns copies of all such modified
// credentials.
// TODO(crbug/831123): remove. FormSaver should do the job.
std::vector<autofill::PasswordForm> FindOtherCredentialsToUpdate() const;
// Helper function for calling form parsing and logging results if logging is
// active.
std::unique_ptr<autofill::PasswordForm> ParseFormAndMakeLogging(
......@@ -276,9 +269,8 @@ class NewPasswordFormManager : public PasswordFormManagerInterface,
// and |not_best_matches_|).
std::vector<const autofill::PasswordForm*> GetAllMatches() const;
// Save/update |pending_credentials_| to the password store. If |old_password|
// is provided, then the corresponding credentials are updated too.
void SavePendingToStore(bool update, const base::string16& old_password);
// Save/update |pending_credentials_| to the password store.
void SavePendingToStore(bool update);
// The client which implements embedder-specific PasswordManager operations.
PasswordManagerClient* client_;
......
......@@ -243,10 +243,11 @@ void PasswordFormManager::PermanentlyBlacklist() {
DCHECK(!client_->IsIncognito());
if (!new_blacklisted_) {
new_blacklisted_ = std::make_unique<PasswordForm>(observed_form_);
new_blacklisted_ = std::make_unique<PasswordForm>();
blacklisted_matches_.push_back(new_blacklisted_.get());
}
form_saver_->PermanentlyBlacklist(new_blacklisted_.get());
*new_blacklisted_ = form_saver_->PermanentlyBlacklist(
PasswordStore::FormDigest(observed_form_));
}
bool PasswordFormManager::IsNewLogin() const {
......@@ -1035,19 +1036,26 @@ std::vector<PasswordForm> PasswordFormManager::FindOtherCredentialsToUpdate()
}
void PasswordFormManager::SavePendingToStore(bool update) {
std::vector<const autofill::PasswordForm*> matches;
for (const auto& match : best_matches_)
matches.push_back(match.second);
matches.insert(matches.end(), not_best_matches_.begin(),
not_best_matches_.end());
if (HasGeneratedPassword()) {
generation_state_->CommitGeneratedPassword(pending_credentials_,
best_matches_, nullptr);
generation_state_->CommitGeneratedPassword(pending_credentials_, matches,
base::string16());
} else if (update) {
std::vector<PasswordForm> credentials_to_update =
FindOtherCredentialsToUpdate();
form_saver_->Update(pending_credentials_, best_matches_,
&credentials_to_update, nullptr);
base::string16 old_password;
if (!pending_credentials_.IsFederatedCredential()) {
auto updated_password_it =
best_matches_.find(pending_credentials_.username_value);
DCHECK(best_matches_.end() != updated_password_it);
old_password = updated_password_it->second->password_value;
}
form_saver_->Update(pending_credentials_, matches, old_password);
} else {
std::vector<const autofill::PasswordForm*> best_matches;
for (const auto& match : best_matches_)
best_matches.push_back(match.second);
form_saver_->Save(pending_credentials_, best_matches, base::string16());
form_saver_->Save(pending_credentials_, matches, base::string16());
}
}
......
......@@ -29,9 +29,9 @@ void PasswordGenerationState::PresaveGeneratedPassword(PasswordForm generated) {
DCHECK(!generated.password_value.empty());
generated.date_created = clock_->Now();
if (presaved_) {
form_saver_->Update(generated, {} /* best_matches */,
nullptr /* credentials_to_update */,
&presaved_.value() /* old_primary_key */);
form_saver_->UpdateReplace(generated, {} /* matches */,
base::string16() /* old_password */,
presaved_.value() /* old_primary_key */);
} else {
form_saver_->Save(generated, {} /* matches */,
base::string16() /* old_password */);
......@@ -47,13 +47,13 @@ void PasswordGenerationState::PasswordNoLongerGenerated() {
void PasswordGenerationState::CommitGeneratedPassword(
PasswordForm generated,
const std::map<base::string16, const PasswordForm*>& best_matches,
const std::vector<PasswordForm>* credentials_to_update) {
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) {
DCHECK(presaved_);
generated.preferred = true;
generated.date_created = clock_->Now();
form_saver_->Update(generated, best_matches, credentials_to_update,
&presaved_.value() /* old_primary_key */);
form_saver_->UpdateReplace(generated, matches, old_password,
presaved_.value() /* old_primary_key */);
}
} // namespace password_manager
......@@ -38,17 +38,12 @@ class PasswordGenerationState {
// Signals that the user cancels password generation.
void PasswordNoLongerGenerated();
// Finish the generation flow by saving the final credential |generated| and
// leaving the generation state.
// |best_matches| constains possible passwords for the current site. They will
// be update according to the new preferred state.
// |credentials_to_update| are credentials for probably related domain that
// should be also updated.
// Finish the generation flow by saving the final credential |generated|.
// |matches| and |old_password| have the same meaning as in FormSaver.
void CommitGeneratedPassword(
autofill::PasswordForm generated,
const std::map<base::string16, const autofill::PasswordForm*>&
best_matches,
const std::vector<autofill::PasswordForm>* credentials_to_update);
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password);
#if defined(UNIT_TEST)
void set_clock(std::unique_ptr<base::Clock> clock) {
......
......@@ -44,6 +44,7 @@ PasswordForm CreateSavedPSL() {
form.action = GURL("https://login.example.org");
form.username_value = ASCIIToUTF16("old_username2");
form.password_value = ASCIIToUTF16("passw0rd");
form.is_public_suffix_match = true;
return form;
}
......@@ -157,7 +158,7 @@ TEST_F(PasswordGenerationStateTest, PresaveGeneratedPassword_ReplaceTwice) {
// credential (as new) results in replacing the presaved password with the
// pending one.
TEST_F(PasswordGenerationStateTest, PresaveGeneratedPassword_ThenSaveAsNew) {
PasswordForm generated = CreateGenerated();
const PasswordForm generated = CreateGenerated();
EXPECT_CALL(store(), AddLogin(_));
state().PresaveGeneratedPassword(generated);
......@@ -170,8 +171,8 @@ TEST_F(PasswordGenerationStateTest, PresaveGeneratedPassword_ThenSaveAsNew) {
generated_with_date.date_created = base::Time::FromTimeT(kTime);
EXPECT_CALL(store(), UpdateLoginWithPrimaryKey(generated_with_date,
FormHasUniqueKey(generated)));
state().CommitGeneratedPassword(pending, {} /* best_matches */,
nullptr /* credentials_to_update */);
state().CommitGeneratedPassword(pending, {} /* matches */,
base::string16() /* old_password */);
EXPECT_TRUE(state().HasGeneratedPassword());
}
......@@ -184,26 +185,50 @@ TEST_F(PasswordGenerationStateTest, PresaveGeneratedPassword_ThenUpdate) {
EXPECT_CALL(store(), AddLogin(_));
state().PresaveGeneratedPassword(generated);
PasswordForm pending = generated;
pending.username_value = ASCIIToUTF16("edited_username");
PasswordForm related_password = CreateSaved();
related_password.username_value = ASCIIToUTF16("username");
related_password.username_element = ASCIIToUTF16("username_field");
related_password.password_value = ASCIIToUTF16("old password");
PasswordForm old_saved = CreateSaved();
old_saved.preferred = false;
PasswordForm old_psl_saved = CreateSavedPSL();
old_psl_saved.password_value = pending.password_value;
std::vector<autofill::PasswordForm> credentials_to_update = {old_psl_saved};
PasswordForm generated_with_date = pending;
PasswordForm related_psl_password = CreateSavedPSL();
related_psl_password.username_value = ASCIIToUTF16("username");
related_psl_password.password_value = ASCIIToUTF16("old password");
PasswordForm unrelated_password = CreateSaved();
unrelated_password.preferred = true;
unrelated_password.username_value = ASCIIToUTF16("another username");
unrelated_password.password_value = ASCIIToUTF16("some password");
PasswordForm unrelated_psl_password = CreateSavedPSL();
unrelated_psl_password.preferred = true;
unrelated_psl_password.username_value = ASCIIToUTF16("another username");
unrelated_psl_password.password_value = ASCIIToUTF16("some password");
generated.username_value = ASCIIToUTF16("username");
PasswordForm generated_with_date = generated;
generated_with_date.date_created = base::Time::FromTimeT(kTime);
EXPECT_CALL(store(), UpdateLoginWithPrimaryKey(generated_with_date,
FormHasUniqueKey(generated)));
EXPECT_CALL(store(), UpdateLogin(old_saved));
EXPECT_CALL(store(), UpdateLogin(old_psl_saved));
EXPECT_CALL(store(),
UpdateLoginWithPrimaryKey(generated_with_date,
FormHasUniqueKey(CreateGenerated())));
PasswordForm related_password_expected = related_password;
related_password_expected.password_value = generated.password_value;
EXPECT_CALL(store(), UpdateLogin(related_password_expected));
PasswordForm related_psl_password_expected = related_psl_password;
related_psl_password_expected.password_value = generated.password_value;
EXPECT_CALL(store(), UpdateLogin(related_psl_password_expected));
PasswordForm unrelated_password_expected = unrelated_password;
unrelated_password_expected.preferred = false;
EXPECT_CALL(store(), UpdateLogin(unrelated_password_expected));
old_saved.preferred = true;
state().CommitGeneratedPassword(
pending, {{old_saved.username_value, &old_saved}} /* best_matches */,
&credentials_to_update);
generated,
{&related_password, &related_psl_password, &unrelated_password,
&unrelated_psl_password} /* matches */,
ASCIIToUTF16("old password"));
EXPECT_TRUE(state().HasGeneratedPassword());
}
......
......@@ -6,6 +6,11 @@
namespace password_manager {
autofill::PasswordForm StubFormSaver::PermanentlyBlacklist(
PasswordStore::FormDigest digest) {
return autofill::PasswordForm();
}
std::unique_ptr<FormSaver> StubFormSaver::Clone() {
return nullptr;
}
......
......@@ -18,15 +18,18 @@ class StubFormSaver : public FormSaver {
~StubFormSaver() override = default;
// FormSaver:
void PermanentlyBlacklist(autofill::PasswordForm* observed) override {}
void Save(const autofill::PasswordForm& pending,
autofill::PasswordForm PermanentlyBlacklist(
PasswordStore::FormDigest digest) override;
void Save(autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) override {}
void Update(const autofill::PasswordForm& pending,
const std::map<base::string16, const autofill::PasswordForm*>&
best_matches,
const std::vector<autofill::PasswordForm>* credentials_to_update,
const autofill::PasswordForm* old_primary_key) override {}
void Update(autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) override {}
void UpdateReplace(autofill::PasswordForm pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password,
const autofill::PasswordForm& old_unique_key) override {}
void Remove(const autofill::PasswordForm& form) override {}
std::unique_ptr<FormSaver> Clone() override;
......
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