diff options
-rw-r--r-- | chrome/browser/password_manager/password_manager.cc | 17 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_manager_unittest.cc | 57 |
2 files changed, 63 insertions, 11 deletions
diff --git a/chrome/browser/password_manager/password_manager.cc b/chrome/browser/password_manager/password_manager.cc index 39629e9..f6834ac 100644 --- a/chrome/browser/password_manager/password_manager.cc +++ b/chrome/browser/password_manager/password_manager.cc @@ -312,17 +312,12 @@ void PasswordManager::OnPasswordFormsRendered( DCHECK(IsSavingEnabled()); - // First, check for a failed login attempt. - for (std::vector<PasswordForm>::const_iterator iter = visible_forms.begin(); - iter != visible_forms.end(); ++iter) { - if (provisional_save_manager_->DoesManage( - *iter, PasswordFormManager::ACTION_MATCH_REQUIRED)) { - // The form trying to be saved has immediately re-appeared. Assume login - // failure and abort this save, by clearing provisional_save_manager_. - provisional_save_manager_->SubmitFailed(); - provisional_save_manager_.reset(); - return; - } + // We now assume that if there is at least one visible password form + // that means that the previous login attempt failed. + if (!visible_forms.empty()) { + provisional_save_manager_->SubmitFailed(); + provisional_save_manager_.reset(); + return; } if (!provisional_save_manager_->HasValidPasswordForm()) { diff --git a/chrome/browser/password_manager/password_manager_unittest.cc b/chrome/browser/password_manager/password_manager_unittest.cc index cecba4f..cebfc2e 100644 --- a/chrome/browser/password_manager/password_manager_unittest.cc +++ b/chrome/browser/password_manager/password_manager_unittest.cc @@ -108,6 +108,37 @@ class PasswordManagerTest : public ChromeRenderViewHostTestHarness { return form; } + // Reproduction of the form present on twitter's login page. + PasswordForm MakeTwitterLoginForm() { + PasswordForm form; + form.origin = GURL("https://twitter.com/"); + form.action = GURL("https://twitter.com/sessions"); + form.username_element = ASCIIToUTF16("Email"); + form.password_element = ASCIIToUTF16("Passwd"); + form.username_value = ASCIIToUTF16("twitter"); + form.password_value = ASCIIToUTF16("password"); + form.password_autocomplete_set = true; + form.submit_element = ASCIIToUTF16("signIn"); + form.signon_realm = "https://twitter.com"; + return form; + } + + // Reproduction of the form present on twitter's failed login page. + PasswordForm MakeTwitterFailedLoginForm() { + PasswordForm form; + form.origin = + GURL("https://twitter.com/login/error?redirect_after_login"); + form.action = GURL("https://twitter.com/sessions"); + form.username_element = ASCIIToUTF16("EmailField"); + form.password_element = ASCIIToUTF16("PasswdField"); + form.username_value = ASCIIToUTF16("twitter"); + form.password_value = ASCIIToUTF16("password"); + form.password_autocomplete_set = true; + form.submit_element = ASCIIToUTF16("signIn"); + form.signon_realm = "https://twitter.com"; + return form; + } + bool FormsAreEqual(const content::PasswordForm& lhs, const content::PasswordForm& rhs) { if (lhs.origin != rhs.origin) @@ -536,3 +567,29 @@ TEST_F(PasswordManagerTest, SubmissionCallbackTest) { OnPasswordFormSubmitted(form); EXPECT_TRUE(FormsAreEqual(form, submitted_form_)); } + +TEST_F(PasswordManagerTest, PasswordFormReappearance) { + // Test the heuristic to know if a password form reappears. + // We assume that if we send our credentials and there + // is at least one visible password form in the next page that + // means that our previous login attempt failed. + std::vector<PasswordForm*> result; // Empty password store. + EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(0); + EXPECT_CALL(*store_.get(), GetLogins(_, _)) + .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); + std::vector<PasswordForm> observed; + PasswordForm login_form(MakeTwitterLoginForm()); + observed.push_back(login_form); + manager()->OnPasswordFormsParsed(observed); // The initial load. + manager()->OnPasswordFormsRendered(observed); // The initial layout. + + manager()->ProvisionallySavePassword(login_form); + + PasswordForm failed_login_form(MakeTwitterFailedLoginForm()); + observed.clear(); + observed.push_back(failed_login_form); + // A PasswordForm appears, and is visible in the layout: + // No expected calls to the PasswordStore... + manager()->OnPasswordFormsParsed(observed); + manager()->OnPasswordFormsRendered(observed); +} |