Commit 1f1d9bb9 authored by Mohamed Amir Yosef's avatar Mohamed Amir Yosef Committed by Commit Bot

[Passwords] Properly update password in both stores

This CL implements the agreed upon proposal in this doc
https://docs.google.com/document/d/1ZJnlpeqdhd_a-ypovOmHLrIPYbbdlK8h3OIggGuj5G4/edit?usp=sharing

By making sure the following fields are preserved when updating password
in MultiStorePasswordSaveManager

date_created
date_synced
times_used
moving_blocked_for_list

times_used is incremented upon update.

Bug: 1012203
Change-Id: Ife4731381f317efddab032fe416d835c0ec86228
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2257932
Commit-Queue: Mohamed Amir Yosef <mamir@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781290}
parent c0fa809b
...@@ -94,6 +94,20 @@ PendingCredentialsState ResolvePendingCredentialsStates( ...@@ -94,6 +94,20 @@ PendingCredentialsState ResolvePendingCredentialsStates(
return PendingCredentialsState::NONE; return PendingCredentialsState::NONE;
} }
// Returns a PasswordForm that has all fields taken from |update| except
// date_created, date_synced, times_used and moving_blocked_for_list that are
// taken from |original_form|.
PasswordForm UpdateFormPreservingDifferentFieldsAcrossStores(
const PasswordForm& original_form,
const PasswordForm& update) {
PasswordForm result(update);
result.date_created = original_form.date_created;
result.date_synced = original_form.date_synced;
result.times_used = original_form.times_used;
result.moving_blocked_for_list = original_form.moving_blocked_for_list;
return result;
}
} // namespace } // namespace
MultiStorePasswordSaveManager::MultiStorePasswordSaveManager( MultiStorePasswordSaveManager::MultiStorePasswordSaveManager(
...@@ -152,11 +166,18 @@ void MultiStorePasswordSaveManager::SavePendingToStoreImpl( ...@@ -152,11 +166,18 @@ void MultiStorePasswordSaveManager::SavePendingToStoreImpl(
case PendingCredentialsState::EQUAL_TO_SAVED_MATCH: { case PendingCredentialsState::EQUAL_TO_SAVED_MATCH: {
// If the submitted credentials exists in both stores, // If the submitted credentials exists in both stores,
// |pending_credentials_| might be from the account store (and thus not // |pending_credentials_| might be from the account store (and thus not
// have a moving_blocked_for_list). We need to preserve any existing list, // have a moving_blocked_for_list). We need to preserve any existing list.
// so explicitly copy it over from the profile store match. // Same applies for other fields. Check the comment on
PasswordForm form_to_update(pending_credentials_); // UpdateFormPreservingDifferentFieldsAcrossStores().
form_to_update.moving_blocked_for_list = PasswordForm form_to_update =
states.similar_saved_form_from_profile_store->moving_blocked_for_list; UpdateFormPreservingDifferentFieldsAcrossStores(
*states.similar_saved_form_from_profile_store,
pending_credentials_);
// For other cases, |pending_credentials_.times_used| is updated in
// UpdateMetadataForUsage() invoked from UploadVotesAndMetrics().
// UpdateFormPreservingDifferentFieldsAcrossStores() preserved the
// original times_used, and hence we should increment it here.
form_to_update.times_used++;
form_saver_->Update(form_to_update, profile_matches, form_saver_->Update(form_to_update, profile_matches,
old_profile_password); old_profile_password);
} break; } break;
...@@ -179,10 +200,18 @@ void MultiStorePasswordSaveManager::SavePendingToStoreImpl( ...@@ -179,10 +200,18 @@ void MultiStorePasswordSaveManager::SavePendingToStoreImpl(
case PendingCredentialsState::EQUAL_TO_SAVED_MATCH: { case PendingCredentialsState::EQUAL_TO_SAVED_MATCH: {
// If the submitted credentials exists in both stores, // If the submitted credentials exists in both stores,
// .|pending_credentials_| might be from the profile store (and thus // .|pending_credentials_| might be from the profile store (and thus
// has a moving_blocked_for_list). We need to clear it before storing to // has a moving_blocked_for_list). We need to preserve any existing
// the account store. // values. Same applies for other fields. Check the comment on
PasswordForm form_to_update(pending_credentials_); // UpdateFormPreservingDifferentFieldsAcrossStores().
form_to_update.moving_blocked_for_list.clear(); PasswordForm form_to_update =
UpdateFormPreservingDifferentFieldsAcrossStores(
*states.similar_saved_form_from_account_store,
pending_credentials_);
// For other cases, |pending_credentials_.times_used| is updated in
// UpdateMetadataForUsage() invoked from UploadVotesAndMetrics().
// UpdateFormPreservingDifferentFieldsAcrossStores() preserved the
// original times_used, and hence we should increment it here.
form_to_update.times_used++;
account_store_form_saver_->Update(form_to_update, account_matches, account_store_form_saver_->Update(form_to_update, account_matches,
old_account_password); old_account_password);
} break; } break;
......
...@@ -406,15 +406,26 @@ TEST_F(MultiStorePasswordSaveManagerTest, UpdateInBothStores) { ...@@ -406,15 +406,26 @@ TEST_F(MultiStorePasswordSaveManagerTest, UpdateInBothStores) {
TEST_F(MultiStorePasswordSaveManagerTest, AutomaticSaveInBothStores) { TEST_F(MultiStorePasswordSaveManagerTest, AutomaticSaveInBothStores) {
SetAccountStoreEnabled(/*is_enabled=*/true); SetAccountStoreEnabled(/*is_enabled=*/true);
// Set different values for the fields that should be preserved per store
// (namely: date_created, date_synced, times_used, moving_blocked_for_list)
PasswordForm saved_match_in_profile_store(saved_match_); PasswordForm saved_match_in_profile_store(saved_match_);
saved_match_in_profile_store.username_value = saved_match_in_profile_store.username_value =
parsed_submitted_form_.username_value; parsed_submitted_form_.username_value;
saved_match_in_profile_store.password_value = saved_match_in_profile_store.password_value =
parsed_submitted_form_.password_value; parsed_submitted_form_.password_value;
saved_match_in_profile_store.in_store = PasswordForm::Store::kProfileStore; saved_match_in_profile_store.in_store = PasswordForm::Store::kProfileStore;
saved_match_in_profile_store.date_created =
base::Time::Now() - base::TimeDelta::FromDays(10);
saved_match_in_profile_store.times_used = 10;
saved_match_in_profile_store.moving_blocked_for_list.push_back(
autofill::GaiaIdHash::FromGaiaId("email@gmail.com"));
PasswordForm saved_match_in_account_store(saved_match_in_profile_store); PasswordForm saved_match_in_account_store(saved_match_in_profile_store);
saved_match_in_account_store.in_store = PasswordForm::Store::kAccountStore; saved_match_in_account_store.in_store = PasswordForm::Store::kAccountStore;
saved_match_in_account_store.date_created = base::Time::Now();
saved_match_in_account_store.date_synced = base::Time::Now();
saved_match_in_account_store.times_used = 5;
saved_match_in_account_store.moving_blocked_for_list.clear();
SetNonFederatedAndNotifyFetchCompleted( SetNonFederatedAndNotifyFetchCompleted(
{&saved_match_in_profile_store, &saved_match_in_account_store}); {&saved_match_in_profile_store, &saved_match_in_account_store});
...@@ -430,6 +441,7 @@ TEST_F(MultiStorePasswordSaveManagerTest, AutomaticSaveInBothStores) { ...@@ -430,6 +441,7 @@ TEST_F(MultiStorePasswordSaveManagerTest, AutomaticSaveInBothStores) {
// We still should update both credentials to update the |date_last_used| and // We still should update both credentials to update the |date_last_used| and
// |times_used|. Note that |in_store| is irrelevant since it's not persisted. // |times_used|. Note that |in_store| is irrelevant since it's not persisted.
// All other fields should be preserved.
PasswordForm expected_profile_update_form(saved_match_in_profile_store); PasswordForm expected_profile_update_form(saved_match_in_profile_store);
expected_profile_update_form.times_used++; expected_profile_update_form.times_used++;
expected_profile_update_form.date_last_used = expected_profile_update_form.date_last_used =
......
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