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 096257b8d1a3114a819949087cb7350fd5c5c466..ad2defff3a948e8cae3461060a1c11becb8f624c 100644 |
--- a/components/password_manager/core/browser/password_form_manager.cc |
+++ b/components/password_manager/core/browser/password_form_manager.cc |
@@ -7,6 +7,7 @@ |
#include <algorithm> |
#include <set> |
+#include "base/command_line.h" |
#include "base/metrics/histogram.h" |
#include "base/metrics/user_metrics.h" |
#include "base/strings/string_split.h" |
@@ -15,6 +16,7 @@ |
#include "components/autofill/core/browser/autofill_manager.h" |
#include "components/autofill/core/browser/form_structure.h" |
#include "components/autofill/core/browser/validation.h" |
+#include "components/autofill/core/common/autofill_switches.h" |
#include "components/autofill/core/common/password_form.h" |
#include "components/password_manager/core/browser/browser_save_password_progress_logger.h" |
#include "components/password_manager/core/browser/password_manager.h" |
@@ -68,6 +70,11 @@ PasswordForm CopyAndModifySSLValidity(const PasswordForm& orig, |
return result; |
} |
+bool IsChangePasswordForm(const PasswordForm& candidate) { |
+ return !candidate.new_password_element.empty() && |
+ !candidate.password_element.empty(); |
+} |
+ |
} // namespace |
PasswordFormManager::PasswordFormManager( |
@@ -246,13 +253,15 @@ void PasswordFormManager::ProvisionallySave( |
base::string16 password_to_save(credentials.new_password_element.empty() ? |
credentials.password_value : credentials.new_password_value); |
+ bool is_username_certainly_correct = credentials.username_marked_by_site; |
+ |
// Make sure the important fields stay the same as the initially observed or |
// autofilled ones, as they may have changed if the user experienced a login |
// failure. |
// Look for these credentials in the list containing auto-fill entries. |
PasswordFormMap::const_iterator it = |
best_matches_.find(credentials.username_value); |
- if (it != best_matches_.end()) { |
+ if (!is_username_certainly_correct && it != best_matches_.end()) { |
// The user signed in with a login we autofilled. |
pending_credentials_ = *it->second; |
bool password_changed = |
@@ -303,6 +312,16 @@ void PasswordFormManager::ProvisionallySave( |
is_new_login_ = false; |
if (password_changed) |
user_action_ = kUserActionOverridePassword; |
+ |
+ // Check whether its a change-password form with matching credentials in |
+ // stored form. |
+ PasswordForm matching_form; |
+ if (IsChangePasswordForm(credentials) && |
+ HasMatchingCredentialsInStore(credentials, &matching_form)) { |
+ pending_credentials_ = matching_form; |
+ selected_username_ = matching_form.username_value; |
+ user_action_ = kUserActionOverridePassword; |
+ } |
} |
} else if (action == ALLOW_OTHER_POSSIBLE_USERNAMES && |
UpdatePendingCredentialsIfOtherPossibleUsername( |
@@ -376,19 +395,6 @@ void PasswordFormManager::FetchMatchingLoginsFromPasswordStore( |
logger->LogMessage(Logger::STRING_FETCH_LOGINS_METHOD); |
} |
- // Do not autofill on sign-up or change password forms (until we have some |
- // working change password functionality). |
- if (!observed_form_.new_password_element.empty()) { |
- if (logger) |
- logger->LogMessage(Logger::STRING_FORM_NOT_AUTOFILLED); |
- client_->AutofillResultsComputed(); |
- // There is no point in looking for the credentials in the store when they |
- // won't be autofilled, so pretend there were none. |
- std::vector<autofill::PasswordForm*> dummy_results; |
- OnGetPasswordStoreResults(dummy_results); |
- return; |
- } |
- |
PasswordStore* password_store = client_->GetPasswordStore(); |
if (!password_store) { |
if (logger) |
@@ -404,10 +410,8 @@ bool PasswordFormManager::HasCompletedMatching() const { |
} |
bool PasswordFormManager::IsIgnorableChangePasswordForm() const { |
- bool is_change_password_form = !observed_form_.new_password_element.empty() && |
- !observed_form_.password_element.empty(); |
bool is_username_certainly_correct = observed_form_.username_marked_by_site; |
- return is_change_password_form && !is_username_certainly_correct; |
+ return IsChangePasswordForm(observed_form_) && !is_username_certainly_correct; |
} |
void PasswordFormManager::OnRequestDone( |
@@ -551,8 +555,13 @@ void PasswordFormManager::ProcessFrame( |
manager_action_ = kManagerActionNone; |
else |
manager_action_ = kManagerActionAutofilled; |
- password_manager_->Autofill(driver.get(), observed_form_, best_matches_, |
- *preferred_match_, wait_for_username); |
+ |
+ // Do not autofill on sign-up or change password forms (until we have some |
+ // working change password functionality). |
+ if (observed_form_.new_password_element.empty()) { |
+ password_manager_->Autofill(driver.get(), observed_form_, best_matches_, |
+ *preferred_match_, wait_for_username); |
+ } |
} |
void PasswordFormManager::OnGetPasswordStoreResults( |
@@ -868,4 +877,25 @@ void PasswordFormManager::SubmitFailed() { |
LogPasswordGenerationSubmissionEvent(PASSWORD_SUBMISSION_FAILED); |
} |
+bool PasswordFormManager::HasMatchingCredentialsInStore( |
+ const autofill::PasswordForm& candidate, |
+ autofill::PasswordForm* matching_form) const { |
+ bool match_found = false; |
+ for (const auto& match : best_matches_) { |
+ // Make sure the username, password and origin signon realm matches to |
+ // ensure that the candidate form is one available in the store. |
+ if (match.second->username_value == candidate.username_value && |
+ match.second->password_value == candidate.password_value && |
+ match.second->original_signon_realm == |
+ candidate.original_signon_realm) { |
+ if (matching_form) |
+ *matching_form = *(match.second); |
+ match_found = true; |
+ break; |
+ } |
+ } |
+ |
+ return match_found; |
+} |
+ |
} // namespace password_manager |