Index: components/password_manager/core/browser/password_form_manager.cc |
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc |
index 5d0ba2afdec63b1dbbf3c58f65d1d2c62669685e..67ea855a3a570a3c850e17d85bad6a83154bb335 100644 |
--- a/components/password_manager/core/browser/password_form_manager.cc |
+++ b/components/password_manager/core/browser/password_form_manager.cc |
@@ -294,6 +294,16 @@ void PasswordFormManager::Save() { |
UpdateLogin(); |
} |
+void PasswordFormManager::Update( |
+ const autofill::PasswordForm& credentials_to_update) { |
+ base::string16 password_to_save = pending_credentials_.password_value; |
+ pending_credentials_ = credentials_to_update; |
+ pending_credentials_.password_value = password_to_save; |
+ pending_credentials_.preferred = true; |
+ is_new_login_ = false; |
+ UpdateLogin(); |
+} |
+ |
void PasswordFormManager::FetchMatchingLoginsFromPasswordStore( |
PasswordStore::AuthorizationPromptPolicy prompt_policy) { |
DCHECK_EQ(state_, PRE_MATCHING_PHASE); |
@@ -325,7 +335,8 @@ void PasswordFormManager::SetSubmittedForm(const autofill::PasswordForm& form) { |
is_ignorable_change_password_form_ = |
is_change_password_form && !form.username_marked_by_site && |
!DoesUsenameAndPasswordMatchCredentials( |
- form.username_value, form.password_value, best_matches_); |
+ form.username_value, form.password_value, best_matches_) && |
+ !client_->IsUpdatePasswordUIEnabled(); |
bool is_signup_form = |
!form.new_password_value.empty() && form.password_value.empty(); |
bool no_username = form.username_element.empty(); |
@@ -866,6 +877,19 @@ void PasswordFormManager::CreatePendingCredentials() { |
// credential. |
selected_username_ = provisionally_saved_form_->username_value; |
is_new_login_ = false; |
+ } else if (client_->IsUpdatePasswordUIEnabled() && !best_matches_.empty() && |
+ provisionally_saved_form_ |
+ ->IsPossibleChangePasswordFormWithoutUsername()) { |
+ PasswordForm* best_update_match = FindBestMatchForUpdatePassword( |
+ provisionally_saved_form_->password_value); |
+ |
+ if (best_update_match) |
+ pending_credentials_ = *best_update_match; |
+ else |
+ pending_credentials_.origin = provisionally_saved_form_->origin; |
+ is_new_login_ = false; |
+ // We don't care about |pending_credentials_| if we didn't find the best |
+ // match, since the user will select the correct one. |
} else { |
// User typed in a new, unknown username. |
user_action_ = kUserActionOverrideUsernameAndPassword; |
@@ -971,6 +995,31 @@ int PasswordFormManager::ScoreResult(const PasswordForm& candidate) const { |
return score; |
} |
+PasswordForm* PasswordFormManager::FindBestMatchForUpdatePassword( |
+ const base::string16& password) const { |
+ if (best_matches_.size() == 1) { |
+ // In case when the user has only one credential, consider it the same as |
+ // is being saved. |
+ return best_matches_.begin()->second; |
+ } |
+ if (password.empty()) |
+ return nullptr; |
+ |
+ PasswordFormMap::const_iterator best_password_match_it = best_matches_.end(); |
+ for (auto it = best_matches_.begin(); it != best_matches_.end(); ++it) { |
+ if (it->second->password_value == password) { |
+ if (best_password_match_it != best_matches_.end()) { |
+ // Found a second credential with the same password, do nothing. |
+ return nullptr; |
+ } |
+ best_password_match_it = it; |
+ } |
+ } |
+ return best_password_match_it == best_matches_.end() |
+ ? nullptr |
+ : best_password_match_it->second; |
+} |
+ |
void PasswordFormManager::SubmitPassed() { |
submit_result_ = kSubmitResultPassed; |
if (has_generated_password_) |