Commit 5d95f6c7 authored by Mohamed Amir Yosef's avatar Mohamed Amir Yosef Committed by Commit Bot

[Passwords] Introduce PasswordSaveManager.BlockMovingToAccountStoreFor()

This method marks the currently submitted credentials to be not movable
to the account store of the user with the passed GaiaIdHash.

Bug: 1032992
Change-Id: Ic292de0adae08e0d5de95c09fca381603329c1a7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2152588
Commit-Queue: Mohamed Amir Yosef <mamir@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#760533}
parent 7b60ef2f
......@@ -4,6 +4,7 @@
#include "components/password_manager/core/browser/multi_store_password_save_manager.h"
#include "components/autofill/core/common/gaia_id_hash.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"
......@@ -147,6 +148,9 @@ void MultiStorePasswordSaveManager::SavePendingToStoreImpl(
break;
case PendingCredentialsState::UPDATE:
case PendingCredentialsState::EQUAL_TO_SAVED_MATCH:
// TODO(crbug.com/1012203): Make to preserve the moving_blocked_for_list
// in the profile store in case |pending_credentials_| is coming from the
// account store.
form_saver_->Update(pending_credentials_, profile_matches,
old_profile_password);
break;
......@@ -246,6 +250,36 @@ void MultiStorePasswordSaveManager::MoveCredentialsToAccountStore() {
}
}
void MultiStorePasswordSaveManager::BlockMovingToAccountStoreFor(
const autofill::GaiaIdHash& gaia_id_hash) {
// TODO(crbug.com/1032992): This doesn't work if moving is offered upon update
// prompts.
// We offer moving credentials to the account store only upon successful
// login. This entails that the credentials must exist in the profile store.
PendingCredentialsStates states = ComputePendingCredentialsStates(
pending_credentials_, form_fetcher_->GetAllRelevantMatches());
DCHECK(states.similar_saved_form_from_profile_store);
DCHECK_EQ(PendingCredentialsState::EQUAL_TO_SAVED_MATCH,
states.profile_store_state);
// If the submitted credentials exists in both stores, .|pending_credentials_|
// might be from the account store (and thus not have a
// moving_blocked_for_list). We need to preserve any existing list, so
// explicitly copy it over from the profile store match.
PasswordForm form_to_block(pending_credentials_);
form_to_block.moving_blocked_for_list =
states.similar_saved_form_from_profile_store->moving_blocked_for_list;
form_to_block.moving_blocked_for_list.push_back(gaia_id_hash);
// No need to pass matches to Update(). It's only used for post processing
// (e.g. updating the password for other credentials with the same
// old password).
form_saver_->Update(form_to_block, /*matches=*/{},
form_to_block.password_value);
}
std::pair<const PasswordForm*, PendingCredentialsState>
MultiStorePasswordSaveManager::FindSimilarSavedFormAndComputeState(
const PasswordForm& parsed_submitted_form) const {
......
......@@ -35,6 +35,9 @@ class MultiStorePasswordSaveManager : public PasswordSaveManagerImpl {
void MoveCredentialsToAccountStore() override;
void BlockMovingToAccountStoreFor(
const autofill::GaiaIdHash& gaia_id_hash) override;
protected:
void SavePendingToStoreImpl(
const autofill::PasswordForm& parsed_submitted_form) override;
......
......@@ -813,4 +813,67 @@ TEST_F(MultiStorePasswordSaveManagerTest,
password_save_manager()->MoveCredentialsToAccountStore();
}
TEST_F(MultiStorePasswordSaveManagerTest, BlockMovingWhenExistsInProfileStore) {
autofill::GaiaIdHash user1_id_hash =
autofill::GaiaIdHash::FromGaiaId("user1@gmail.com");
autofill::GaiaIdHash user2_id_hash =
autofill::GaiaIdHash::FromGaiaId("user2@gmail.com");
PasswordForm profile_saved_match(saved_match_);
profile_saved_match.username_value = parsed_submitted_form_.username_value;
profile_saved_match.password_value = parsed_submitted_form_.password_value;
profile_saved_match.in_store = PasswordForm::Store::kProfileStore;
profile_saved_match.moving_blocked_for_list = {user1_id_hash};
SetNonFederatedAndNotifyFetchCompleted({&profile_saved_match});
password_save_manager()->CreatePendingCredentials(
parsed_submitted_form_, observed_form_, submitted_form_,
/*is_http_auth=*/false,
/*is_credential_api_save=*/false);
PasswordForm profile_updated_match(profile_saved_match);
profile_updated_match.date_last_used =
password_save_manager()->GetPendingCredentials().date_last_used;
profile_updated_match.moving_blocked_for_list.push_back(user2_id_hash);
EXPECT_CALL(*mock_account_form_saver(), Update).Times(0);
EXPECT_CALL(*mock_profile_form_saver(), Update(profile_updated_match, _, _));
password_save_manager()->BlockMovingToAccountStoreFor(user2_id_hash);
}
TEST_F(MultiStorePasswordSaveManagerTest, BlockMovingWhenExistsInBothStores) {
autofill::GaiaIdHash user1_id_hash =
autofill::GaiaIdHash::FromGaiaId("user1@gmail.com");
autofill::GaiaIdHash user2_id_hash =
autofill::GaiaIdHash::FromGaiaId("user2@gmail.com");
PasswordForm account_saved_match(saved_match_);
account_saved_match.username_value = parsed_submitted_form_.username_value;
account_saved_match.password_value = parsed_submitted_form_.password_value;
account_saved_match.in_store = PasswordForm::Store::kAccountStore;
PasswordForm profile_saved_match(account_saved_match);
profile_saved_match.in_store = PasswordForm::Store::kProfileStore;
profile_saved_match.moving_blocked_for_list = {user1_id_hash};
SetNonFederatedAndNotifyFetchCompleted({&profile_saved_match});
password_save_manager()->CreatePendingCredentials(
parsed_submitted_form_, observed_form_, submitted_form_,
/*is_http_auth=*/false,
/*is_credential_api_save=*/false);
PasswordForm profile_updated_match(profile_saved_match);
profile_updated_match.date_last_used =
password_save_manager()->GetPendingCredentials().date_last_used;
profile_updated_match.moving_blocked_for_list.push_back(user2_id_hash);
EXPECT_CALL(*mock_account_form_saver(), Update).Times(0);
EXPECT_CALL(*mock_profile_form_saver(), Update(profile_updated_match, _, _));
password_save_manager()->BlockMovingToAccountStoreFor(user2_id_hash);
}
} // namespace password_manager
......@@ -2359,6 +2359,7 @@ class MockPasswordSaveManager : public PasswordSaveManager {
return std::make_unique<MockPasswordSaveManager>();
}
MOCK_METHOD0(MoveCredentialsToAccountStore, void());
MOCK_METHOD1(BlockMovingToAccountStoreFor, void(const autofill::GaiaIdHash&));
private:
DISALLOW_COPY_AND_ASSIGN(MockPasswordSaveManager);
......
......@@ -11,6 +11,7 @@
namespace autofill {
struct FormData;
struct PasswordForm;
class GaiaIdHash;
} // namespace autofill
namespace password_manager {
......@@ -82,6 +83,12 @@ class PasswordSaveManager {
// the profile store to the account store.
virtual void MoveCredentialsToAccountStore() = 0;
// Adds the |gaia_id_hash| to the |moving_blocked_for_list| of the
// PasswordForm returned by GetPendingCredentials() and stores it in the
// profile store. This is relevant only for account store users.
virtual void BlockMovingToAccountStoreFor(
const autofill::GaiaIdHash& gaia_id_hash) = 0;
virtual bool IsNewLogin() const = 0;
virtual bool IsPasswordUpdate() const = 0;
virtual bool HasGeneratedPassword() const = 0;
......
......@@ -318,6 +318,12 @@ void PasswordSaveManagerImpl::MoveCredentialsToAccountStore() {
NOTREACHED();
}
void PasswordSaveManagerImpl::BlockMovingToAccountStoreFor(
const autofill::GaiaIdHash& gaia_id_hash) {
// Moving credentials is only supported in MultiStorePasswordSaveManager.
NOTREACHED();
}
bool PasswordSaveManagerImpl::IsNewLogin() const {
return pending_credentials_state_ == PendingCredentialsState::NEW_LOGIN ||
pending_credentials_state_ == PendingCredentialsState::AUTOMATIC_SAVE;
......
......@@ -73,6 +73,9 @@ class PasswordSaveManagerImpl : public PasswordSaveManager {
void MoveCredentialsToAccountStore() override;
void BlockMovingToAccountStoreFor(
const autofill::GaiaIdHash& gaia_id_hash) override;
bool IsNewLogin() const override;
bool IsPasswordUpdate() const override;
bool HasGeneratedPassword() const 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