Commit 8de693d4 authored by Mohamed Amir Yosef's avatar Mohamed Amir Yosef Committed by Commit Bot

[Passwords] Introduce Multi-Store Password Save Manager

This class encapsulates the logic for updating/saving for
Butter for Passwords efforts.

Change-Id: I03ac490ad272576f4613df172a333b2c97a01919
Bug: 1012203
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1876409Reviewed-by: default avatarVadym Doroshenko <dvadym@chromium.org>
Commit-Queue: Mohamed Amir Yosef <mamir@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719955}
parent 635a777e
......@@ -128,6 +128,8 @@ jumbo_static_library("browser") {
"manage_passwords_referrer.h",
"multi_store_form_fetcher.cc",
"multi_store_form_fetcher.h",
"multi_store_password_save_manager.cc",
"multi_store_password_save_manager.h",
"origin_credential_store.cc",
"origin_credential_store.h",
"password_autofill_manager.cc",
......@@ -543,6 +545,7 @@ source_set("unit_tests") {
"leak_detection_dialog_utils_unittest.cc",
"login_database_unittest.cc",
"multi_store_form_fetcher_unittest.cc",
"multi_store_password_save_manager_unittest.cc",
"origin_credential_store_unittest.cc",
"password_autofill_manager_unittest.cc",
"password_bubble_experiment_unittest.cc",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/password_manager/core/browser/multi_store_password_save_manager.h"
#include "components/password_manager/core/browser/form_fetcher.h"
#include "components/password_manager/core/browser/form_saver.h"
#include "components/password_manager/core/browser/form_saver_impl.h"
#include "components/password_manager/core/browser/password_form_metrics_recorder.h"
#include "components/password_manager/core/browser/password_generation_manager.h"
#include "components/password_manager/core/browser/password_manager_util.h"
using autofill::PasswordForm;
namespace password_manager {
MultiStorePasswordSaveManager::MultiStorePasswordSaveManager(
std::unique_ptr<FormSaver> profile_form_saver,
std::unique_ptr<FormSaver> account_form_saver)
: PasswordSaveManagerImpl(std::move(profile_form_saver)),
account_store_form_saver_(std::move(account_form_saver)) {}
MultiStorePasswordSaveManager::~MultiStorePasswordSaveManager() = default;
FormSaver* MultiStorePasswordSaveManager::GetFormSaverForGeneration() {
return IsAccountStoreActive() && account_store_form_saver_
? account_store_form_saver_.get()
: form_saver_.get();
}
void MultiStorePasswordSaveManager::SaveInternal(
const PasswordForm& pending,
const std::vector<const PasswordForm*>& matches,
const base::string16& old_password) {
switch (pending.in_store) {
case PasswordForm::Store::kAccountStore:
if (account_store_form_saver_ && IsAccountStoreActive())
account_store_form_saver_->Save(pending, matches, old_password);
break;
case PasswordForm::Store::kProfileStore:
form_saver_->Save(pending, matches, old_password);
break;
case PasswordForm::Store::kNotSet:
if (account_store_form_saver_ && IsAccountStoreActive())
account_store_form_saver_->Save(pending, matches, old_password);
else
form_saver_->Save(pending, matches, old_password);
break;
}
}
void MultiStorePasswordSaveManager::UpdateInternal(
const PasswordForm& pending,
const std::vector<const PasswordForm*>& matches,
const base::string16& old_password) {
// Try to update both stores anyway because if credentials don't exist, the
// update operation is no-op.
form_saver_->Update(pending, matches, old_password);
if (account_store_form_saver_ && IsAccountStoreActive()) {
account_store_form_saver_->Update(pending, matches, old_password);
}
}
bool MultiStorePasswordSaveManager::IsAccountStoreActive() {
return client_->GetPasswordSyncState() ==
password_manager::ACCOUNT_PASSWORDS_ACTIVE_NORMAL_ENCRYPTION;
}
} // namespace password_manager
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_MULTI_STORE_PASSWORD_SAVE_MANAGER_H_
#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_MULTI_STORE_PASSWORD_SAVE_MANAGER_H_
#include "base/macros.h"
#include "components/password_manager/core/browser/password_save_manager_impl.h"
namespace password_manager {
// This class encapsulates the logic for Save/Update credentials in the case
// when both a profile and account store exists. In case the account store isn't
// available (e.g. the user is Syncing), it should introduce no behavioral
// difference to the PasswordSaveManagerImpl base class. After the launch of the
// account store feature, this class should be merged with
// PasswordSaveManagerImpl.
// TODO(crbug.com/1012203): It currently has the following limitations:
// 1. When a PSL matched entry exists, a non-PSL matched entry is silently added
// to the correpsonding store. However, if a PSL matched entry exists in both
// stores, it's only added to the account store.
// 2. There is no API to set the destination store from the PasswordFormManager.
// This will be eventually required in order to communicate the user choice
// from the UI.
// 3. (Un)Blacklisting is done always against the profile store.
class MultiStorePasswordSaveManager : public PasswordSaveManagerImpl {
public:
MultiStorePasswordSaveManager(std::unique_ptr<FormSaver> profile_form_saver,
std::unique_ptr<FormSaver> account_form_saver);
~MultiStorePasswordSaveManager() override;
void SaveInternal(const autofill::PasswordForm& pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) override;
void UpdateInternal(const autofill::PasswordForm& pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password) override;
protected:
FormSaver* GetFormSaverForGeneration() override;
private:
bool IsAccountStoreActive();
const std::unique_ptr<FormSaver> account_store_form_saver_;
DISALLOW_COPY_AND_ASSIGN(MultiStorePasswordSaveManager);
};
} // namespace password_manager
#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_MULTI_STORE_PASSWORD_SAVE_MANAGER_H_
......@@ -294,7 +294,7 @@ void PasswordSaveManagerImpl::PresaveGeneratedPassword(
generation_manager_->PresaveGeneratedPassword(
std::move(parsed_form), form_fetcher_->GetAllRelevantMatches(),
form_saver_.get());
GetFormSaverForGeneration());
}
void PasswordSaveManagerImpl::GeneratedPasswordAccepted(
......@@ -307,7 +307,7 @@ void PasswordSaveManagerImpl::GeneratedPasswordAccepted(
void PasswordSaveManagerImpl::PasswordNoLongerGenerated() {
DCHECK(generation_manager_);
generation_manager_->PasswordNoLongerGenerated(form_saver_.get());
generation_manager_->PasswordNoLongerGenerated(GetFormSaverForGeneration());
generation_manager_.reset();
votes_uploader_->set_has_generated_password(false);
......@@ -376,13 +376,13 @@ void PasswordSaveManagerImpl::SavePendingToStore(
if (HasGeneratedPassword()) {
generation_manager_->CommitGeneratedPassword(
pending_credentials_, form_fetcher_->GetAllRelevantMatches(),
old_password, form_saver_.get());
old_password, GetFormSaverForGeneration());
} else if (update) {
form_saver_->Update(pending_credentials_,
form_fetcher_->GetAllRelevantMatches(), old_password);
UpdateInternal(pending_credentials_, form_fetcher_->GetAllRelevantMatches(),
old_password);
} else {
form_saver_->Save(pending_credentials_,
form_fetcher_->GetAllRelevantMatches(), old_password);
SaveInternal(pending_credentials_, form_fetcher_->GetAllRelevantMatches(),
old_password);
}
}
......@@ -424,4 +424,23 @@ void PasswordSaveManagerImpl::ProcessUpdate(
}
}
FormSaver* PasswordSaveManagerImpl::GetFormSaverForGeneration() {
DCHECK(form_saver_);
return form_saver_.get();
}
void PasswordSaveManagerImpl::SaveInternal(
const PasswordForm& pending,
const std::vector<const PasswordForm*>& matches,
const base::string16& old_password) {
form_saver_->Save(pending, matches, old_password);
}
void PasswordSaveManagerImpl::UpdateInternal(
const PasswordForm& pending,
const std::vector<const PasswordForm*>& matches,
const base::string16& old_password) {
form_saver_->Update(pending, matches, old_password);
}
} // namespace password_manager
......@@ -67,6 +67,28 @@ class PasswordSaveManagerImpl : public PasswordSaveManager {
FormSaver* GetFormSaver() { return form_saver_.get(); }
#endif
protected:
// Returns the form_saver to be used for generated passwords. Subclasses will
// override this method to provide different logic for get the form saver.
virtual FormSaver* GetFormSaverForGeneration();
virtual void SaveInternal(
const autofill::PasswordForm& pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password);
virtual void UpdateInternal(
const autofill::PasswordForm& pending,
const std::vector<const autofill::PasswordForm*>& matches,
const base::string16& old_password);
// FormSaver instance used by |this| to all tasks related to storing
// credentials.
const std::unique_ptr<FormSaver> form_saver_;
// The client which implements embedder-specific PasswordManager operations.
PasswordManagerClient* client_;
private:
// Create pending credentials from provisionally saved form when this form
// represents credentials that were not previously saved.
......@@ -87,19 +109,12 @@ class PasswordSaveManagerImpl : public PasswordSaveManager {
void ProcessUpdate(const autofill::FormData& observed_form,
const autofill::PasswordForm& parsed_submitted_form);
// The client which implements embedder-specific PasswordManager operations.
PasswordManagerClient* client_;
// Handles the user flows related to the generation.
std::unique_ptr<PasswordGenerationManager> generation_manager_;
// FormFetcher instance which owns the login data from PasswordStore.
const FormFetcher* form_fetcher_;
// FormSaver instance used by |this| to all tasks related to storing
// credentials.
const std::unique_ptr<FormSaver> form_saver_;
// Stores updated credentials when the form was submitted but success is still
// unknown. This variable contains credentials that are ready to be written
// (saved or updated) to a password store. It is calculated based on
......
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