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 "base/memory/scoped_ptr.h" 6 #include "base/message_loop/message_loop.h" 7 #include "base/prefs/pref_registry_simple.h" 8 #include "base/prefs/pref_service.h" 9 #include "base/prefs/testing_pref_service.h" 10 #include "base/run_loop.h" 11 #include "base/strings/string_util.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "components/autofill/core/common/password_form.h" 14 #include "components/password_manager/core/browser/mock_password_store.h" 15 #include "components/password_manager/core/browser/password_form_manager.h" 16 #include "components/password_manager/core/browser/password_manager.h" 17 #include "components/password_manager/core/browser/password_manager_driver.h" 18 #include "components/password_manager/core/browser/password_store.h" 19 #include "components/password_manager/core/browser/stub_password_manager_client.h" 20 #include "components/password_manager/core/browser/stub_password_manager_driver.h" 21 #include "components/password_manager/core/browser/test_password_store.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 using autofill::PasswordForm; 27 using base::ASCIIToUTF16; 28 using ::testing::_; 29 using ::testing::Eq; 30 using ::testing::Mock; 31 using ::testing::Return; 32 33 namespace autofill { 34 class AutofillManager; 35 } 36 37 namespace password_manager { 38 39 namespace { 40 41 void RunAllPendingTasks() { 42 base::RunLoop run_loop; 43 base::MessageLoop::current()->PostTask( 44 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 45 run_loop.Run(); 46 } 47 48 class MockPasswordManagerDriver : public StubPasswordManagerDriver { 49 public: 50 MOCK_METHOD0(IsOffTheRecord, bool()); 51 MOCK_METHOD1(AllowPasswordGenerationForForm, 52 void(const autofill::PasswordForm&)); 53 }; 54 55 class TestPasswordManagerClient : public StubPasswordManagerClient { 56 public: 57 explicit TestPasswordManagerClient(PasswordStore* password_store) 58 : password_store_(password_store) { 59 prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerSavingEnabled, 60 true); 61 } 62 63 virtual bool ShouldFilterAutofillResult( 64 const autofill::PasswordForm& form) OVERRIDE { 65 if (form == form_to_filter_) 66 return true; 67 return false; 68 } 69 70 virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; } 71 virtual PasswordStore* GetPasswordStore() OVERRIDE { return password_store_; } 72 virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; } 73 virtual void AuthenticateAutofillAndFillForm( 74 scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE { 75 driver_.FillPasswordForm(*fill_data.get()); 76 } 77 78 void SetFormToFilter(const autofill::PasswordForm& form) { 79 form_to_filter_ = form; 80 } 81 82 MockPasswordManagerDriver* GetMockDriver() { return &driver_; } 83 84 private: 85 autofill::PasswordForm form_to_filter_; 86 87 TestingPrefServiceSimple prefs_; 88 PasswordStore* password_store_; 89 testing::NiceMock<MockPasswordManagerDriver> driver_; 90 }; 91 92 class TestPasswordManager : public PasswordManager { 93 public: 94 explicit TestPasswordManager(PasswordManagerClient* client) 95 : PasswordManager(client) {} 96 97 virtual void Autofill(const autofill::PasswordForm& form_for_autofill, 98 const autofill::PasswordFormMap& best_matches, 99 const autofill::PasswordForm& preferred_match, 100 bool wait_for_username) const OVERRIDE { 101 best_matches_ = best_matches; 102 } 103 104 const autofill::PasswordFormMap& GetLatestBestMatches() { 105 return best_matches_; 106 } 107 108 private: 109 // Marked mutable to get around constness of Autofill(). 110 mutable autofill::PasswordFormMap best_matches_; 111 }; 112 113 class MockPasswordFormManager : public PasswordFormManager { 114 public: 115 MockPasswordFormManager(PasswordManager* manager, 116 PasswordManagerClient* client, 117 PasswordManagerDriver* driver, 118 const autofill::PasswordForm& observed_form, 119 bool ssl_valid) 120 : PasswordFormManager(manager, client, driver, observed_form, ssl_valid) 121 {} 122 123 MOCK_METHOD2(UploadPasswordForm, void(const autofill::FormData&, 124 const autofill::ServerFieldType&)); 125 }; 126 127 } // namespace 128 129 class PasswordFormManagerTest : public testing::Test { 130 public: 131 PasswordFormManagerTest() : client_(NULL /*password_store*/) {} 132 133 // Types of possible outcomes of simulated matching, see 134 // SimulateMatchingPhase. 135 enum ResultOfSimulatedMatching { RESULT_MATCH_FOUND, RESULT_NO_MATCH }; 136 137 virtual void SetUp() { 138 observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth"); 139 observed_form_.action = GURL("http://accounts.google.com/a/Login"); 140 observed_form_.username_element = ASCIIToUTF16("Email"); 141 observed_form_.password_element = ASCIIToUTF16("Passwd"); 142 observed_form_.submit_element = ASCIIToUTF16("signIn"); 143 observed_form_.signon_realm = "http://accounts.google.com"; 144 145 saved_match_ = observed_form_; 146 saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth"); 147 saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin"); 148 saved_match_.preferred = true; 149 saved_match_.username_value = ASCIIToUTF16("test (at) gmail.com"); 150 saved_match_.password_value = ASCIIToUTF16("test1"); 151 saved_match_.other_possible_usernames.push_back( 152 ASCIIToUTF16("test2 (at) gmail.com")); 153 } 154 155 virtual void TearDown() { 156 if (mock_store_.get()) 157 mock_store_->Shutdown(); 158 } 159 160 void InitializeMockStore() { 161 if (!mock_store_.get()) { 162 mock_store_ = new testing::NiceMock<MockPasswordStore>(); 163 ASSERT_TRUE(mock_store_.get()); 164 } 165 } 166 167 MockPasswordStore* mock_store() const { return mock_store_.get(); } 168 169 PasswordForm* GetPendingCredentials(PasswordFormManager* p) { 170 return &p->pending_credentials_; 171 } 172 173 void SimulateMatchingPhase(PasswordFormManager* p, 174 ResultOfSimulatedMatching result) { 175 // Roll up the state to mock out the matching phase. 176 p->state_ = PasswordFormManager::POST_MATCHING_PHASE; 177 if (result == RESULT_NO_MATCH) 178 return; 179 180 PasswordForm* match = new PasswordForm(saved_match_); 181 // Heap-allocated form is owned by p. 182 p->best_matches_[match->username_value] = match; 183 p->preferred_match_ = match; 184 } 185 186 void SimulateFetchMatchingLoginsFromPasswordStore( 187 PasswordFormManager* manager) { 188 // Just need to update the internal states. 189 manager->state_ = PasswordFormManager::MATCHING_PHASE; 190 } 191 192 void SimulateResponseFromPasswordStore( 193 PasswordFormManager* manager, 194 const std::vector<PasswordForm*>& result) { 195 // Simply call the callback method when request done. This will transfer 196 // the ownership of the objects in |result| to the |manager|. 197 manager->OnGetPasswordStoreResults(result); 198 } 199 200 void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) { 201 p->SanitizePossibleUsernames(form); 202 } 203 204 bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) { 205 return p->ShouldIgnoreResult(*form); 206 } 207 208 PasswordForm* observed_form() { return &observed_form_; } 209 PasswordForm* saved_match() { return &saved_match_; } 210 PasswordForm* CreateSavedMatch(bool blacklisted) { 211 // Owned by the caller of this method. 212 PasswordForm* match = new PasswordForm(saved_match_); 213 match->blacklisted_by_user = blacklisted; 214 return match; 215 } 216 217 TestPasswordManagerClient* client() { return &client_; } 218 219 private: 220 PasswordForm observed_form_; 221 PasswordForm saved_match_; 222 scoped_refptr<testing::NiceMock<MockPasswordStore> > mock_store_; 223 TestPasswordManagerClient client_; 224 }; 225 226 TEST_F(PasswordFormManagerTest, TestNewLogin) { 227 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 228 SimulateMatchingPhase(&manager, RESULT_NO_MATCH); 229 230 // User submits credentials for the observed form. 231 PasswordForm credentials = *observed_form(); 232 credentials.username_value = saved_match()->username_value; 233 credentials.password_value = saved_match()->password_value; 234 credentials.preferred = true; 235 manager.ProvisionallySave( 236 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 237 238 // Successful login. The PasswordManager would instruct PasswordFormManager 239 // to save, which should know this is a new login. 240 EXPECT_TRUE(manager.IsNewLogin()); 241 // Make sure the credentials that would be submitted on successful login 242 // are going to match the stored entry in the db. 243 EXPECT_EQ(observed_form()->origin.spec(), 244 GetPendingCredentials(&manager)->origin.spec()); 245 EXPECT_EQ(observed_form()->signon_realm, 246 GetPendingCredentials(&manager)->signon_realm); 247 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action); 248 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred); 249 EXPECT_EQ(saved_match()->password_value, 250 GetPendingCredentials(&manager)->password_value); 251 EXPECT_EQ(saved_match()->username_value, 252 GetPendingCredentials(&manager)->username_value); 253 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty()); 254 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty()); 255 256 // Now, suppose the user re-visits the site and wants to save an additional 257 // login for the site with a new username. In this case, the matching phase 258 // will yield the previously saved login. 259 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND); 260 // Set up the new login. 261 base::string16 new_user = ASCIIToUTF16("newuser"); 262 base::string16 new_pass = ASCIIToUTF16("newpass"); 263 credentials.username_value = new_user; 264 credentials.password_value = new_pass; 265 manager.ProvisionallySave( 266 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 267 268 // Again, the PasswordFormManager should know this is still a new login. 269 EXPECT_TRUE(manager.IsNewLogin()); 270 // And make sure everything squares up again. 271 EXPECT_EQ(observed_form()->origin.spec(), 272 GetPendingCredentials(&manager)->origin.spec()); 273 EXPECT_EQ(observed_form()->signon_realm, 274 GetPendingCredentials(&manager)->signon_realm); 275 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred); 276 EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value); 277 EXPECT_EQ(new_user, GetPendingCredentials(&manager)->username_value); 278 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty()); 279 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty()); 280 } 281 282 // If PSL-matched credentials had been suggested, but the user has overwritten 283 // the password, the provisionally saved credentials should no longer be 284 // considered as PSL-matched, so that the exception for not prompting before 285 // saving PSL-matched credentials should no longer apply. 286 TEST_F(PasswordFormManagerTest, 287 OverriddenPSLMatchedCredentialsNotMarkedAsPSLMatched) { 288 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 289 290 // The suggestion needs to be PSL-matched. 291 saved_match()->original_signon_realm = "www.example.org"; 292 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND); 293 294 // User modifies the suggested password and submits the form. 295 PasswordForm credentials(*observed_form()); 296 credentials.username_value = saved_match()->username_value; 297 credentials.password_value = 298 saved_match()->password_value + ASCIIToUTF16("modify"); 299 manager.ProvisionallySave( 300 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 301 302 EXPECT_TRUE(manager.IsNewLogin()); 303 EXPECT_FALSE(manager.IsPendingCredentialsPublicSuffixMatch()); 304 } 305 306 TEST_F(PasswordFormManagerTest, TestNewLoginFromNewPasswordElement) { 307 // Add a new password field to the test form. The PasswordFormManager should 308 // save the password from this field, instead of the current password field. 309 observed_form()->new_password_element = ASCIIToUTF16("NewPasswd"); 310 311 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 312 SimulateMatchingPhase(&manager, RESULT_NO_MATCH); 313 314 // User enters current and new credentials to the observed form. 315 PasswordForm credentials(*observed_form()); 316 credentials.username_value = saved_match()->username_value; 317 credentials.password_value = saved_match()->password_value; 318 credentials.new_password_value = ASCIIToUTF16("newpassword"); 319 credentials.preferred = true; 320 manager.ProvisionallySave( 321 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 322 323 // Successful login. The PasswordManager would instruct PasswordFormManager 324 // to save, which should know this is a new login. 325 EXPECT_TRUE(manager.IsNewLogin()); 326 EXPECT_EQ(credentials.origin, GetPendingCredentials(&manager)->origin); 327 EXPECT_EQ(credentials.signon_realm, 328 GetPendingCredentials(&manager)->signon_realm); 329 EXPECT_EQ(credentials.action, GetPendingCredentials(&manager)->action); 330 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred); 331 EXPECT_EQ(credentials.username_value, 332 GetPendingCredentials(&manager)->username_value); 333 334 // By this point, the PasswordFormManager should have promoted the new 335 // password value to be the current password, and should have wiped the 336 // password element names: they are likely going to be different on a login 337 // form, so it is not worth remembering them. 338 EXPECT_EQ(credentials.new_password_value, 339 GetPendingCredentials(&manager)->password_value); 340 EXPECT_TRUE(GetPendingCredentials(&manager)->password_element.empty()); 341 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty()); 342 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty()); 343 } 344 345 TEST_F(PasswordFormManagerTest, TestUpdatePassword) { 346 // Create a PasswordFormManager with observed_form, as if we just 347 // saw this form and need to find matching logins. 348 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 349 350 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND); 351 352 // User submits credentials for the observed form using a username previously 353 // stored, but a new password. Note that the observed form may have different 354 // origin URL (as it does in this case) than the saved_match, but we want to 355 // make sure the updated password is reflected in saved_match, because that is 356 // what we autofilled. 357 base::string16 new_pass = ASCIIToUTF16("test2"); 358 PasswordForm credentials = *observed_form(); 359 credentials.username_value = saved_match()->username_value; 360 credentials.password_value = new_pass; 361 credentials.preferred = true; 362 manager.ProvisionallySave( 363 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 364 365 // Successful login. The PasswordManager would instruct PasswordFormManager 366 // to save, and since this is an update, it should know not to save as a new 367 // login. 368 EXPECT_FALSE(manager.IsNewLogin()); 369 370 // Make sure the credentials that would be submitted on successful login 371 // are going to match the stored entry in the db. (This verifies correct 372 // behaviour for bug 1074420). 373 EXPECT_EQ(GetPendingCredentials(&manager)->origin.spec(), 374 saved_match()->origin.spec()); 375 EXPECT_EQ(GetPendingCredentials(&manager)->signon_realm, 376 saved_match()->signon_realm); 377 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred); 378 EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value); 379 } 380 381 TEST_F(PasswordFormManagerTest, TestUpdatePasswordFromNewPasswordElement) { 382 // Add a new password field to the test form. The PasswordFormManager should 383 // save the password from this field, instead of the current password field. 384 observed_form()->new_password_element = ASCIIToUTF16("NewPasswd"); 385 386 // Given that |observed_form| was most likely a change password form, it 387 // should not serve as a source for updating meta-information stored with the 388 // old credentials, such as element names, as they are likely going to be 389 // different between change password and login forms. To test this in depth, 390 // forcibly wipe |submit_element|, which should normally trigger updating this 391 // field from |observed_form| in the UpdateLogin() step as a special case. We 392 // will verify in the end that this did not happen. 393 saved_match()->submit_element.clear(); 394 395 InitializeMockStore(); 396 TestPasswordManagerClient client_with_store(mock_store()); 397 PasswordFormManager manager(NULL, 398 &client_with_store, 399 client_with_store.GetDriver(), 400 *observed_form(), 401 false); 402 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord()) 403 .WillRepeatedly(Return(false)); 404 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND); 405 406 // User submits current and new credentials to the observed form. 407 PasswordForm credentials(*observed_form()); 408 credentials.username_value = saved_match()->username_value; 409 credentials.password_value = saved_match()->password_value; 410 credentials.new_password_value = ASCIIToUTF16("test2"); 411 credentials.preferred = true; 412 manager.ProvisionallySave( 413 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 414 415 // Successful login. The PasswordManager would instruct PasswordFormManager 416 // to save, and since this is an update, it should know not to save as a new 417 // login. 418 EXPECT_FALSE(manager.IsNewLogin()); 419 420 // By now, the PasswordFormManager should have promoted the new password value 421 // already to be the current password, and should no longer maintain any info 422 // about the new password. 423 EXPECT_EQ(credentials.new_password_value, 424 GetPendingCredentials(&manager)->password_value); 425 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty()); 426 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty()); 427 428 // Trigger saving to exercise some special case handling in UpdateLogin(). 429 PasswordForm new_credentials; 430 EXPECT_CALL(*mock_store(), UpdateLogin(_)) 431 .WillOnce(testing::SaveArg<0>(&new_credentials)); 432 manager.Save(); 433 Mock::VerifyAndClearExpectations(mock_store()); 434 435 // No meta-information should be updated, only the password. 436 EXPECT_EQ(credentials.new_password_value, new_credentials.password_value); 437 EXPECT_EQ(saved_match()->username_element, new_credentials.username_element); 438 EXPECT_EQ(saved_match()->password_element, new_credentials.password_element); 439 EXPECT_EQ(saved_match()->submit_element, new_credentials.submit_element); 440 } 441 442 TEST_F(PasswordFormManagerTest, TestIgnoreResult) { 443 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 444 445 // Make sure we don't match a PasswordForm if it was originally saved on 446 // an SSL-valid page and we are now on a page with invalid certificate. 447 saved_match()->ssl_valid = true; 448 EXPECT_TRUE(IgnoredResult(&manager, saved_match())); 449 450 saved_match()->ssl_valid = false; 451 // Different paths for action / origin are okay. 452 saved_match()->action = GURL("http://www.google.com/b/Login"); 453 saved_match()->origin = GURL("http://www.google.com/foo"); 454 EXPECT_FALSE(IgnoredResult(&manager, saved_match())); 455 456 // Results should be ignored if the client requests it. 457 client()->SetFormToFilter(*saved_match()); 458 EXPECT_TRUE(IgnoredResult(&manager, saved_match())); 459 } 460 461 TEST_F(PasswordFormManagerTest, TestEmptyAction) { 462 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 463 464 saved_match()->action = GURL(); 465 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND); 466 // User logs in with the autofilled username / password from saved_match. 467 PasswordForm login = *observed_form(); 468 login.username_value = saved_match()->username_value; 469 login.password_value = saved_match()->password_value; 470 manager.ProvisionallySave( 471 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 472 EXPECT_FALSE(manager.IsNewLogin()); 473 // We bless our saved PasswordForm entry with the action URL of the 474 // observed form. 475 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action); 476 } 477 478 TEST_F(PasswordFormManagerTest, TestUpdateAction) { 479 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 480 481 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND); 482 // User logs in with the autofilled username / password from saved_match. 483 PasswordForm login = *observed_form(); 484 login.username_value = saved_match()->username_value; 485 login.password_value = saved_match()->password_value; 486 487 manager.ProvisionallySave( 488 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 489 EXPECT_FALSE(manager.IsNewLogin()); 490 // The observed action URL is different from the previously saved one, and 491 // is the same as the one that would be submitted on successful login. 492 EXPECT_NE(observed_form()->action, saved_match()->action); 493 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action); 494 } 495 496 TEST_F(PasswordFormManagerTest, TestDynamicAction) { 497 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 498 499 SimulateMatchingPhase(&manager, RESULT_NO_MATCH); 500 PasswordForm login(*observed_form()); 501 // The submitted action URL is different from the one observed on page load. 502 GURL new_action = GURL("http://www.google.com/new_action"); 503 login.action = new_action; 504 505 manager.ProvisionallySave( 506 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 507 EXPECT_TRUE(manager.IsNewLogin()); 508 // Check that the provisionally saved action URL is the same as the submitted 509 // action URL, not the one observed on page load. 510 EXPECT_EQ(new_action, GetPendingCredentials(&manager)->action); 511 } 512 513 TEST_F(PasswordFormManagerTest, TestAlternateUsername) { 514 // Need a MessageLoop for callbacks. 515 base::MessageLoop message_loop; 516 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore; 517 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), "")); 518 519 TestPasswordManagerClient client_with_store(password_store.get()); 520 TestPasswordManager password_manager(&client_with_store); 521 PasswordFormManager manager(&password_manager, 522 &client_with_store, 523 client_with_store.GetDriver(), 524 *observed_form(), 525 false); 526 EXPECT_CALL(*client_with_store.GetMockDriver(), 527 AllowPasswordGenerationForForm(_)).Times(1); 528 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord()) 529 .WillRepeatedly(Return(false)); 530 531 password_store->AddLogin(*saved_match()); 532 manager.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT); 533 RunAllPendingTasks(); 534 535 // The saved match has the right username already. 536 PasswordForm login(*observed_form()); 537 login.username_value = saved_match()->username_value; 538 login.password_value = saved_match()->password_value; 539 login.preferred = true; 540 manager.ProvisionallySave( 541 login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES); 542 543 EXPECT_FALSE(manager.IsNewLogin()); 544 manager.Save(); 545 RunAllPendingTasks(); 546 547 // Should be only one password stored, and should not have 548 // |other_possible_usernames| set anymore. 549 TestPasswordStore::PasswordMap passwords = password_store->stored_passwords(); 550 EXPECT_EQ(1U, passwords.size()); 551 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size()); 552 EXPECT_EQ(saved_match()->username_value, 553 passwords[saved_match()->signon_realm][0].username_value); 554 EXPECT_EQ(0U, 555 passwords[saved_match()->signon_realm][0] 556 .other_possible_usernames.size()); 557 558 // This time use an alternate username 559 PasswordFormManager manager_alt(&password_manager, 560 &client_with_store, 561 client_with_store.GetDriver(), 562 *observed_form(), 563 false); 564 EXPECT_CALL(*client_with_store.GetMockDriver(), 565 AllowPasswordGenerationForForm(_)).Times(1); 566 password_store->Clear(); 567 password_store->AddLogin(*saved_match()); 568 manager_alt.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT); 569 RunAllPendingTasks(); 570 571 base::string16 new_username = saved_match()->other_possible_usernames[0]; 572 login.username_value = new_username; 573 manager_alt.ProvisionallySave( 574 login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES); 575 576 EXPECT_FALSE(manager_alt.IsNewLogin()); 577 manager_alt.Save(); 578 RunAllPendingTasks(); 579 580 // |other_possible_usernames| should also be empty, but username_value should 581 // be changed to match |new_username| 582 passwords = password_store->stored_passwords(); 583 EXPECT_EQ(1U, passwords.size()); 584 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size()); 585 EXPECT_EQ(new_username, 586 passwords[saved_match()->signon_realm][0].username_value); 587 EXPECT_EQ(0U, 588 passwords[saved_match()->signon_realm][0] 589 .other_possible_usernames.size()); 590 password_store->Shutdown(); 591 } 592 593 TEST_F(PasswordFormManagerTest, TestValidForms) { 594 // User submits credentials for the observed form. 595 PasswordForm credentials = *observed_form(); 596 credentials.scheme = PasswordForm::SCHEME_HTML; 597 credentials.username_value = saved_match()->username_value; 598 credentials.password_value = saved_match()->password_value; 599 600 // An alternate version of the form that also has a new_password_element. 601 PasswordForm new_credentials(*observed_form()); 602 new_credentials.new_password_element = ASCIIToUTF16("NewPasswd"); 603 new_credentials.new_password_value = ASCIIToUTF16("test1new"); 604 605 // Form with both username_element and password_element. 606 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false); 607 SimulateMatchingPhase(&manager1, RESULT_NO_MATCH); 608 EXPECT_TRUE(manager1.HasValidPasswordForm()); 609 610 // Form with username_element, password_element, and new_password_element. 611 PasswordFormManager manager2(NULL, NULL, NULL, new_credentials, false); 612 SimulateMatchingPhase(&manager2, RESULT_NO_MATCH); 613 EXPECT_TRUE(manager2.HasValidPasswordForm()); 614 615 // Form with username_element and only new_password_element. 616 new_credentials.password_element.clear(); 617 PasswordFormManager manager3(NULL, NULL, NULL, new_credentials, false); 618 SimulateMatchingPhase(&manager3, RESULT_NO_MATCH); 619 EXPECT_TRUE(manager3.HasValidPasswordForm()); 620 621 // Form without a username_element but with a password_element. 622 credentials.username_element.clear(); 623 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false); 624 SimulateMatchingPhase(&manager4, RESULT_NO_MATCH); 625 EXPECT_TRUE(manager4.HasValidPasswordForm()); 626 627 // Form without a username_element but with a new_password_element. 628 new_credentials.username_element.clear(); 629 PasswordFormManager manager5(NULL, NULL, NULL, new_credentials, false); 630 SimulateMatchingPhase(&manager5, RESULT_NO_MATCH); 631 EXPECT_TRUE(manager5.HasValidPasswordForm()); 632 633 // Form without a password_element but with a username_element. 634 credentials.username_element = saved_match()->username_element; 635 credentials.password_element.clear(); 636 PasswordFormManager manager6(NULL, NULL, NULL, credentials, false); 637 SimulateMatchingPhase(&manager6, RESULT_NO_MATCH); 638 EXPECT_FALSE(manager6.HasValidPasswordForm()); 639 640 // Form with neither a password_element nor a username_element. 641 credentials.username_element.clear(); 642 credentials.password_element.clear(); 643 PasswordFormManager manager7(NULL, NULL, NULL, credentials, false); 644 SimulateMatchingPhase(&manager7, RESULT_NO_MATCH); 645 EXPECT_FALSE(manager7.HasValidPasswordForm()); 646 } 647 648 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) { 649 // User submits credentials for the observed form. 650 PasswordForm credentials = *observed_form(); 651 credentials.scheme = PasswordForm::SCHEME_BASIC; 652 credentials.username_value = saved_match()->username_value; 653 credentials.password_value = saved_match()->password_value; 654 655 // Form with both username_element and password_element. 656 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false); 657 SimulateMatchingPhase(&manager1, RESULT_NO_MATCH); 658 EXPECT_TRUE(manager1.HasValidPasswordForm()); 659 660 // Form without a username_element but with a password_element. 661 credentials.username_element.clear(); 662 PasswordFormManager manager2(NULL, NULL, NULL, credentials, false); 663 SimulateMatchingPhase(&manager2, RESULT_NO_MATCH); 664 EXPECT_TRUE(manager2.HasValidPasswordForm()); 665 666 // Form without a password_element but with a username_element. 667 credentials.username_element = saved_match()->username_element; 668 credentials.password_element.clear(); 669 PasswordFormManager manager3(NULL, NULL, NULL, credentials, false); 670 SimulateMatchingPhase(&manager3, RESULT_NO_MATCH); 671 EXPECT_TRUE(manager3.HasValidPasswordForm()); 672 673 // Form with neither a password_element nor a username_element. 674 credentials.username_element.clear(); 675 credentials.password_element.clear(); 676 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false); 677 SimulateMatchingPhase(&manager4, RESULT_NO_MATCH); 678 EXPECT_TRUE(manager4.HasValidPasswordForm()); 679 } 680 681 TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) { 682 base::MessageLoop message_loop; 683 684 TestPasswordManager password_manager(client()); 685 PasswordFormManager manager_no_creds(&password_manager, 686 client(), 687 client()->GetDriver(), 688 *observed_form(), 689 false); 690 691 // First time sign-up attempt. Password store does not contain matching 692 // credentials. AllowPasswordGenerationForForm should be called to send the 693 // "not blacklisted" message. 694 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_)) 695 .Times(1); 696 SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_creds); 697 std::vector<PasswordForm*> result; 698 SimulateResponseFromPasswordStore(&manager_no_creds, result); 699 Mock::VerifyAndClearExpectations(client()->GetMockDriver()); 700 701 // Signing up on a previously visited site. Credentials are found in the 702 // password store, and are not blacklisted. AllowPasswordGenerationForForm 703 // should be called to send the "not blacklisted" message. 704 PasswordFormManager manager_creds(&password_manager, 705 client(), 706 client()->GetDriver(), 707 *observed_form(), 708 false); 709 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_)) 710 .Times(1); 711 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord()) 712 .WillRepeatedly(Return(false)); 713 SimulateFetchMatchingLoginsFromPasswordStore(&manager_creds); 714 // We need add heap allocated objects to result. 715 result.push_back(CreateSavedMatch(false)); 716 SimulateResponseFromPasswordStore(&manager_creds, result); 717 Mock::VerifyAndClearExpectations(client()->GetMockDriver()); 718 719 // There are cases, such as when a form is explicitly for creating a new 720 // password, where we may ignore saved credentials. Make sure that we still 721 // allow generation in that case. 722 PasswordForm signup_form(*observed_form()); 723 signup_form.new_password_element = base::ASCIIToUTF16("new_password_field"); 724 725 PasswordFormManager manager_dropped_creds(&password_manager, 726 client(), 727 client()->GetDriver(), 728 signup_form, 729 false); 730 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_)) 731 .Times(1); 732 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord()) 733 .WillRepeatedly(Return(false)); 734 SimulateFetchMatchingLoginsFromPasswordStore(&manager_dropped_creds); 735 result.clear(); 736 result.push_back(CreateSavedMatch(false)); 737 SimulateResponseFromPasswordStore(&manager_dropped_creds, result); 738 Mock::VerifyAndClearExpectations(client()->GetMockDriver()); 739 740 // Signing up on a previously visited site. Credentials are found in the 741 // password store, but they are blacklisted. AllowPasswordGenerationForForm 742 // should not be called and no "not blacklisted" message sent. 743 PasswordFormManager manager_blacklisted(&password_manager, 744 client(), 745 client()->GetDriver(), 746 *observed_form(), 747 false); 748 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_)) 749 .Times(0); 750 SimulateFetchMatchingLoginsFromPasswordStore(&manager_blacklisted); 751 result.clear(); 752 result.push_back(CreateSavedMatch(true)); 753 SimulateResponseFromPasswordStore(&manager_blacklisted, result); 754 Mock::VerifyAndClearExpectations(client()->GetMockDriver()); 755 } 756 757 TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) { 758 base::MessageLoop message_loop; 759 760 // Simulate having two matches for this origin, one of which was from a form 761 // with different HTML tags for elements. Because of scoring differences, 762 // only the first form will be sent to Autofill(). 763 TestPasswordManager password_manager(client()); 764 PasswordFormManager manager_match(&password_manager, 765 client(), 766 client()->GetDriver(), 767 *observed_form(), 768 false); 769 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_)) 770 .Times(1); 771 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord()) 772 .WillRepeatedly(Return(false)); 773 774 std::vector<PasswordForm*> results; 775 results.push_back(CreateSavedMatch(false)); 776 results.push_back(CreateSavedMatch(false)); 777 results[1]->username_value = ASCIIToUTF16("other (at) gmail.com"); 778 results[1]->password_element = ASCIIToUTF16("signup_password"); 779 results[1]->username_element = ASCIIToUTF16("signup_username"); 780 SimulateFetchMatchingLoginsFromPasswordStore(&manager_match); 781 SimulateResponseFromPasswordStore(&manager_match, results); 782 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size()); 783 results.clear(); 784 785 // Same thing, except this time the credentials that don't match quite as 786 // well are generated. They should now be sent to Autofill(). 787 PasswordFormManager manager_no_match(&password_manager, 788 client(), 789 client()->GetDriver(), 790 *observed_form(), 791 false); 792 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_)) 793 .Times(1); 794 795 results.push_back(CreateSavedMatch(false)); 796 results.push_back(CreateSavedMatch(false)); 797 results[1]->username_value = ASCIIToUTF16("other (at) gmail.com"); 798 results[1]->password_element = ASCIIToUTF16("signup_password"); 799 results[1]->username_element = ASCIIToUTF16("signup_username"); 800 results[1]->type = PasswordForm::TYPE_GENERATED; 801 SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_match); 802 SimulateResponseFromPasswordStore(&manager_no_match, results); 803 EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size()); 804 } 805 806 TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) { 807 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 808 PasswordForm credentials(*observed_form()); 809 credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234")); 810 credentials.other_possible_usernames.push_back( 811 ASCIIToUTF16("378282246310005")); 812 credentials.other_possible_usernames.push_back( 813 ASCIIToUTF16("other username")); 814 credentials.username_value = ASCIIToUTF16("test (at) gmail.com"); 815 816 SanitizePossibleUsernames(&manager, &credentials); 817 818 // Possible credit card number and SSN are stripped. 819 std::vector<base::string16> expected; 820 expected.push_back(ASCIIToUTF16("other username")); 821 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected)); 822 823 credentials.other_possible_usernames.clear(); 824 credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830")); 825 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate")); 826 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate")); 827 credentials.other_possible_usernames.push_back(ASCIIToUTF16("random")); 828 credentials.other_possible_usernames.push_back( 829 ASCIIToUTF16("test (at) gmail.com")); 830 831 SanitizePossibleUsernames(&manager, &credentials); 832 833 // SSN, duplicate in |other_possible_usernames| and duplicate of 834 // |username_value| all removed. 835 expected.clear(); 836 expected.push_back(ASCIIToUTF16("duplicate")); 837 expected.push_back(ASCIIToUTF16("random")); 838 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected)); 839 } 840 841 TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) { 842 InitializeMockStore(); 843 844 // We've found this form on a website: 845 PasswordForm encountered_form; 846 encountered_form.origin = GURL("http://accounts.google.com/LoginAuth"); 847 encountered_form.signon_realm = "http://accounts.google.com/"; 848 encountered_form.action = GURL("http://accounts.google.com/Login"); 849 encountered_form.username_element = ASCIIToUTF16("Email"); 850 encountered_form.password_element = ASCIIToUTF16("Passwd"); 851 encountered_form.submit_element = ASCIIToUTF16("signIn"); 852 853 TestPasswordManagerClient client_with_store(mock_store()); 854 EXPECT_CALL(*(client_with_store.GetMockDriver()), IsOffTheRecord()) 855 .WillRepeatedly(Return(false)); 856 EXPECT_CALL(*(client_with_store.GetMockDriver()), 857 AllowPasswordGenerationForForm(_)); 858 859 TestPasswordManager manager(&client_with_store); 860 PasswordFormManager form_manager(&manager, 861 &client_with_store, 862 client_with_store.GetMockDriver(), 863 encountered_form, 864 false); 865 866 const PasswordStore::AuthorizationPromptPolicy auth_policy = 867 PasswordStore::DISALLOW_PROMPT; 868 EXPECT_CALL(*mock_store(), 869 GetLogins(encountered_form, auth_policy, &form_manager)); 870 form_manager.FetchMatchingLoginsFromPasswordStore(auth_policy); 871 872 // Password store only has these incomplete credentials. 873 PasswordForm* incomplete_form = new PasswordForm(); 874 incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth"); 875 incomplete_form->signon_realm = "http://accounts.google.com/"; 876 incomplete_form->password_value = ASCIIToUTF16("my_password"); 877 incomplete_form->username_value = ASCIIToUTF16("my_username"); 878 incomplete_form->preferred = true; 879 incomplete_form->ssl_valid = false; 880 incomplete_form->scheme = PasswordForm::SCHEME_HTML; 881 882 // We expect to see this form eventually sent to the Password store. It 883 // has password/username values from the store and 'username_element', 884 // 'password_element', 'submit_element' and 'action' fields copied from 885 // the encountered form. 886 PasswordForm complete_form(*incomplete_form); 887 complete_form.action = encountered_form.action; 888 complete_form.password_element = encountered_form.password_element; 889 complete_form.username_element = encountered_form.username_element; 890 complete_form.submit_element = encountered_form.submit_element; 891 892 PasswordForm obsolete_form(*incomplete_form); 893 obsolete_form.action = encountered_form.action; 894 895 // Feed the incomplete credentials to the manager. 896 std::vector<PasswordForm*> results; 897 results.push_back(incomplete_form); // Takes ownership. 898 form_manager.OnRequestDone(results); 899 900 form_manager.ProvisionallySave( 901 complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 902 // By now that form has been used once. 903 complete_form.times_used = 1; 904 obsolete_form.times_used = 1; 905 906 // Check that PasswordStore receives an update request with the complete form. 907 EXPECT_CALL(*mock_store(), RemoveLogin(obsolete_form)); 908 EXPECT_CALL(*mock_store(), AddLogin(complete_form)); 909 form_manager.Save(); 910 } 911 912 TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) { 913 base::MessageLoop message_loop; 914 915 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord()) 916 .WillRepeatedly(Return(false)); 917 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_)); 918 919 TestPasswordManager password_manager(client()); 920 PasswordFormManager manager(&password_manager, 921 client(), 922 client()->GetMockDriver(), 923 *observed_form(), 924 false); 925 926 // Simulate having two matches for this form, first comes from different 927 // signon realm, but reports the same origin and action as matched form. 928 // Second candidate has the same signon realm as the form, but has a different 929 // origin and action. Public suffix match is the most important criterion so 930 // the second candidate should be selected. 931 std::vector<PasswordForm*> results; 932 results.push_back(CreateSavedMatch(false)); 933 results.push_back(CreateSavedMatch(false)); 934 results[0]->original_signon_realm = "http://accounts2.google.com"; 935 results[1]->origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2"); 936 results[1]->action = GURL("http://accounts.google.com/a/ServiceLogin2"); 937 SimulateFetchMatchingLoginsFromPasswordStore(&manager); 938 SimulateResponseFromPasswordStore(&manager, results); 939 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size()); 940 EXPECT_EQ("", password_manager.GetLatestBestMatches().begin() 941 ->second->original_signon_realm); 942 } 943 944 TEST_F(PasswordFormManagerTest, InvalidActionURLsDoNotMatch) { 945 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 946 947 PasswordForm invalid_action_form(*observed_form()); 948 invalid_action_form.action = GURL("http://"); 949 ASSERT_FALSE(invalid_action_form.action.is_valid()); 950 ASSERT_FALSE(invalid_action_form.action.is_empty()); 951 // Non-empty invalid action URLs should not match other actions. 952 // First when the compared form has an invalid URL: 953 EXPECT_EQ(0, 954 manager.DoesManage(invalid_action_form) & 955 PasswordFormManager::RESULT_ACTION_MATCH); 956 // Then when the observed form has an invalid URL: 957 PasswordForm valid_action_form(*observed_form()); 958 PasswordFormManager invalid_manager( 959 NULL, client(), NULL, invalid_action_form, false); 960 EXPECT_EQ(0, 961 invalid_manager.DoesManage(valid_action_form) & 962 PasswordFormManager::RESULT_ACTION_MATCH); 963 } 964 965 TEST_F(PasswordFormManagerTest, EmptyActionURLsDoNotMatchNonEmpty) { 966 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 967 968 PasswordForm empty_action_form(*observed_form()); 969 empty_action_form.action = GURL(); 970 ASSERT_FALSE(empty_action_form.action.is_valid()); 971 ASSERT_TRUE(empty_action_form.action.is_empty()); 972 // First when the compared form has an empty URL: 973 EXPECT_EQ(0, 974 manager.DoesManage(empty_action_form) & 975 PasswordFormManager::RESULT_ACTION_MATCH); 976 // Then when the observed form has an empty URL: 977 PasswordForm valid_action_form(*observed_form()); 978 PasswordFormManager empty_action_manager( 979 NULL, client(), NULL, empty_action_form, false); 980 EXPECT_EQ(0, 981 empty_action_manager.DoesManage(valid_action_form) & 982 PasswordFormManager::RESULT_ACTION_MATCH); 983 } 984 985 TEST_F(PasswordFormManagerTest, NonHTMLFormsDoNotMatchHTMLForms) { 986 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 987 988 ASSERT_EQ(PasswordForm::SCHEME_HTML, observed_form()->scheme); 989 PasswordForm non_html_form(*observed_form()); 990 non_html_form.scheme = PasswordForm::SCHEME_DIGEST; 991 EXPECT_EQ(0, 992 manager.DoesManage(non_html_form) & 993 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH); 994 995 // The other way round: observing a non-HTML form, don't match a HTML form. 996 PasswordForm html_form(*observed_form()); 997 PasswordFormManager non_html_manager( 998 NULL, client(), NULL, non_html_form, false); 999 EXPECT_EQ(0, 1000 non_html_manager.DoesManage(html_form) & 1001 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH); 1002 } 1003 1004 TEST_F(PasswordFormManagerTest, OriginCheck_HostsMatchExactly) { 1005 // Host part of origins must match exactly, not just by prefix. 1006 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 1007 1008 PasswordForm form_longer_host(*observed_form()); 1009 form_longer_host.origin = GURL("http://accounts.google.com.au/a/LoginAuth"); 1010 // Check that accounts.google.com does not match accounts.google.com.au. 1011 EXPECT_EQ(0, 1012 manager.DoesManage(form_longer_host) & 1013 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH); 1014 } 1015 1016 TEST_F(PasswordFormManagerTest, OriginCheck_MoreSecureSchemePathsMatchPrefix) { 1017 // If the URL scheme of the observed form is HTTP, and the compared form is 1018 // HTTPS, then the compared form can extend the path. 1019 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 1020 1021 PasswordForm form_longer_path(*observed_form()); 1022 form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec"); 1023 EXPECT_NE(0, 1024 manager.DoesManage(form_longer_path) & 1025 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH); 1026 } 1027 1028 TEST_F(PasswordFormManagerTest, 1029 OriginCheck_NotMoreSecureSchemePathsMatchExactly) { 1030 // If the origin URL scheme of the compared form is not more secure than that 1031 // of the observed form, then the paths must match exactly. 1032 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false); 1033 1034 PasswordForm form_longer_path(*observed_form()); 1035 form_longer_path.origin = GURL("http://accounts.google.com/a/LoginAuth/sec"); 1036 // Check that /a/LoginAuth does not match /a/LoginAuth/more. 1037 EXPECT_EQ(0, 1038 manager.DoesManage(form_longer_path) & 1039 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH); 1040 1041 PasswordForm secure_observed_form(*observed_form()); 1042 secure_observed_form.origin = GURL("https://accounts.google.com/a/LoginAuth"); 1043 PasswordFormManager secure_manager( 1044 NULL, client(), NULL, secure_observed_form, true); 1045 // Also for HTTPS in the observed form, and HTTP in the compared form, an 1046 // exact path match is expected. 1047 EXPECT_EQ(0, 1048 secure_manager.DoesManage(form_longer_path) & 1049 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH); 1050 // Not even upgrade to HTTPS in the compared form should help. 1051 form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec"); 1052 EXPECT_EQ(0, 1053 secure_manager.DoesManage(form_longer_path) & 1054 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH); 1055 } 1056 1057 TEST_F(PasswordFormManagerTest, CorrectlyUpdatePasswordsWithSameUsername) { 1058 // Need a MessageLoop for callbacks. 1059 base::MessageLoop message_loop; 1060 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore; 1061 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), "")); 1062 1063 TestPasswordManagerClient client_with_store(password_store.get()); 1064 TestPasswordManager password_manager(&client_with_store); 1065 EXPECT_CALL(*client_with_store.GetMockDriver(), 1066 AllowPasswordGenerationForForm(_)).Times(2); 1067 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord()) 1068 .WillRepeatedly(Return(false)); 1069 1070 // Add two credentials with the same username. Both should score the same 1071 // and be seen as candidates to autofill. 1072 PasswordForm first(*saved_match()); 1073 first.action = observed_form()->action; 1074 first.password_value = ASCIIToUTF16("first"); 1075 password_store->AddLogin(first); 1076 1077 PasswordForm second(first); 1078 second.origin = GURL("http://accounts.google.com/a/AddLogin"); 1079 second.password_value = ASCIIToUTF16("second"); 1080 second.preferred = false; 1081 password_store->AddLogin(second); 1082 1083 PasswordFormManager storing_manager(&password_manager, 1084 &client_with_store, 1085 client_with_store.GetDriver(), 1086 *observed_form(), 1087 false); 1088 storing_manager.FetchMatchingLoginsFromPasswordStore( 1089 PasswordStore::ALLOW_PROMPT); 1090 RunAllPendingTasks(); 1091 1092 // We always take the last credential with a particular username, regardless 1093 // of which ones are labeled preferred. 1094 EXPECT_EQ(ASCIIToUTF16("second"), 1095 storing_manager.preferred_match()->password_value); 1096 1097 PasswordForm login(*observed_form()); 1098 login.username_value = saved_match()->username_value; 1099 login.password_value = ASCIIToUTF16("third"); 1100 login.preferred = true; 1101 storing_manager.ProvisionallySave( 1102 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 1103 1104 EXPECT_FALSE(storing_manager.IsNewLogin()); 1105 storing_manager.Save(); 1106 RunAllPendingTasks(); 1107 1108 PasswordFormManager retrieving_manager(&password_manager, 1109 &client_with_store, 1110 client_with_store.GetDriver(), 1111 *observed_form(), 1112 false); 1113 1114 retrieving_manager.FetchMatchingLoginsFromPasswordStore( 1115 PasswordStore::ALLOW_PROMPT); 1116 RunAllPendingTasks(); 1117 1118 // Make sure that the preferred match is updated appropriately. 1119 EXPECT_EQ(ASCIIToUTF16("third"), 1120 retrieving_manager.preferred_match()->password_value); 1121 password_store->Shutdown(); 1122 } 1123 1124 TEST_F(PasswordFormManagerTest, UploadFormData_NewPassword) { 1125 InitializeMockStore(); 1126 TestPasswordManagerClient client_with_store(mock_store()); 1127 TestPasswordManager password_manager(&client_with_store); 1128 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord()) 1129 .WillRepeatedly(Return(false)); 1130 1131 PasswordForm form(*observed_form()); 1132 1133 autofill::FormFieldData field; 1134 field.label = ASCIIToUTF16("full_name"); 1135 field.name = ASCIIToUTF16("full_name"); 1136 field.form_control_type = "text"; 1137 form.form_data.fields.push_back(field); 1138 1139 field.label = ASCIIToUTF16("Email"); 1140 field.name = ASCIIToUTF16("Email"); 1141 field.form_control_type = "text"; 1142 form.form_data.fields.push_back(field); 1143 1144 field.label = ASCIIToUTF16("password"); 1145 field.name = ASCIIToUTF16("password"); 1146 field.form_control_type = "password"; 1147 form.form_data.fields.push_back(field); 1148 1149 // For newly saved passwords, upload a vote for autofill::PASSWORD. 1150 MockPasswordFormManager form_manager(&password_manager, 1151 &client_with_store, 1152 client_with_store.GetDriver(), 1153 form, 1154 false); 1155 SimulateMatchingPhase(&form_manager, RESULT_NO_MATCH); 1156 1157 PasswordForm form_to_save(form); 1158 form_to_save.preferred = true; 1159 form_to_save.username_value = ASCIIToUTF16("username"); 1160 form_to_save.password_value = ASCIIToUTF16("1234"); 1161 1162 EXPECT_CALL(form_manager, UploadPasswordForm(_, autofill::PASSWORD)).Times(1); 1163 form_manager.ProvisionallySave( 1164 form_to_save, 1165 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 1166 form_manager.Save(); 1167 Mock::VerifyAndClearExpectations(&form_manager); 1168 1169 // Do not upload a vote if the user is blacklisting the form. 1170 MockPasswordFormManager blacklist_form_manager(&password_manager, 1171 &client_with_store, 1172 client_with_store.GetDriver(), 1173 form, 1174 false); 1175 SimulateMatchingPhase(&blacklist_form_manager, RESULT_NO_MATCH); 1176 1177 EXPECT_CALL(blacklist_form_manager, 1178 UploadPasswordForm(_, autofill::PASSWORD)).Times(0); 1179 blacklist_form_manager.PermanentlyBlacklist(); 1180 Mock::VerifyAndClearExpectations(&blacklist_form_manager); 1181 } 1182 1183 TEST_F(PasswordFormManagerTest, UploadFormData_AccountCreationPassword) { 1184 InitializeMockStore(); 1185 TestPasswordManagerClient client_with_store(mock_store()); 1186 TestPasswordManager password_manager(&client_with_store); 1187 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord()) 1188 .WillRepeatedly(Return(false)); 1189 1190 PasswordForm form(*observed_form()); 1191 1192 autofill::FormFieldData field; 1193 field.label = ASCIIToUTF16("Email"); 1194 field.name = ASCIIToUTF16("Email"); 1195 field.form_control_type = "text"; 1196 form.form_data.fields.push_back(field); 1197 1198 field.label = ASCIIToUTF16("password"); 1199 field.name = ASCIIToUTF16("password"); 1200 field.form_control_type = "password"; 1201 form.form_data.fields.push_back(field); 1202 1203 MockPasswordFormManager form_manager(&password_manager, 1204 &client_with_store, 1205 client_with_store.GetDriver(), 1206 form, 1207 false); 1208 std::vector<PasswordForm*> result; 1209 result.push_back(CreateSavedMatch(false)); 1210 1211 field.label = ASCIIToUTF16("full_name"); 1212 field.name = ASCIIToUTF16("full_name"); 1213 field.form_control_type = "text"; 1214 result[0]->form_data.fields.push_back(field); 1215 1216 field.label = ASCIIToUTF16("Email"); 1217 field.name = ASCIIToUTF16("Email"); 1218 field.form_control_type = "text"; 1219 result[0]->form_data.fields.push_back(field); 1220 1221 field.label = ASCIIToUTF16("password"); 1222 field.name = ASCIIToUTF16("password"); 1223 field.form_control_type = "password"; 1224 result[0]->form_data.fields.push_back(field); 1225 1226 PasswordForm form_to_save(form); 1227 form_to_save.preferred = true; 1228 form_to_save.username_value = result[0]->username_value; 1229 form_to_save.password_value = result[0]->password_value; 1230 1231 SimulateFetchMatchingLoginsFromPasswordStore(&form_manager); 1232 SimulateResponseFromPasswordStore(&form_manager, result); 1233 1234 EXPECT_CALL(form_manager, 1235 UploadPasswordForm(_, 1236 autofill::ACCOUNT_CREATION_PASSWORD)).Times(1); 1237 form_manager.ProvisionallySave( 1238 form_to_save, 1239 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 1240 form_manager.Save(); 1241 } 1242 1243 TEST_F(PasswordFormManagerTest, CorrectlySavePasswordWithoutUsernameFields) { 1244 // Need a MessageLoop for callbacks. 1245 base::MessageLoop message_loop; 1246 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore; 1247 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), "")); 1248 1249 TestPasswordManagerClient client_with_store(password_store.get()); 1250 TestPasswordManager password_manager(&client_with_store); 1251 EXPECT_CALL(*client_with_store.GetMockDriver(), 1252 AllowPasswordGenerationForForm(_)).Times(2); 1253 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord()) 1254 .WillRepeatedly(Return(false)); 1255 1256 PasswordForm form(*observed_form()); 1257 form.username_element.clear(); 1258 form.password_value = ASCIIToUTF16("password"); 1259 form.preferred = true; 1260 1261 PasswordFormManager storing_manager(&password_manager, 1262 &client_with_store, 1263 client_with_store.GetDriver(), 1264 *observed_form(), 1265 false); 1266 storing_manager.FetchMatchingLoginsFromPasswordStore( 1267 PasswordStore::ALLOW_PROMPT); 1268 RunAllPendingTasks(); 1269 1270 storing_manager.ProvisionallySave( 1271 form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES); 1272 1273 EXPECT_TRUE(storing_manager.IsNewLogin()); 1274 storing_manager.Save(); 1275 RunAllPendingTasks(); 1276 1277 PasswordFormManager retrieving_manager(&password_manager, 1278 &client_with_store, 1279 client_with_store.GetDriver(), 1280 *observed_form(), 1281 false); 1282 1283 retrieving_manager.FetchMatchingLoginsFromPasswordStore( 1284 PasswordStore::ALLOW_PROMPT); 1285 RunAllPendingTasks(); 1286 1287 // Make sure that the preferred match is updated appropriately. 1288 EXPECT_EQ(ASCIIToUTF16("password"), 1289 retrieving_manager.preferred_match()->password_value); 1290 password_store->Shutdown(); 1291 } 1292 1293 } // namespace password_manager 1294