1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "components/password_manager/core/browser/password_manager.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/message_loop/message_loop.h" 11 #include "base/prefs/pref_registry_simple.h" 12 #include "base/prefs/pref_service.h" 13 #include "base/prefs/testing_pref_service.h" 14 #include "base/strings/string_util.h" 15 #include "base/strings/utf_string_conversions.h" 16 #include "components/password_manager/core/browser/mock_password_store.h" 17 #include "components/password_manager/core/browser/password_autofill_manager.h" 18 #include "components/password_manager/core/browser/password_manager_driver.h" 19 #include "components/password_manager/core/browser/password_store.h" 20 #include "components/password_manager/core/browser/stub_password_manager_client.h" 21 #include "components/password_manager/core/browser/stub_password_manager_driver.h" 22 #include "components/password_manager/core/common/password_manager_pref_names.h" 23 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gtest/include/gtest/gtest.h" 25 26 class PasswordGenerationManager; 27 28 using autofill::PasswordForm; 29 using base::ASCIIToUTF16; 30 using testing::_; 31 using testing::AnyNumber; 32 using testing::DoAll; 33 using testing::Exactly; 34 using testing::Return; 35 using testing::WithArg; 36 37 namespace autofill { 38 class AutofillManager; 39 } 40 41 namespace password_manager { 42 43 namespace { 44 45 class MockPasswordManagerClient : public StubPasswordManagerClient { 46 public: 47 MOCK_CONST_METHOD0(IsPasswordManagerEnabledForCurrentPage, bool()); 48 MOCK_CONST_METHOD2(IsSyncAccountCredential, 49 bool(const std::string&, const std::string&)); 50 MOCK_METHOD1(PromptUserToSavePasswordPtr, void(PasswordFormManager*)); 51 MOCK_METHOD1(AutomaticPasswordSavePtr, void(PasswordFormManager*)); 52 MOCK_METHOD0(GetPasswordStore, PasswordStore*()); 53 MOCK_METHOD0(GetPrefs, PrefService*()); 54 MOCK_METHOD0(GetDriver, PasswordManagerDriver*()); 55 56 // Workaround for scoped_ptr<> lacking a copy constructor. 57 virtual bool PromptUserToSavePassword( 58 scoped_ptr<PasswordFormManager> manager) OVERRIDE { 59 PromptUserToSavePasswordPtr(manager.release()); 60 return false; 61 } 62 virtual void AutomaticPasswordSave( 63 scoped_ptr<PasswordFormManager> manager) OVERRIDE { 64 AutomaticPasswordSavePtr(manager.release()); 65 } 66 }; 67 68 class MockPasswordManagerDriver : public StubPasswordManagerDriver { 69 public: 70 MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&)); 71 MOCK_METHOD0(GetPasswordManager, PasswordManager*()); 72 MOCK_METHOD0(GetPasswordAutofillManager, PasswordAutofillManager*()); 73 MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool()); 74 }; 75 76 ACTION_P(InvokeConsumer, forms) { arg0->OnGetPasswordStoreResults(forms); } 77 78 ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); } 79 80 class TestPasswordManager : public PasswordManager { 81 public: 82 explicit TestPasswordManager(PasswordManagerClient* client) 83 : PasswordManager(client) {} 84 virtual ~TestPasswordManager() {} 85 86 private: 87 DISALLOW_COPY_AND_ASSIGN(TestPasswordManager); 88 }; 89 90 } // namespace 91 92 class PasswordManagerTest : public testing::Test { 93 protected: 94 virtual void SetUp() { 95 prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerSavingEnabled, 96 true); 97 98 store_ = new MockPasswordStore; 99 EXPECT_CALL(*store_.get(), ReportMetrics(_)).Times(AnyNumber()); 100 CHECK(store_->Init(syncer::SyncableService::StartSyncFlare(), "")); 101 102 EXPECT_CALL(client_, IsPasswordManagerEnabledForCurrentPage()) 103 .WillRepeatedly(Return(true)); 104 EXPECT_CALL(client_, IsSyncAccountCredential(_, _)) 105 .WillRepeatedly(Return(false)); 106 EXPECT_CALL(client_, GetPasswordStore()) 107 .WillRepeatedly(Return(store_.get())); 108 EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_)); 109 EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_)); 110 111 manager_.reset(new TestPasswordManager(&client_)); 112 password_autofill_manager_.reset( 113 new PasswordAutofillManager(&client_, NULL)); 114 115 EXPECT_CALL(driver_, GetPasswordManager()) 116 .WillRepeatedly(Return(manager_.get())); 117 EXPECT_CALL(driver_, GetPasswordAutofillManager()) 118 .WillRepeatedly(Return(password_autofill_manager_.get())); 119 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors()) 120 .WillRepeatedly(Return(false)); 121 } 122 123 virtual void TearDown() { 124 store_->Shutdown(); 125 store_ = NULL; 126 } 127 128 PasswordForm MakeSimpleForm() { 129 PasswordForm form; 130 form.origin = GURL("http://www.google.com/a/LoginAuth"); 131 form.action = GURL("http://www.google.com/a/Login"); 132 form.username_element = ASCIIToUTF16("Email"); 133 form.password_element = ASCIIToUTF16("Passwd"); 134 form.username_value = ASCIIToUTF16("google"); 135 form.password_value = ASCIIToUTF16("password"); 136 // Default to true so we only need to add tests in autocomplete=off cases. 137 form.password_autocomplete_set = true; 138 form.submit_element = ASCIIToUTF16("signIn"); 139 form.signon_realm = "http://www.google.com"; 140 return form; 141 } 142 143 // Create a sign-up form that only has a new password field. 144 PasswordForm MakeFormWithOnlyNewPasswordField() { 145 PasswordForm form = MakeSimpleForm(); 146 form.new_password_element.swap(form.password_element); 147 form.new_password_value.swap(form.password_value); 148 return form; 149 } 150 151 // Reproduction of the form present on twitter's login page. 152 PasswordForm MakeTwitterLoginForm() { 153 PasswordForm form; 154 form.origin = GURL("https://twitter.com/"); 155 form.action = GURL("https://twitter.com/sessions"); 156 form.username_element = ASCIIToUTF16("Email"); 157 form.password_element = ASCIIToUTF16("Passwd"); 158 form.username_value = ASCIIToUTF16("twitter"); 159 form.password_value = ASCIIToUTF16("password"); 160 form.password_autocomplete_set = true; 161 form.submit_element = ASCIIToUTF16("signIn"); 162 form.signon_realm = "https://twitter.com"; 163 return form; 164 } 165 166 // Reproduction of the form present on twitter's failed login page. 167 PasswordForm MakeTwitterFailedLoginForm() { 168 PasswordForm form; 169 form.origin = GURL("https://twitter.com/login/error?redirect_after_login"); 170 form.action = GURL("https://twitter.com/sessions"); 171 form.username_element = ASCIIToUTF16("EmailField"); 172 form.password_element = ASCIIToUTF16("PasswdField"); 173 form.username_value = ASCIIToUTF16("twitter"); 174 form.password_value = ASCIIToUTF16("password"); 175 form.password_autocomplete_set = true; 176 form.submit_element = ASCIIToUTF16("signIn"); 177 form.signon_realm = "https://twitter.com"; 178 return form; 179 } 180 181 PasswordForm MakeSimpleFormWithOnlyPasswordField() { 182 PasswordForm form(MakeSimpleForm()); 183 form.username_element.clear(); 184 form.username_value.clear(); 185 return form; 186 } 187 188 bool FormsAreEqual(const autofill::PasswordForm& lhs, 189 const autofill::PasswordForm& rhs) { 190 if (lhs.origin != rhs.origin) 191 return false; 192 if (lhs.action != rhs.action) 193 return false; 194 if (lhs.username_element != rhs.username_element) 195 return false; 196 if (lhs.password_element != rhs.password_element) 197 return false; 198 if (lhs.new_password_element != rhs.new_password_element) 199 return false; 200 if (lhs.username_value != rhs.username_value) 201 return false; 202 if (lhs.password_value != rhs.password_value) 203 return false; 204 if (lhs.new_password_value != rhs.new_password_value) 205 return false; 206 if (lhs.password_autocomplete_set != rhs.password_autocomplete_set) 207 return false; 208 if (lhs.submit_element != rhs.submit_element) 209 return false; 210 if (lhs.signon_realm != rhs.signon_realm) 211 return false; 212 return true; 213 } 214 215 TestPasswordManager* manager() { return manager_.get(); } 216 217 void OnPasswordFormSubmitted(const autofill::PasswordForm& form) { 218 manager()->OnPasswordFormSubmitted(form); 219 } 220 221 PasswordManager::PasswordSubmittedCallback SubmissionCallback() { 222 return base::Bind(&PasswordManagerTest::FormSubmitted, 223 base::Unretained(this)); 224 } 225 226 void FormSubmitted(const autofill::PasswordForm& form) { 227 submitted_form_ = form; 228 } 229 230 TestingPrefServiceSimple prefs_; 231 scoped_refptr<MockPasswordStore> store_; 232 MockPasswordManagerClient client_; 233 MockPasswordManagerDriver driver_; 234 scoped_ptr<PasswordAutofillManager> password_autofill_manager_; 235 scoped_ptr<TestPasswordManager> manager_; 236 PasswordForm submitted_form_; 237 }; 238 239 MATCHER_P(FormMatches, form, "") { 240 return form.signon_realm == arg.signon_realm && form.origin == arg.origin && 241 form.action == arg.action && 242 form.username_element == arg.username_element && 243 form.password_element == arg.password_element && 244 form.new_password_element == arg.new_password_element && 245 form.password_autocomplete_set == arg.password_autocomplete_set && 246 form.submit_element == arg.submit_element; 247 } 248 249 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) { 250 // Test that observing a newly submitted form shows the save password bar. 251 std::vector<PasswordForm*> result; // Empty password store. 252 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 253 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 254 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 255 std::vector<PasswordForm> observed; 256 PasswordForm form(MakeSimpleForm()); 257 observed.push_back(form); 258 manager()->OnPasswordFormsParsed(observed); // The initial load. 259 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 260 261 // And the form submit contract is to call ProvisionallySavePassword. 262 manager()->ProvisionallySavePassword(form); 263 264 scoped_ptr<PasswordFormManager> form_to_save; 265 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)) 266 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 267 268 // Now the password manager waits for the navigation to complete. 269 observed.clear(); 270 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 271 manager()->OnPasswordFormsRendered(observed, 272 true); // The post-navigation layout. 273 274 ASSERT_TRUE(form_to_save.get()); 275 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 276 277 // Simulate saving the form, as if the info bar was accepted. 278 form_to_save->Save(); 279 } 280 281 TEST_F(PasswordManagerTest, FormSubmitWithOnlyNewPasswordField) { 282 // This test is the same as FormSubmitEmptyStore, except that it simulates the 283 // user entering credentials into a sign-up form that only has a new password 284 // field. 285 std::vector<PasswordForm*> result; // Empty password store. 286 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 287 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 288 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 289 std::vector<PasswordForm> observed; 290 PasswordForm form(MakeFormWithOnlyNewPasswordField()); 291 observed.push_back(form); 292 manager()->OnPasswordFormsParsed(observed); 293 manager()->OnPasswordFormsRendered(observed, true); 294 295 // And the form submit contract is to call ProvisionallySavePassword. 296 manager()->ProvisionallySavePassword(form); 297 298 scoped_ptr<PasswordFormManager> form_to_save; 299 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)) 300 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 301 302 // Now the password manager waits for the navigation to complete. 303 observed.clear(); 304 manager()->OnPasswordFormsParsed(observed); 305 manager()->OnPasswordFormsRendered(observed, true); 306 307 ASSERT_TRUE(form_to_save.get()); 308 309 // Simulate saving the form, as if the info bar was accepted. 310 PasswordForm saved_form; 311 EXPECT_CALL(*store_.get(), AddLogin(_)) 312 .WillOnce(testing::SaveArg<0>(&saved_form)); 313 form_to_save->Save(); 314 315 // The value of the new password field should have been promoted to, and saved 316 // to the password store as the current password, and no password element name 317 // should have been saved. 318 PasswordForm expected_form(form); 319 expected_form.password_value.swap(expected_form.new_password_value); 320 expected_form.new_password_element.clear(); 321 EXPECT_THAT(saved_form, FormMatches(expected_form)); 322 EXPECT_EQ(expected_form.password_value, saved_form.password_value); 323 EXPECT_EQ(expected_form.new_password_value, saved_form.new_password_value); 324 } 325 326 TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) { 327 // This test is the same as FormSubmitEmptyStore, except that it simulates the 328 // user generating the password through the browser. 329 std::vector<PasswordForm*> result; // Empty password store. 330 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 331 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 332 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 333 std::vector<PasswordForm> observed; 334 PasswordForm form(MakeSimpleForm()); 335 observed.push_back(form); 336 manager()->OnPasswordFormsParsed(observed); // The initial load. 337 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 338 339 // Simulate the user generating the password and submitting the form. 340 manager()->SetFormHasGeneratedPassword(form); 341 manager()->ProvisionallySavePassword(form); 342 343 // The user should not be presented with an infobar as they have already given 344 // consent by using the generated password. The form should be saved once 345 // navigation occurs. The client will be informed that automatic saving has 346 // occured. 347 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(0)); 348 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 349 scoped_ptr<PasswordFormManager> saved_form_manager; 350 EXPECT_CALL(client_, AutomaticPasswordSavePtr(_)).Times(Exactly(1)) 351 .WillOnce(WithArg<0>(SaveToScopedPtr(&saved_form_manager))); 352 353 // Now the password manager waits for the navigation to complete. 354 observed.clear(); 355 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 356 manager()->OnPasswordFormsRendered(observed, 357 true); // The post-navigation layout. 358 } 359 360 TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) { 361 // Same as above, except with an existing form for the same signon realm, 362 // but different origin. Detailed cases like this are covered by 363 // PasswordFormManagerTest. 364 std::vector<PasswordForm*> result; 365 PasswordForm* existing_different = new PasswordForm(MakeSimpleForm()); 366 existing_different->username_value = ASCIIToUTF16("google2"); 367 result.push_back(existing_different); 368 EXPECT_CALL(driver_, FillPasswordForm(_)); 369 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 370 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 371 372 std::vector<PasswordForm> observed; 373 PasswordForm form(MakeSimpleForm()); 374 observed.push_back(form); 375 manager()->OnPasswordFormsParsed(observed); // The initial load. 376 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 377 manager()->ProvisionallySavePassword(form); 378 379 // We still expect an add, since we didn't have a good match. 380 scoped_ptr<PasswordFormManager> form_to_save; 381 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)) 382 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 383 384 // Now the password manager waits for the navigation to complete. 385 observed.clear(); 386 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 387 manager()->OnPasswordFormsRendered(observed, 388 true); // The post-navigation layout. 389 390 ASSERT_TRUE(form_to_save.get()); 391 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 392 393 // Simulate saving the form. 394 form_to_save->Save(); 395 } 396 397 TEST_F(PasswordManagerTest, FormSeenThenLeftPage) { 398 std::vector<PasswordForm*> result; // Empty password store. 399 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 400 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 401 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 402 std::vector<PasswordForm> observed; 403 PasswordForm form(MakeSimpleForm()); 404 observed.push_back(form); 405 manager()->OnPasswordFormsParsed(observed); // The initial load. 406 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 407 408 // No message from the renderer that a password was submitted. No 409 // expected calls. 410 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(0); 411 observed.clear(); 412 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 413 manager()->OnPasswordFormsRendered(observed, 414 true); // The post-navigation layout. 415 } 416 417 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateInPage) { 418 // Test that navigating in the page does not prevent us from showing the save 419 // password infobar. 420 std::vector<PasswordForm*> result; // Empty password store. 421 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 422 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 423 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 424 std::vector<PasswordForm> observed; 425 PasswordForm form(MakeSimpleForm()); 426 observed.push_back(form); 427 manager()->OnPasswordFormsParsed(observed); // The initial load. 428 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 429 430 // Simulate navigating in the page. 431 manager()->DidNavigateMainFrame(true); 432 433 // Simulate submitting the password. 434 OnPasswordFormSubmitted(form); 435 436 // Now the password manager waits for the navigation to complete. 437 scoped_ptr<PasswordFormManager> form_to_save; 438 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)) 439 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 440 441 observed.clear(); 442 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 443 manager()->OnPasswordFormsRendered(observed, 444 true); // The post-navigation layout. 445 446 ASSERT_FALSE(NULL == form_to_save.get()); 447 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 448 449 // Simulate saving the form, as if the info bar was accepted. 450 form_to_save->Save(); 451 } 452 453 // This test verifies a fix for http://crbug.com/236673 454 TEST_F(PasswordManagerTest, FormSubmitWithFormOnPreviousPage) { 455 std::vector<PasswordForm*> result; // Empty password store. 456 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 457 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 458 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 459 PasswordForm first_form(MakeSimpleForm()); 460 first_form.origin = GURL("http://www.nytimes.com/"); 461 first_form.action = GURL("https://myaccount.nytimes.com/auth/login"); 462 first_form.signon_realm = "http://www.nytimes.com/"; 463 PasswordForm second_form(MakeSimpleForm()); 464 second_form.origin = GURL("https://myaccount.nytimes.com/auth/login"); 465 second_form.action = GURL("https://myaccount.nytimes.com/auth/login"); 466 second_form.signon_realm = "https://myaccount.nytimes.com/"; 467 468 // Pretend that the form is hidden on the first page. 469 std::vector<PasswordForm> observed; 470 observed.push_back(first_form); 471 manager()->OnPasswordFormsParsed(observed); 472 observed.clear(); 473 manager()->OnPasswordFormsRendered(observed, true); 474 475 // Now navigate to a second page. 476 manager()->DidNavigateMainFrame(false); 477 478 // This page contains a form with the same markup, but on a different 479 // URL. 480 observed.push_back(second_form); 481 manager()->OnPasswordFormsParsed(observed); 482 manager()->OnPasswordFormsRendered(observed, true); 483 484 // Now submit this form 485 OnPasswordFormSubmitted(second_form); 486 487 // Navigation after form submit. 488 scoped_ptr<PasswordFormManager> form_to_save; 489 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)) 490 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 491 observed.clear(); 492 manager()->OnPasswordFormsParsed(observed); 493 manager()->OnPasswordFormsRendered(observed, true); 494 495 // Make sure that the saved form matches the second form, not the first. 496 ASSERT_TRUE(form_to_save.get()); 497 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(second_form))); 498 499 // Simulate saving the form, as if the info bar was accepted. 500 form_to_save->Save(); 501 } 502 503 TEST_F(PasswordManagerTest, FormSubmitFailedLogin) { 504 std::vector<PasswordForm*> result; // Empty password store. 505 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 506 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 507 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 508 std::vector<PasswordForm> observed; 509 PasswordForm form(MakeSimpleForm()); 510 observed.push_back(form); 511 manager()->OnPasswordFormsParsed(observed); // The initial load. 512 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 513 514 manager()->ProvisionallySavePassword(form); 515 516 // The form reappears, and is visible in the layout: 517 // No expected calls to the PasswordStore... 518 manager()->OnPasswordFormsParsed(observed); 519 manager()->OnPasswordFormsRendered(observed, true); 520 } 521 522 TEST_F(PasswordManagerTest, FormSubmitInvisibleLogin) { 523 // Tests fix of issue 28911: if the login form reappears on the subsequent 524 // page, but is invisible, it shouldn't count as a failed login. 525 std::vector<PasswordForm*> result; // Empty password store. 526 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 527 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 528 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 529 std::vector<PasswordForm> observed; 530 PasswordForm form(MakeSimpleForm()); 531 observed.push_back(form); 532 manager()->OnPasswordFormsParsed(observed); // The initial load. 533 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 534 535 manager()->ProvisionallySavePassword(form); 536 537 // Expect info bar to appear: 538 scoped_ptr<PasswordFormManager> form_to_save; 539 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)) 540 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 541 542 // The form reappears, but is not visible in the layout: 543 manager()->OnPasswordFormsParsed(observed); 544 observed.clear(); 545 manager()->OnPasswordFormsRendered(observed, true); 546 547 ASSERT_TRUE(form_to_save.get()); 548 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 549 550 // Simulate saving the form. 551 form_to_save->Save(); 552 } 553 554 TEST_F(PasswordManagerTest, InitiallyInvisibleForm) { 555 // Make sure an invisible login form still gets autofilled. 556 std::vector<PasswordForm*> result; 557 PasswordForm* existing = new PasswordForm(MakeSimpleForm()); 558 result.push_back(existing); 559 EXPECT_CALL(driver_, FillPasswordForm(_)); 560 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 561 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 562 std::vector<PasswordForm> observed; 563 PasswordForm form(MakeSimpleForm()); 564 observed.push_back(form); 565 manager()->OnPasswordFormsParsed(observed); // The initial load. 566 observed.clear(); 567 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 568 569 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 570 manager()->OnPasswordFormsRendered(observed, 571 true); // The post-navigation layout. 572 } 573 574 TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) { 575 // Test that saving passwords depends on the password manager enabled 576 // preference. 577 prefs_.SetUserPref(prefs::kPasswordManagerSavingEnabled, 578 new base::FundamentalValue(true)); 579 EXPECT_TRUE(manager()->IsSavingEnabledForCurrentPage()); 580 prefs_.SetUserPref(prefs::kPasswordManagerSavingEnabled, 581 new base::FundamentalValue(false)); 582 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage()); 583 } 584 585 TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) { 586 // Test fix for issue 158296: Passwords must be filled even if the password 587 // manager is disabled. 588 std::vector<PasswordForm*> result; 589 PasswordForm* existing = new PasswordForm(MakeSimpleForm()); 590 result.push_back(existing); 591 prefs_.SetUserPref(prefs::kPasswordManagerSavingEnabled, 592 new base::FundamentalValue(false)); 593 EXPECT_CALL(driver_, FillPasswordForm(_)); 594 EXPECT_CALL(*store_.get(), 595 GetLogins(_, testing::Eq(PasswordStore::DISALLOW_PROMPT), _)) 596 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 597 std::vector<PasswordForm> observed; 598 PasswordForm form(MakeSimpleForm()); 599 observed.push_back(form); 600 manager()->OnPasswordFormsParsed(observed); 601 } 602 603 TEST_F(PasswordManagerTest, FormSavedWithAutocompleteOff) { 604 // Test password form with non-generated password will be saved even if 605 // autocomplete=off. 606 std::vector<PasswordForm*> result; // Empty password store. 607 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 608 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 609 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 610 std::vector<PasswordForm> observed; 611 PasswordForm form(MakeSimpleForm()); 612 form.password_autocomplete_set = false; 613 observed.push_back(form); 614 manager()->OnPasswordFormsParsed(observed); // The initial load. 615 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 616 617 // And the form submit contract is to call ProvisionallySavePassword. 618 manager()->ProvisionallySavePassword(form); 619 620 // Password form should be saved. 621 scoped_ptr<PasswordFormManager> form_to_save; 622 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(1)) 623 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 624 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))).Times(Exactly(0)); 625 626 // Now the password manager waits for the navigation to complete. 627 observed.clear(); 628 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 629 manager()->OnPasswordFormsRendered(observed, 630 true); // The post-navigation layout. 631 632 ASSERT_TRUE(form_to_save.get()); 633 } 634 635 TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) { 636 // Test password form with generated password will still be saved if 637 // autocomplete=off. 638 std::vector<PasswordForm*> result; // Empty password store. 639 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 640 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 641 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 642 std::vector<PasswordForm> observed; 643 PasswordForm form(MakeSimpleForm()); 644 form.password_autocomplete_set = false; 645 observed.push_back(form); 646 manager()->OnPasswordFormsParsed(observed); // The initial load. 647 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 648 649 // Simulate the user generating the password and submitting the form. 650 manager()->SetFormHasGeneratedPassword(form); 651 manager()->ProvisionallySavePassword(form); 652 653 // The user should not be presented with an infobar as they have already given 654 // consent by using the generated password. The form should be saved once 655 // navigation occurs. The client will be informed that automatic saving has 656 // occured. 657 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(0)); 658 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 659 scoped_ptr<PasswordFormManager> saved_form_manager; 660 EXPECT_CALL(client_, AutomaticPasswordSavePtr(_)).Times(Exactly(1)) 661 .WillOnce(WithArg<0>(SaveToScopedPtr(&saved_form_manager))); 662 663 // Now the password manager waits for the navigation to complete. 664 observed.clear(); 665 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 666 manager()->OnPasswordFormsRendered(observed, 667 true); // The post-navigation layout. 668 } 669 670 TEST_F(PasswordManagerTest, SubmissionCallbackTest) { 671 manager()->AddSubmissionCallback(SubmissionCallback()); 672 PasswordForm form = MakeSimpleForm(); 673 OnPasswordFormSubmitted(form); 674 EXPECT_TRUE(FormsAreEqual(form, submitted_form_)); 675 } 676 677 TEST_F(PasswordManagerTest, PasswordFormReappearance) { 678 // Test the heuristic to know if a password form reappears. 679 // We assume that if we send our credentials and there 680 // is at least one visible password form in the next page that 681 // means that our previous login attempt failed. 682 std::vector<PasswordForm*> result; // Empty password store. 683 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0); 684 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 685 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 686 std::vector<PasswordForm> observed; 687 PasswordForm login_form(MakeTwitterLoginForm()); 688 observed.push_back(login_form); 689 manager()->OnPasswordFormsParsed(observed); // The initial load. 690 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 691 692 manager()->ProvisionallySavePassword(login_form); 693 694 PasswordForm failed_login_form(MakeTwitterFailedLoginForm()); 695 observed.clear(); 696 observed.push_back(failed_login_form); 697 // A PasswordForm appears, and is visible in the layout: 698 // No expected calls to the PasswordStore... 699 manager()->OnPasswordFormsParsed(observed); 700 manager()->OnPasswordFormsRendered(observed, true); 701 } 702 703 TEST_F(PasswordManagerTest, SavingNotEnabledOnSSLErrors) { 704 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors()) 705 .WillRepeatedly(Return(true)); 706 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage()); 707 } 708 709 TEST_F(PasswordManagerTest, AutofillingNotEnabledOnSSLErrors) { 710 // Test that in the presence of SSL errors, the password manager does not 711 // attempt to autofill forms found on a website. 712 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors()) 713 .WillRepeatedly(Return(true)); 714 715 // Let us pretend some forms were found on a website. 716 std::vector<PasswordForm> forms; 717 forms.push_back(MakeSimpleForm()); 718 719 // Feed those forms to |manager()| and check that it does not try to find 720 // matching saved credentials for the forms. 721 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)).Times(Exactly(0)); 722 manager()->OnPasswordFormsParsed(forms); 723 } 724 725 TEST_F(PasswordManagerTest, SavingDisabledIfManagerDisabled) { 726 EXPECT_CALL(client_, IsPasswordManagerEnabledForCurrentPage()) 727 .WillRepeatedly(Return(false)); 728 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage()); 729 } 730 731 TEST_F(PasswordManagerTest, AutofillingDisabledIfManagerDisabled) { 732 EXPECT_CALL(client_, IsPasswordManagerEnabledForCurrentPage()) 733 .WillRepeatedly(Return(false)); 734 735 // Let us pretend some forms were found on a website. 736 std::vector<PasswordForm> forms; 737 forms.push_back(MakeSimpleForm()); 738 739 // Feed those forms to |manager()| and check that it does not try to find 740 // matching saved credentials for the forms. 741 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)).Times(Exactly(0)); 742 manager()->OnPasswordFormsParsed(forms); 743 } 744 745 TEST_F(PasswordManagerTest, SyncCredentialsNotSaved) { 746 EXPECT_CALL(client_, IsSyncAccountCredential(_, _)) 747 .WillRepeatedly(Return(true)); 748 749 // Simulate loading a simple form with no existing stored password. 750 std::vector<PasswordForm*> result; // Empty password store. 751 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 752 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 753 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 754 std::vector<PasswordForm> observed; 755 PasswordForm form(MakeSimpleForm()); 756 form.password_autocomplete_set = false; 757 observed.push_back(form); 758 manager()->OnPasswordFormsParsed(observed); // The initial load. 759 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 760 761 // User should not be prompted and password should not be saved. 762 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(0)); 763 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))).Times(Exactly(0)); 764 765 // Submit form and finish navigation. 766 manager()->ProvisionallySavePassword(form); 767 observed.clear(); 768 manager()->OnPasswordFormsParsed(observed); 769 manager()->OnPasswordFormsRendered(observed, true); 770 } 771 772 // On failed login attempts, the retry-form can have action scheme changed from 773 // HTTP to HTTPS (see http://crbug.com/400769). Check that such retry-form is 774 // considered equal to the original login form, and the attempt recognised as a 775 // failure. 776 TEST_F(PasswordManagerTest, 777 SeeingFormActionWithOnlyHttpHttpsChangeIsLoginFailure) { 778 std::vector<PasswordForm*> result; // Empty password store. 779 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 780 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 781 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 782 783 PasswordForm first_form(MakeSimpleForm()); 784 first_form.origin = GURL("http://www.xda-developers.com/"); 785 first_form.action = GURL("http://forum.xda-developers.com/login.php"); 786 787 // |second_form|'s action differs only with it's scheme i.e. *https://*. 788 PasswordForm second_form(first_form); 789 second_form.action = GURL("https://forum.xda-developers.com/login.php"); 790 791 std::vector<PasswordForm> observed; 792 observed.push_back(first_form); 793 manager()->OnPasswordFormsParsed(observed); 794 manager()->OnPasswordFormsRendered(observed, true); 795 observed.clear(); 796 797 // Now submit the |first_form|. 798 OnPasswordFormSubmitted(first_form); 799 800 // Simulate loading a page, which contains |second_form| instead of 801 // |first_form|. 802 observed.push_back(second_form); 803 804 // Verify that no prompt to save the password is shown. 805 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(0)); 806 manager()->OnPasswordFormsParsed(observed); 807 manager()->OnPasswordFormsRendered(observed, true); 808 observed.clear(); 809 } 810 811 // Create a form with a new_password_element. Submit the form with the empty 812 // new password value. It shouldn't overwrite the existing password. 813 TEST_F(PasswordManagerTest, DoNotUpdateWithEmptyPassword) { 814 std::vector<PasswordForm*> result; // Empty password store. 815 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 816 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 817 std::vector<PasswordForm> observed; 818 PasswordForm form(MakeSimpleForm()); 819 form.new_password_element = ASCIIToUTF16("new_password_element"); 820 form.new_password_value.clear(); 821 observed.push_back(form); 822 manager()->OnPasswordFormsParsed(observed); // The initial load. 823 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 824 825 // And the form submit contract is to call ProvisionallySavePassword. 826 OnPasswordFormSubmitted(form); 827 828 scoped_ptr<PasswordFormManager> form_to_save; 829 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(0); 830 831 // Now the password manager waits for the login to complete successfully. 832 observed.clear(); 833 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 834 manager()->OnPasswordFormsRendered(observed, 835 true); // The post-navigation layout. 836 } 837 838 TEST_F(PasswordManagerTest, FormSubmitWithOnlyPassowrdField) { 839 // Test to verify that on submitting the HTML password form without having 840 // username input filed shows password save promt and saves the password to 841 // store. 842 std::vector<PasswordForm*> result; // Empty password store. 843 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 844 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 845 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 846 std::vector<PasswordForm> observed; 847 848 // Loads passsword form without username input field. 849 PasswordForm form(MakeSimpleFormWithOnlyPasswordField()); 850 observed.push_back(form); 851 manager()->OnPasswordFormsParsed(observed); // The initial load. 852 manager()->OnPasswordFormsRendered(observed, true); // The initial layout. 853 854 // And the form submit contract is to call ProvisionallySavePassword. 855 manager()->ProvisionallySavePassword(form); 856 857 scoped_ptr<PasswordFormManager> form_to_save; 858 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)) 859 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 860 861 // Now the password manager waits for the navigation to complete. 862 observed.clear(); 863 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 864 manager()->OnPasswordFormsRendered(observed, 865 true); // The post-navigation layout. 866 867 ASSERT_TRUE(form_to_save.get()); 868 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 869 870 // Simulate saving the form, as if the info bar was accepted. 871 form_to_save->Save(); 872 } 873 874 } // namespace password_manager 875