| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/files/scoped_temp_dir.h" | 9 #include "base/files/scoped_temp_dir.h" |
| 10 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 27 | 27 |
| 28 using autofill::PasswordForm; | 28 using autofill::PasswordForm; |
| 29 using password_manager::ContainsAllPasswordForms; | 29 using password_manager::ContainsAllPasswordForms; |
| 30 using password_manager::PasswordStoreChange; | 30 using password_manager::PasswordStoreChange; |
| 31 using password_manager::PasswordStoreChangeList; | 31 using password_manager::PasswordStoreChangeList; |
| 32 using testing::_; | 32 using testing::_; |
| 33 using testing::ElementsAreArray; | 33 using testing::ElementsAreArray; |
| 34 using testing::WithArg; | 34 using testing::WithArg; |
| 35 | 35 |
| 36 typedef std::vector<PasswordForm*> VectorOfForms; | |
| 37 | |
| 38 namespace { | 36 namespace { |
| 39 | 37 |
| 40 class MockPasswordStoreConsumer | 38 class MockPasswordStoreConsumer |
| 41 : public password_manager::PasswordStoreConsumer { | 39 : public password_manager::PasswordStoreConsumer { |
| 42 public: | 40 public: |
| 43 MOCK_METHOD1(OnGetPasswordStoreResults, | 41 MOCK_METHOD1(OnGetPasswordStoreResults, |
| 44 void(const std::vector<PasswordForm*>&)); | 42 void(const std::vector<PasswordForm*>&)); |
| 45 }; | 43 }; |
| 46 | 44 |
| 47 class MockPasswordStoreObserver | 45 class MockPasswordStoreObserver |
| (...skipping 23 matching lines...) Expand all Loading... |
| 71 return false; | 69 return false; |
| 72 } | 70 } |
| 73 | 71 |
| 74 bool RemoveLoginsSyncedBetween( | 72 bool RemoveLoginsSyncedBetween( |
| 75 base::Time delete_begin, | 73 base::Time delete_begin, |
| 76 base::Time delete_end, | 74 base::Time delete_end, |
| 77 password_manager::PasswordStoreChangeList* changes) override { | 75 password_manager::PasswordStoreChangeList* changes) override { |
| 78 return false; | 76 return false; |
| 79 } | 77 } |
| 80 | 78 |
| 81 bool GetLogins(const PasswordForm& form, PasswordFormList* forms) override { | 79 bool GetLogins(const PasswordForm& form, |
| 80 ScopedVector<autofill::PasswordForm>* forms) override { |
| 82 return false; | 81 return false; |
| 83 } | 82 } |
| 84 | 83 |
| 85 bool GetAutofillableLogins(PasswordFormList* forms) override { return false; } | 84 bool GetAutofillableLogins( |
| 86 bool GetBlacklistLogins(PasswordFormList* forms) override { return false; } | 85 ScopedVector<autofill::PasswordForm>* forms) override { |
| 86 return false; |
| 87 } |
| 88 bool GetBlacklistLogins( |
| 89 ScopedVector<autofill::PasswordForm>* forms) override { |
| 90 return false; |
| 91 } |
| 87 }; | 92 }; |
| 88 | 93 |
| 89 class MockBackend : public PasswordStoreX::NativeBackend { | 94 class MockBackend : public PasswordStoreX::NativeBackend { |
| 90 public: | 95 public: |
| 91 bool Init() override { return true; } | 96 bool Init() override { return true; } |
| 92 | 97 |
| 93 PasswordStoreChangeList AddLogin(const PasswordForm& form) override { | 98 PasswordStoreChangeList AddLogin(const PasswordForm& form) override { |
| 94 all_forms_.push_back(form); | 99 all_forms_.push_back(form); |
| 95 PasswordStoreChange change(PasswordStoreChange::ADD, form); | 100 PasswordStoreChange change(PasswordStoreChange::ADD, form); |
| 96 return PasswordStoreChangeList(1, change); | 101 return PasswordStoreChangeList(1, change); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 if (delete_begin <= all_forms_[i].date_synced && | 140 if (delete_begin <= all_forms_[i].date_synced && |
| 136 (delete_end.is_null() || all_forms_[i].date_synced < delete_end)) { | 141 (delete_end.is_null() || all_forms_[i].date_synced < delete_end)) { |
| 137 changes->push_back(password_manager::PasswordStoreChange( | 142 changes->push_back(password_manager::PasswordStoreChange( |
| 138 password_manager::PasswordStoreChange::REMOVE, all_forms_[i])); | 143 password_manager::PasswordStoreChange::REMOVE, all_forms_[i])); |
| 139 erase(i--); | 144 erase(i--); |
| 140 } | 145 } |
| 141 } | 146 } |
| 142 return true; | 147 return true; |
| 143 } | 148 } |
| 144 | 149 |
| 145 bool GetLogins(const PasswordForm& form, PasswordFormList* forms) override { | 150 bool GetLogins(const PasswordForm& form, |
| 151 ScopedVector<autofill::PasswordForm>* forms) override { |
| 146 for (size_t i = 0; i < all_forms_.size(); ++i) | 152 for (size_t i = 0; i < all_forms_.size(); ++i) |
| 147 if (all_forms_[i].signon_realm == form.signon_realm) | 153 if (all_forms_[i].signon_realm == form.signon_realm) |
| 148 forms->push_back(new PasswordForm(all_forms_[i])); | 154 forms->push_back(new PasswordForm(all_forms_[i])); |
| 149 return true; | 155 return true; |
| 150 } | 156 } |
| 151 | 157 |
| 152 bool GetAutofillableLogins(PasswordFormList* forms) override { | 158 bool GetAutofillableLogins( |
| 159 ScopedVector<autofill::PasswordForm>* forms) override { |
| 153 for (size_t i = 0; i < all_forms_.size(); ++i) | 160 for (size_t i = 0; i < all_forms_.size(); ++i) |
| 154 if (!all_forms_[i].blacklisted_by_user) | 161 if (!all_forms_[i].blacklisted_by_user) |
| 155 forms->push_back(new PasswordForm(all_forms_[i])); | 162 forms->push_back(new PasswordForm(all_forms_[i])); |
| 156 return true; | 163 return true; |
| 157 } | 164 } |
| 158 | 165 |
| 159 bool GetBlacklistLogins(PasswordFormList* forms) override { | 166 bool GetBlacklistLogins( |
| 167 ScopedVector<autofill::PasswordForm>* forms) override { |
| 160 for (size_t i = 0; i < all_forms_.size(); ++i) | 168 for (size_t i = 0; i < all_forms_.size(); ++i) |
| 161 if (all_forms_[i].blacklisted_by_user) | 169 if (all_forms_[i].blacklisted_by_user) |
| 162 forms->push_back(new PasswordForm(all_forms_[i])); | 170 forms->push_back(new PasswordForm(all_forms_[i])); |
| 163 return true; | 171 return true; |
| 164 } | 172 } |
| 165 | 173 |
| 166 private: | 174 private: |
| 167 void erase(size_t index) { | 175 void erase(size_t index) { |
| 168 if (index < all_forms_.size() - 1) | 176 if (index < all_forms_.size() - 1) |
| 169 all_forms_[index] = all_forms_[all_forms_.size() - 1]; | 177 all_forms_[index] = all_forms_[all_forms_.size() - 1]; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 186 | 194 |
| 187 class MockLoginDatabaseReturn { | 195 class MockLoginDatabaseReturn { |
| 188 public: | 196 public: |
| 189 MOCK_METHOD1(OnLoginDatabaseQueryDone, | 197 MOCK_METHOD1(OnLoginDatabaseQueryDone, |
| 190 void(const std::vector<PasswordForm*>&)); | 198 void(const std::vector<PasswordForm*>&)); |
| 191 }; | 199 }; |
| 192 | 200 |
| 193 void LoginDatabaseQueryCallback(password_manager::LoginDatabase* login_db, | 201 void LoginDatabaseQueryCallback(password_manager::LoginDatabase* login_db, |
| 194 bool autofillable, | 202 bool autofillable, |
| 195 MockLoginDatabaseReturn* mock_return) { | 203 MockLoginDatabaseReturn* mock_return) { |
| 196 std::vector<PasswordForm*> forms; | 204 ScopedVector<autofill::PasswordForm> forms; |
| 197 if (autofillable) | 205 if (autofillable) |
| 198 login_db->GetAutofillableLogins(&forms); | 206 login_db->GetAutofillableLogins(&forms); |
| 199 else | 207 else |
| 200 login_db->GetBlacklistLogins(&forms); | 208 login_db->GetBlacklistLogins(&forms); |
| 201 mock_return->OnLoginDatabaseQueryDone(forms); | 209 mock_return->OnLoginDatabaseQueryDone(forms.get()); |
| 202 } | 210 } |
| 203 | 211 |
| 204 // Generate |count| expected logins, either auto-fillable or blacklisted. | 212 // Generate |count| expected logins, either auto-fillable or blacklisted. |
| 205 void InitExpectedForms(bool autofillable, size_t count, VectorOfForms* forms) { | 213 void InitExpectedForms(bool autofillable, |
| 214 size_t count, |
| 215 ScopedVector<autofill::PasswordForm>* forms) { |
| 206 const char* domain = autofillable ? "example" : "blacklisted"; | 216 const char* domain = autofillable ? "example" : "blacklisted"; |
| 207 for (size_t i = 0; i < count; ++i) { | 217 for (size_t i = 0; i < count; ++i) { |
| 208 std::string realm = base::StringPrintf("http://%zu.%s.com", i, domain); | 218 std::string realm = base::StringPrintf("http://%zu.%s.com", i, domain); |
| 209 std::string origin = base::StringPrintf("http://%zu.%s.com/origin", | 219 std::string origin = base::StringPrintf("http://%zu.%s.com/origin", |
| 210 i, domain); | 220 i, domain); |
| 211 std::string action = base::StringPrintf("http://%zu.%s.com/action", | 221 std::string action = base::StringPrintf("http://%zu.%s.com/action", |
| 212 i, domain); | 222 i, domain); |
| 213 password_manager::PasswordFormData data = { | 223 password_manager::PasswordFormData data = { |
| 214 PasswordForm::SCHEME_HTML, | 224 PasswordForm::SCHEME_HTML, |
| 215 realm.c_str(), | 225 realm.c_str(), |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 | 342 |
| 333 // Wait for PasswordStore to execute. | 343 // Wait for PasswordStore to execute. |
| 334 base::RunLoop().RunUntilIdle(); | 344 base::RunLoop().RunUntilIdle(); |
| 335 | 345 |
| 336 store->RemoveObserver(&observer); | 346 store->RemoveObserver(&observer); |
| 337 | 347 |
| 338 store->Shutdown(); | 348 store->Shutdown(); |
| 339 } | 349 } |
| 340 | 350 |
| 341 TEST_P(PasswordStoreXTest, NativeMigration) { | 351 TEST_P(PasswordStoreXTest, NativeMigration) { |
| 342 VectorOfForms expected_autofillable; | 352 ScopedVector<autofill::PasswordForm> expected_autofillable; |
| 343 InitExpectedForms(true, 50, &expected_autofillable); | 353 InitExpectedForms(true, 50, &expected_autofillable); |
| 344 | 354 |
| 345 VectorOfForms expected_blacklisted; | 355 ScopedVector<autofill::PasswordForm> expected_blacklisted; |
| 346 InitExpectedForms(false, 50, &expected_blacklisted); | 356 InitExpectedForms(false, 50, &expected_blacklisted); |
| 347 | 357 |
| 348 const base::FilePath login_db_file = test_login_db_file_path(); | 358 const base::FilePath login_db_file = test_login_db_file_path(); |
| 349 scoped_ptr<password_manager::LoginDatabase> login_db( | 359 scoped_ptr<password_manager::LoginDatabase> login_db( |
| 350 new password_manager::LoginDatabase(login_db_file)); | 360 new password_manager::LoginDatabase(login_db_file)); |
| 351 ASSERT_TRUE(login_db->Init()); | 361 ASSERT_TRUE(login_db->Init()); |
| 352 | 362 |
| 353 // Get the initial size of the login DB file, before we populate it. | 363 // Get the initial size of the login DB file, before we populate it. |
| 354 // This will be used later to make sure it gets back to this size. | 364 // This will be used later to make sure it gets back to this size. |
| 355 base::File::Info db_file_start_info; | 365 base::File::Info db_file_start_info; |
| 356 ASSERT_TRUE(base::GetFileInfo(login_db_file, &db_file_start_info)); | 366 ASSERT_TRUE(base::GetFileInfo(login_db_file, &db_file_start_info)); |
| 357 | 367 |
| 358 // Populate the login DB with logins that should be migrated. | 368 // Populate the login DB with logins that should be migrated. |
| 359 for (VectorOfForms::iterator it = expected_autofillable.begin(); | 369 for (const auto* form : expected_autofillable) { |
| 360 it != expected_autofillable.end(); ++it) { | 370 login_db->AddLogin(*form); |
| 361 login_db->AddLogin(**it); | |
| 362 } | 371 } |
| 363 for (VectorOfForms::iterator it = expected_blacklisted.begin(); | 372 for (const auto* form : expected_blacklisted) { |
| 364 it != expected_blacklisted.end(); ++it) { | 373 login_db->AddLogin(*form); |
| 365 login_db->AddLogin(**it); | |
| 366 } | 374 } |
| 367 | 375 |
| 368 // Get the new size of the login DB file. We expect it to be larger. | 376 // Get the new size of the login DB file. We expect it to be larger. |
| 369 base::File::Info db_file_full_info; | 377 base::File::Info db_file_full_info; |
| 370 ASSERT_TRUE(base::GetFileInfo(login_db_file, &db_file_full_info)); | 378 ASSERT_TRUE(base::GetFileInfo(login_db_file, &db_file_full_info)); |
| 371 EXPECT_GT(db_file_full_info.size, db_file_start_info.size); | 379 EXPECT_GT(db_file_full_info.size, db_file_start_info.size); |
| 372 | 380 |
| 373 // Initializing the PasswordStore shouldn't trigger a native migration (yet). | 381 // Initializing the PasswordStore shouldn't trigger a native migration (yet). |
| 374 login_db.reset(new password_manager::LoginDatabase(login_db_file)); | 382 login_db.reset(new password_manager::LoginDatabase(login_db_file)); |
| 375 scoped_refptr<PasswordStoreX> store(new PasswordStoreX( | 383 scoped_refptr<PasswordStoreX> store(new PasswordStoreX( |
| 376 base::MessageLoopProxy::current(), base::MessageLoopProxy::current(), | 384 base::MessageLoopProxy::current(), base::MessageLoopProxy::current(), |
| 377 login_db.Pass(), GetBackend())); | 385 login_db.Pass(), GetBackend())); |
| 378 store->Init(syncer::SyncableService::StartSyncFlare()); | 386 store->Init(syncer::SyncableService::StartSyncFlare()); |
| 379 | 387 |
| 380 MockPasswordStoreConsumer consumer; | 388 MockPasswordStoreConsumer consumer; |
| 381 | 389 |
| 382 // The autofillable forms should have been migrated to the native backend. | 390 // The autofillable forms should have been migrated to the native backend. |
| 383 EXPECT_CALL(consumer, | 391 EXPECT_CALL(consumer, OnGetPasswordStoreResults(ContainsAllPasswordForms( |
| 384 OnGetPasswordStoreResults( | 392 expected_autofillable.get()))) |
| 385 ContainsAllPasswordForms(expected_autofillable))) | |
| 386 .WillOnce(WithArg<0>(STLDeleteElements0())); | 393 .WillOnce(WithArg<0>(STLDeleteElements0())); |
| 387 | 394 |
| 388 store->GetAutofillableLogins(&consumer); | 395 store->GetAutofillableLogins(&consumer); |
| 389 base::RunLoop().RunUntilIdle(); | 396 base::RunLoop().RunUntilIdle(); |
| 390 | 397 |
| 391 // The blacklisted forms should have been migrated to the native backend. | 398 // The blacklisted forms should have been migrated to the native backend. |
| 392 EXPECT_CALL(consumer, | 399 EXPECT_CALL(consumer, OnGetPasswordStoreResults(ContainsAllPasswordForms( |
| 393 OnGetPasswordStoreResults(ContainsAllPasswordForms(expected_blacklisted))) | 400 expected_blacklisted.get()))) |
| 394 .WillOnce(WithArg<0>(STLDeleteElements0())); | 401 .WillOnce(WithArg<0>(STLDeleteElements0())); |
| 395 | 402 |
| 396 store->GetBlacklistLogins(&consumer); | 403 store->GetBlacklistLogins(&consumer); |
| 397 base::RunLoop().RunUntilIdle(); | 404 base::RunLoop().RunUntilIdle(); |
| 398 | 405 |
| 399 VectorOfForms empty; | 406 ScopedVector<autofill::PasswordForm> empty; |
| 400 MockLoginDatabaseReturn ld_return; | 407 MockLoginDatabaseReturn ld_return; |
| 401 | 408 |
| 402 if (GetParam() == WORKING_BACKEND) { | 409 if (GetParam() == WORKING_BACKEND) { |
| 403 // No autofillable logins should be left in the login DB. | 410 // No autofillable logins should be left in the login DB. |
| 404 EXPECT_CALL(ld_return, | 411 EXPECT_CALL(ld_return, OnLoginDatabaseQueryDone( |
| 405 OnLoginDatabaseQueryDone(ContainsAllPasswordForms(empty))); | 412 ContainsAllPasswordForms(empty.get()))); |
| 406 } else { | 413 } else { |
| 407 // The autofillable logins should still be in the login DB. | 414 // The autofillable logins should still be in the login DB. |
| 408 EXPECT_CALL(ld_return, | 415 EXPECT_CALL(ld_return, OnLoginDatabaseQueryDone(ContainsAllPasswordForms( |
| 409 OnLoginDatabaseQueryDone( | 416 expected_autofillable.get()))); |
| 410 ContainsAllPasswordForms(expected_autofillable))) | |
| 411 .WillOnce(WithArg<0>(STLDeleteElements0())); | |
| 412 } | 417 } |
| 413 | 418 |
| 414 LoginDatabaseQueryCallback(store->login_db(), true, &ld_return); | 419 LoginDatabaseQueryCallback(store->login_db(), true, &ld_return); |
| 415 | 420 |
| 416 // Wait for the login DB methods to execute. | 421 // Wait for the login DB methods to execute. |
| 417 base::RunLoop().RunUntilIdle(); | 422 base::RunLoop().RunUntilIdle(); |
| 418 | 423 |
| 419 if (GetParam() == WORKING_BACKEND) { | 424 if (GetParam() == WORKING_BACKEND) { |
| 420 // Likewise, no blacklisted logins should be left in the login DB. | 425 // Likewise, no blacklisted logins should be left in the login DB. |
| 421 EXPECT_CALL(ld_return, | 426 EXPECT_CALL(ld_return, OnLoginDatabaseQueryDone( |
| 422 OnLoginDatabaseQueryDone(ContainsAllPasswordForms(empty))); | 427 ContainsAllPasswordForms(empty.get()))); |
| 423 } else { | 428 } else { |
| 424 // The blacklisted logins should still be in the login DB. | 429 // The blacklisted logins should still be in the login DB. |
| 425 EXPECT_CALL(ld_return, | 430 EXPECT_CALL(ld_return, OnLoginDatabaseQueryDone(ContainsAllPasswordForms( |
| 426 OnLoginDatabaseQueryDone( | 431 expected_blacklisted.get()))); |
| 427 ContainsAllPasswordForms(expected_blacklisted))) | |
| 428 .WillOnce(WithArg<0>(STLDeleteElements0())); | |
| 429 } | 432 } |
| 430 | 433 |
| 431 LoginDatabaseQueryCallback(store->login_db(), false, &ld_return); | 434 LoginDatabaseQueryCallback(store->login_db(), false, &ld_return); |
| 432 | 435 |
| 433 // Wait for the login DB methods to execute. | 436 // Wait for the login DB methods to execute. |
| 434 base::RunLoop().RunUntilIdle(); | 437 base::RunLoop().RunUntilIdle(); |
| 435 | 438 |
| 436 if (GetParam() == WORKING_BACKEND) { | 439 if (GetParam() == WORKING_BACKEND) { |
| 437 // If the migration succeeded, then not only should there be no logins left | 440 // If the migration succeeded, then not only should there be no logins left |
| 438 // in the login DB, but also the file should have been deleted and then | 441 // in the login DB, but also the file should have been deleted and then |
| 439 // recreated. We approximate checking for this by checking that the file | 442 // recreated. We approximate checking for this by checking that the file |
| 440 // size is equal to the size before we populated it, even though it was | 443 // size is equal to the size before we populated it, even though it was |
| 441 // larger after populating it. | 444 // larger after populating it. |
| 442 base::File::Info db_file_end_info; | 445 base::File::Info db_file_end_info; |
| 443 ASSERT_TRUE(base::GetFileInfo(login_db_file, &db_file_end_info)); | 446 ASSERT_TRUE(base::GetFileInfo(login_db_file, &db_file_end_info)); |
| 444 EXPECT_EQ(db_file_start_info.size, db_file_end_info.size); | 447 EXPECT_EQ(db_file_start_info.size, db_file_end_info.size); |
| 445 } | 448 } |
| 446 | 449 |
| 447 STLDeleteElements(&expected_autofillable); | |
| 448 STLDeleteElements(&expected_blacklisted); | |
| 449 | |
| 450 store->Shutdown(); | 450 store->Shutdown(); |
| 451 } | 451 } |
| 452 | 452 |
| 453 INSTANTIATE_TEST_CASE_P(NoBackend, | 453 INSTANTIATE_TEST_CASE_P(NoBackend, |
| 454 PasswordStoreXTest, | 454 PasswordStoreXTest, |
| 455 testing::Values(NO_BACKEND)); | 455 testing::Values(NO_BACKEND)); |
| 456 INSTANTIATE_TEST_CASE_P(FailingBackend, | 456 INSTANTIATE_TEST_CASE_P(FailingBackend, |
| 457 PasswordStoreXTest, | 457 PasswordStoreXTest, |
| 458 testing::Values(FAILING_BACKEND)); | 458 testing::Values(FAILING_BACKEND)); |
| 459 INSTANTIATE_TEST_CASE_P(WorkingBackend, | 459 INSTANTIATE_TEST_CASE_P(WorkingBackend, |
| 460 PasswordStoreXTest, | 460 PasswordStoreXTest, |
| 461 testing::Values(WORKING_BACKEND)); | 461 testing::Values(WORKING_BACKEND)); |
| OLD | NEW |