| 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 "chrome/browser/password_manager/password_store_mac.h" | 5 #include "chrome/browser/password_manager/password_store_mac.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/files/scoped_temp_dir.h" | 11 #include "base/files/scoped_temp_dir.h" |
| 12 #include "base/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/memory/ptr_util.h" |
| 13 #include "base/scoped_observer.h" | 14 #include "base/scoped_observer.h" |
| 14 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 15 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 17 #include "base/synchronization/waitable_event.h" | 18 #include "base/synchronization/waitable_event.h" |
| 18 #include "base/test/histogram_tester.h" | 19 #include "base/test/histogram_tester.h" |
| 19 #include "base/thread_task_runner_handle.h" | 20 #include "base/thread_task_runner_handle.h" |
| 20 #include "chrome/browser/password_manager/password_store_mac_internal.h" | 21 #include "chrome/browser/password_manager/password_store_mac_internal.h" |
| 21 #include "chrome/common/chrome_paths.h" | 22 #include "chrome/common/chrome_paths.h" |
| 22 #include "components/os_crypt/os_crypt.h" | 23 #include "components/os_crypt/os_crypt.h" |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 | 185 |
| 185 private: | 186 private: |
| 186 void Initialize(); | 187 void Initialize(); |
| 187 | 188 |
| 188 void ClosePasswordStore(); | 189 void ClosePasswordStore(); |
| 189 | 190 |
| 190 base::FilePath test_login_db_file_path() const; | 191 base::FilePath test_login_db_file_path() const; |
| 191 | 192 |
| 192 base::MessageLoopForUI message_loop_; | 193 base::MessageLoopForUI message_loop_; |
| 193 base::ScopedTempDir db_dir_; | 194 base::ScopedTempDir db_dir_; |
| 194 scoped_ptr<LoginDatabase> login_db_; | 195 std::unique_ptr<LoginDatabase> login_db_; |
| 195 scoped_refptr<PasswordStoreMac> store_; | 196 scoped_refptr<PasswordStoreMac> store_; |
| 196 | 197 |
| 197 DISALLOW_COPY_AND_ASSIGN(PasswordStoreMacTestDelegate); | 198 DISALLOW_COPY_AND_ASSIGN(PasswordStoreMacTestDelegate); |
| 198 }; | 199 }; |
| 199 | 200 |
| 200 PasswordStoreMacTestDelegate::PasswordStoreMacTestDelegate() { | 201 PasswordStoreMacTestDelegate::PasswordStoreMacTestDelegate() { |
| 201 Initialize(); | 202 Initialize(); |
| 202 } | 203 } |
| 203 | 204 |
| 204 PasswordStoreMacTestDelegate::~PasswordStoreMacTestDelegate() { | 205 PasswordStoreMacTestDelegate::~PasswordStoreMacTestDelegate() { |
| 205 ClosePasswordStore(); | 206 ClosePasswordStore(); |
| 206 } | 207 } |
| 207 | 208 |
| 208 void PasswordStoreMacTestDelegate::FinishAsyncProcessing() { | 209 void PasswordStoreMacTestDelegate::FinishAsyncProcessing() { |
| 209 base::MessageLoop::current()->RunUntilIdle(); | 210 base::MessageLoop::current()->RunUntilIdle(); |
| 210 } | 211 } |
| 211 | 212 |
| 212 void PasswordStoreMacTestDelegate::Initialize() { | 213 void PasswordStoreMacTestDelegate::Initialize() { |
| 213 ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); | 214 ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); |
| 214 | 215 |
| 215 // Ensure that LoginDatabase will use the mock keychain if it needs to | 216 // Ensure that LoginDatabase will use the mock keychain if it needs to |
| 216 // encrypt/decrypt a password. | 217 // encrypt/decrypt a password. |
| 217 OSCrypt::UseMockKeychain(true); | 218 OSCrypt::UseMockKeychain(true); |
| 218 login_db_.reset(new LoginDatabase(test_login_db_file_path())); | 219 login_db_.reset(new LoginDatabase(test_login_db_file_path())); |
| 219 ASSERT_TRUE(login_db_->Init()); | 220 ASSERT_TRUE(login_db_->Init()); |
| 220 | 221 |
| 221 // Create and initialize the password store. | 222 // Create and initialize the password store. |
| 222 store_ = new PasswordStoreMac(base::ThreadTaskRunnerHandle::Get(), | 223 store_ = new PasswordStoreMac(base::ThreadTaskRunnerHandle::Get(), |
| 223 base::ThreadTaskRunnerHandle::Get(), | 224 base::ThreadTaskRunnerHandle::Get(), |
| 224 make_scoped_ptr(new MockAppleKeychain)); | 225 base::WrapUnique(new MockAppleKeychain)); |
| 225 store_->set_login_metadata_db(login_db_.get()); | 226 store_->set_login_metadata_db(login_db_.get()); |
| 226 store_->login_metadata_db()->set_clear_password_values(false); | 227 store_->login_metadata_db()->set_clear_password_values(false); |
| 227 } | 228 } |
| 228 | 229 |
| 229 void PasswordStoreMacTestDelegate::ClosePasswordStore() { | 230 void PasswordStoreMacTestDelegate::ClosePasswordStore() { |
| 230 store_->ShutdownOnUIThread(); | 231 store_->ShutdownOnUIThread(); |
| 231 FinishAsyncProcessing(); | 232 FinishAsyncProcessing(); |
| 232 } | 233 } |
| 233 | 234 |
| 234 base::FilePath PasswordStoreMacTestDelegate::test_login_db_file_path() const { | 235 base::FilePath PasswordStoreMacTestDelegate::test_login_db_file_path() const { |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 /// Garbage forms should have no matches. | 562 /// Garbage forms should have no matches. |
| 562 { { PasswordForm::SCHEME_HTML, "foo/bar/baz", | 563 { { PasswordForm::SCHEME_HTML, "foo/bar/baz", |
| 563 NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 }, | 564 NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 }, |
| 564 }; | 565 }; |
| 565 /* clang-format on */ | 566 /* clang-format on */ |
| 566 | 567 |
| 567 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); | 568 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); |
| 568 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); | 569 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); |
| 569 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 570 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 570 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | 571 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
| 571 scoped_ptr<PasswordForm> query_form = | 572 std::unique_ptr<PasswordForm> query_form = |
| 572 CreatePasswordFormFromDataForTesting(test_data[i].data); | 573 CreatePasswordFormFromDataForTesting(test_data[i].data); |
| 573 | 574 |
| 574 // Check matches treating the form as a fill target. | 575 // Check matches treating the form as a fill target. |
| 575 ScopedVector<autofill::PasswordForm> matching_items = | 576 ScopedVector<autofill::PasswordForm> matching_items = |
| 576 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, | 577 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, |
| 577 query_form->scheme); | 578 query_form->scheme); |
| 578 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size()); | 579 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size()); |
| 579 | 580 |
| 580 // Check matches treating the form as a merging target. | 581 // Check matches treating the form as a merging target. |
| 581 EXPECT_EQ(test_data[i].expected_merge_matches > 0, | 582 EXPECT_EQ(test_data[i].expected_merge_matches > 0, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", | 641 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", |
| 641 "http://some.domain.com:4567/insecure.html", | 642 "http://some.domain.com:4567/insecure.html", |
| 642 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 }, | 643 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 }, |
| 643 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", | 644 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", |
| 644 "https://some.domain.com", | 645 "https://some.domain.com", |
| 645 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 }, | 646 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 }, |
| 646 }; | 647 }; |
| 647 | 648 |
| 648 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) { | 649 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) { |
| 649 // Create a base form and make sure we find a match. | 650 // Create a base form and make sure we find a match. |
| 650 scoped_ptr<PasswordForm> base_form = | 651 std::unique_ptr<PasswordForm> base_form = |
| 651 CreatePasswordFormFromDataForTesting(base_form_data[i]); | 652 CreatePasswordFormFromDataForTesting(base_form_data[i]); |
| 652 EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form)); | 653 EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form)); |
| 653 EXPECT_TRUE(keychain_adapter.HasPasswordExactlyMatchingForm(*base_form)); | 654 EXPECT_TRUE(keychain_adapter.HasPasswordExactlyMatchingForm(*base_form)); |
| 654 | 655 |
| 655 // Make sure that the matching isn't looser than it should be by checking | 656 // Make sure that the matching isn't looser than it should be by checking |
| 656 // that slightly altered forms don't match. | 657 // that slightly altered forms don't match. |
| 657 ScopedVector<autofill::PasswordForm> modified_forms; | 658 ScopedVector<autofill::PasswordForm> modified_forms; |
| 658 | 659 |
| 659 modified_forms.push_back(new PasswordForm(*base_form)); | 660 modified_forms.push_back(new PasswordForm(*base_form)); |
| 660 modified_forms.back()->username_value = ASCIIToUTF16("wrong_user"); | 661 modified_forms.back()->username_value = ASCIIToUTF16("wrong_user"); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 724 { { PasswordForm::SCHEME_HTML, "http://some.domain.com", | 725 { { PasswordForm::SCHEME_HTML, "http://some.domain.com", |
| 725 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, | 726 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, |
| 726 L"joe_user", L"fail_me", false, false, 0 }, false }, | 727 L"joe_user", L"fail_me", false, false, 0 }, false }, |
| 727 }; | 728 }; |
| 728 /* clang-format on */ | 729 /* clang-format on */ |
| 729 | 730 |
| 730 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); | 731 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); |
| 731 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 732 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 732 | 733 |
| 733 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | 734 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
| 734 scoped_ptr<PasswordForm> in_form = | 735 std::unique_ptr<PasswordForm> in_form = |
| 735 CreatePasswordFormFromDataForTesting(test_data[i].data); | 736 CreatePasswordFormFromDataForTesting(test_data[i].data); |
| 736 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); | 737 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); |
| 737 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); | 738 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); |
| 738 if (add_succeeded) { | 739 if (add_succeeded) { |
| 739 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm( | 740 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm( |
| 740 *in_form)); | 741 *in_form)); |
| 741 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm( | 742 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm( |
| 742 *in_form)); | 743 *in_form)); |
| 743 } | 744 } |
| 744 } | 745 } |
| 745 | 746 |
| 746 // Test that adding duplicate item updates the existing item. | 747 // Test that adding duplicate item updates the existing item. |
| 747 // TODO(engedy): Add a test to verify that updating Android credentials work. | 748 // TODO(engedy): Add a test to verify that updating Android credentials work. |
| 748 // See: https://crbug.com/476851. | 749 // See: https://crbug.com/476851. |
| 749 { | 750 { |
| 750 PasswordFormData data = { | 751 PasswordFormData data = { |
| 751 PasswordForm::SCHEME_HTML, "http://some.domain.com", | 752 PasswordForm::SCHEME_HTML, "http://some.domain.com", |
| 752 "http://some.domain.com/insecure.html", NULL, | 753 "http://some.domain.com/insecure.html", NULL, |
| 753 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 | 754 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 |
| 754 }; | 755 }; |
| 755 scoped_ptr<PasswordForm> update_form = | 756 std::unique_ptr<PasswordForm> update_form = |
| 756 CreatePasswordFormFromDataForTesting(data); | 757 CreatePasswordFormFromDataForTesting(data); |
| 757 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); | 758 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); |
| 758 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); | 759 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); |
| 759 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); | 760 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); |
| 760 PasswordForm stored_form; | 761 PasswordForm stored_form; |
| 761 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, | 762 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, |
| 762 keychain_item, | 763 keychain_item, |
| 763 &stored_form, | 764 &stored_form, |
| 764 true); | 765 true); |
| 765 EXPECT_EQ(update_form->password_value, stored_form.password_value); | 766 EXPECT_EQ(update_form->password_value, stored_form.password_value); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 790 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, | 791 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, |
| 791 L"joe_user", NULL, true, false, 0 }, false }, | 792 L"joe_user", NULL, true, false, 0 }, false }, |
| 792 }; | 793 }; |
| 793 /* clang-format on */ | 794 /* clang-format on */ |
| 794 | 795 |
| 795 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); | 796 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); |
| 796 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 797 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 797 | 798 |
| 798 // Add our test items (except the last one) so that we can delete them. | 799 // Add our test items (except the last one) so that we can delete them. |
| 799 for (unsigned int i = 0; i + 1 < arraysize(test_data); ++i) { | 800 for (unsigned int i = 0; i + 1 < arraysize(test_data); ++i) { |
| 800 scoped_ptr<PasswordForm> add_form = | 801 std::unique_ptr<PasswordForm> add_form = |
| 801 CreatePasswordFormFromDataForTesting(test_data[i].data); | 802 CreatePasswordFormFromDataForTesting(test_data[i].data); |
| 802 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form)); | 803 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form)); |
| 803 } | 804 } |
| 804 | 805 |
| 805 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | 806 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
| 806 scoped_ptr<PasswordForm> form = | 807 std::unique_ptr<PasswordForm> form = |
| 807 CreatePasswordFormFromDataForTesting(test_data[i].data); | 808 CreatePasswordFormFromDataForTesting(test_data[i].data); |
| 808 EXPECT_EQ(test_data[i].should_succeed, | 809 EXPECT_EQ(test_data[i].should_succeed, |
| 809 owned_keychain_adapter.RemovePassword(*form)); | 810 owned_keychain_adapter.RemovePassword(*form)); |
| 810 | 811 |
| 811 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); | 812 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); |
| 812 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form); | 813 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form); |
| 813 EXPECT_EQ(test_data[i].should_succeed, !match); | 814 EXPECT_EQ(test_data[i].should_succeed, !match); |
| 814 } | 815 } |
| 815 } | 816 } |
| 816 | 817 |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, | 1221 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, |
| 1221 L"anonymous", L"knock-knock", false, false, 0 }, | 1222 L"anonymous", L"knock-knock", false, false, 0 }, |
| 1222 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", | 1223 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", |
| 1223 "http://a.site.com:2222/", NULL, NULL, NULL, NULL, | 1224 "http://a.site.com:2222/", NULL, NULL, NULL, NULL, |
| 1224 L"username", L"password", false, false, 0 }, | 1225 L"username", L"password", false, false, 0 }, |
| 1225 { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", | 1226 { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", |
| 1226 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, | 1227 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, |
| 1227 L"testname", L"testpass", false, false, 0 }, | 1228 L"testname", L"testpass", false, false, 0 }, |
| 1228 }; | 1229 }; |
| 1229 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) { | 1230 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) { |
| 1230 scoped_ptr<PasswordForm> form = | 1231 std::unique_ptr<PasswordForm> form = |
| 1231 CreatePasswordFormFromDataForTesting(owned_password_data[i]); | 1232 CreatePasswordFormFromDataForTesting(owned_password_data[i]); |
| 1232 owned_keychain_adapter.AddPassword(*form); | 1233 owned_keychain_adapter.AddPassword(*form); |
| 1233 } | 1234 } |
| 1234 | 1235 |
| 1235 ScopedVector<autofill::PasswordForm> all_passwords = | 1236 ScopedVector<autofill::PasswordForm> all_passwords = |
| 1236 keychain_adapter.GetAllPasswordFormPasswords(); | 1237 keychain_adapter.GetAllPasswordFormPasswords(); |
| 1237 EXPECT_EQ(9 + arraysize(owned_password_data), all_passwords.size()); | 1238 EXPECT_EQ(9 + arraysize(owned_password_data), all_passwords.size()); |
| 1238 | 1239 |
| 1239 ScopedVector<autofill::PasswordForm> owned_passwords = | 1240 ScopedVector<autofill::PasswordForm> owned_passwords = |
| 1240 owned_keychain_adapter.GetAllPasswordFormPasswords(); | 1241 owned_keychain_adapter.GetAllPasswordFormPasswords(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1280 } | 1281 } |
| 1281 } | 1282 } |
| 1282 | 1283 |
| 1283 static void InitLoginDatabase(password_manager::LoginDatabase* login_db) { | 1284 static void InitLoginDatabase(password_manager::LoginDatabase* login_db) { |
| 1284 ASSERT_TRUE(login_db->Init()); | 1285 ASSERT_TRUE(login_db->Init()); |
| 1285 } | 1286 } |
| 1286 | 1287 |
| 1287 void CreateAndInitPasswordStore(password_manager::LoginDatabase* login_db) { | 1288 void CreateAndInitPasswordStore(password_manager::LoginDatabase* login_db) { |
| 1288 store_ = new PasswordStoreMac( | 1289 store_ = new PasswordStoreMac( |
| 1289 base::ThreadTaskRunnerHandle::Get(), nullptr, | 1290 base::ThreadTaskRunnerHandle::Get(), nullptr, |
| 1290 make_scoped_ptr<AppleKeychain>(new MockAppleKeychain)); | 1291 base::WrapUnique<AppleKeychain>(new MockAppleKeychain)); |
| 1291 ASSERT_TRUE(thread_->task_runner()->PostTask( | 1292 ASSERT_TRUE(thread_->task_runner()->PostTask( |
| 1292 FROM_HERE, base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_, | 1293 FROM_HERE, base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_, |
| 1293 thread_->task_runner()))); | 1294 thread_->task_runner()))); |
| 1294 | 1295 |
| 1295 ASSERT_TRUE(thread_->task_runner()->PostTask( | 1296 ASSERT_TRUE(thread_->task_runner()->PostTask( |
| 1296 FROM_HERE, base::Bind(&PasswordStoreMac::set_login_metadata_db, store_, | 1297 FROM_HERE, base::Bind(&PasswordStoreMac::set_login_metadata_db, store_, |
| 1297 base::Unretained(login_db)))); | 1298 base::Unretained(login_db)))); |
| 1298 } | 1299 } |
| 1299 | 1300 |
| 1300 void ClosePasswordStore() { | 1301 void ClosePasswordStore() { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1373 FROM_HERE, base::Bind(&Noop), runner->QuitClosure())); | 1374 FROM_HERE, base::Bind(&Noop), runner->QuitClosure())); |
| 1374 runner->Run(); | 1375 runner->Run(); |
| 1375 } | 1376 } |
| 1376 | 1377 |
| 1377 PasswordStoreMac* store() { return store_.get(); } | 1378 PasswordStoreMac* store() { return store_.get(); } |
| 1378 | 1379 |
| 1379 protected: | 1380 protected: |
| 1380 base::MessageLoopForUI message_loop_; | 1381 base::MessageLoopForUI message_loop_; |
| 1381 content::TestBrowserThread ui_thread_; | 1382 content::TestBrowserThread ui_thread_; |
| 1382 // Thread that the synchronous methods are run on. | 1383 // Thread that the synchronous methods are run on. |
| 1383 scoped_ptr<base::Thread> thread_; | 1384 std::unique_ptr<base::Thread> thread_; |
| 1384 | 1385 |
| 1385 base::ScopedTempDir db_dir_; | 1386 base::ScopedTempDir db_dir_; |
| 1386 scoped_ptr<password_manager::LoginDatabase> login_db_; | 1387 std::unique_ptr<password_manager::LoginDatabase> login_db_; |
| 1387 scoped_refptr<PasswordStoreMac> store_; | 1388 scoped_refptr<PasswordStoreMac> store_; |
| 1388 scoped_ptr<base::HistogramTester> histogram_tester_; | 1389 std::unique_ptr<base::HistogramTester> histogram_tester_; |
| 1389 }; | 1390 }; |
| 1390 | 1391 |
| 1391 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { | 1392 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { |
| 1392 // Insert a password into both the database and the keychain. | 1393 // Insert a password into both the database and the keychain. |
| 1393 // This is done manually, rather than through store_->AddLogin, because the | 1394 // This is done manually, rather than through store_->AddLogin, because the |
| 1394 // Mock Keychain isn't smart enough to be able to support update generically, | 1395 // Mock Keychain isn't smart enough to be able to support update generically, |
| 1395 // so some.domain.com triggers special handling to test it that make inserting | 1396 // so some.domain.com triggers special handling to test it that make inserting |
| 1396 // fail. | 1397 // fail. |
| 1397 PasswordFormData joint_data = { | 1398 PasswordFormData joint_data = { |
| 1398 PasswordForm::SCHEME_HTML, "http://some.domain.com/", | 1399 PasswordForm::SCHEME_HTML, "http://some.domain.com/", |
| 1399 "http://some.domain.com/insecure.html", "login.cgi", | 1400 "http://some.domain.com/insecure.html", "login.cgi", |
| 1400 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 | 1401 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 |
| 1401 }; | 1402 }; |
| 1402 scoped_ptr<PasswordForm> joint_form = | 1403 std::unique_ptr<PasswordForm> joint_form = |
| 1403 CreatePasswordFormFromDataForTesting(joint_data); | 1404 CreatePasswordFormFromDataForTesting(joint_data); |
| 1404 EXPECT_EQ(AddChangeForForm(*joint_form), login_db()->AddLogin(*joint_form)); | 1405 EXPECT_EQ(AddChangeForForm(*joint_form), login_db()->AddLogin(*joint_form)); |
| 1405 MockAppleKeychain::KeychainTestData joint_keychain_data = { | 1406 MockAppleKeychain::KeychainTestData joint_keychain_data = { |
| 1406 kSecAuthenticationTypeHTMLForm, "some.domain.com", | 1407 kSecAuthenticationTypeHTMLForm, "some.domain.com", |
| 1407 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z", | 1408 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z", |
| 1408 "joe_user", "sekrit", false }; | 1409 "joe_user", "sekrit", false }; |
| 1409 keychain()->AddTestItem(joint_keychain_data); | 1410 keychain()->AddTestItem(joint_keychain_data); |
| 1410 | 1411 |
| 1411 // Insert a password into the keychain only. | 1412 // Insert a password into the keychain only. |
| 1412 MockAppleKeychain::KeychainTestData keychain_only_data = { | 1413 MockAppleKeychain::KeychainTestData keychain_only_data = { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1442 // case where a form is filled, then the stored login is removed, then the | 1443 // case where a form is filled, then the stored login is removed, then the |
| 1443 // form is submitted. | 1444 // form is submitted. |
| 1444 { { PasswordForm::SCHEME_HTML, "http://different.com/", | 1445 { { PasswordForm::SCHEME_HTML, "http://different.com/", |
| 1445 "http://different.com/index.html", "login.cgi", | 1446 "http://different.com/index.html", "login.cgi", |
| 1446 L"username", L"password", L"submit", L"abc", L"123", | 1447 L"username", L"password", L"submit", L"abc", L"123", |
| 1447 true, false, 2 }, | 1448 true, false, 2 }, |
| 1448 NULL, | 1449 NULL, |
| 1449 }, | 1450 }, |
| 1450 }; | 1451 }; |
| 1451 for (unsigned int i = 0; i < arraysize(updates); ++i) { | 1452 for (unsigned int i = 0; i < arraysize(updates); ++i) { |
| 1452 scoped_ptr<PasswordForm> form = | 1453 std::unique_ptr<PasswordForm> form = |
| 1453 CreatePasswordFormFromDataForTesting(updates[i].form_data); | 1454 CreatePasswordFormFromDataForTesting(updates[i].form_data); |
| 1454 store_->UpdateLogin(*form); | 1455 store_->UpdateLogin(*form); |
| 1455 } | 1456 } |
| 1456 | 1457 |
| 1457 FinishAsyncProcessing(); | 1458 FinishAsyncProcessing(); |
| 1458 | 1459 |
| 1459 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); | 1460 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); |
| 1460 for (unsigned int i = 0; i < arraysize(updates); ++i) { | 1461 for (unsigned int i = 0; i < arraysize(updates); ++i) { |
| 1461 scoped_ptr<PasswordForm> query_form = | 1462 std::unique_ptr<PasswordForm> query_form = |
| 1462 CreatePasswordFormFromDataForTesting(updates[i].form_data); | 1463 CreatePasswordFormFromDataForTesting(updates[i].form_data); |
| 1463 | 1464 |
| 1464 ScopedVector<autofill::PasswordForm> matching_items = | 1465 ScopedVector<autofill::PasswordForm> matching_items = |
| 1465 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, | 1466 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, |
| 1466 query_form->scheme); | 1467 query_form->scheme); |
| 1467 if (updates[i].password) { | 1468 if (updates[i].password) { |
| 1468 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i; | 1469 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i; |
| 1469 if (matching_items.size() >= 1) | 1470 if (matching_items.size() >= 1) |
| 1470 EXPECT_EQ(ASCIIToUTF16(updates[i].password), | 1471 EXPECT_EQ(ASCIIToUTF16(updates[i].password), |
| 1471 matching_items[0]->password_value) << "iteration " << i; | 1472 matching_items[0]->password_value) << "iteration " << i; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1494 // www.facebook.com password from the login database, we should not be blocked | 1495 // www.facebook.com password from the login database, we should not be blocked |
| 1495 // from deleting it from the keystore just becaus the m.facebook.com password | 1496 // from deleting it from the keystore just becaus the m.facebook.com password |
| 1496 // fuzzy-matches the www.facebook.com one.) | 1497 // fuzzy-matches the www.facebook.com one.) |
| 1497 | 1498 |
| 1498 // 1. Add a password for www.facebook.com | 1499 // 1. Add a password for www.facebook.com |
| 1499 PasswordFormData www_form_data = { | 1500 PasswordFormData www_form_data = { |
| 1500 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1501 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1501 "http://www.facebook.com/index.html", "login", | 1502 "http://www.facebook.com/index.html", "login", |
| 1502 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 | 1503 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 |
| 1503 }; | 1504 }; |
| 1504 scoped_ptr<PasswordForm> www_form = | 1505 std::unique_ptr<PasswordForm> www_form = |
| 1505 CreatePasswordFormFromDataForTesting(www_form_data); | 1506 CreatePasswordFormFromDataForTesting(www_form_data); |
| 1506 EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form)); | 1507 EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form)); |
| 1507 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); | 1508 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); |
| 1508 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1509 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 1509 owned_keychain_adapter.AddPassword(*www_form); | 1510 owned_keychain_adapter.AddPassword(*www_form); |
| 1510 | 1511 |
| 1511 // 2. Get a password for m.facebook.com. | 1512 // 2. Get a password for m.facebook.com. |
| 1512 PasswordForm m_form(*www_form); | 1513 PasswordForm m_form(*www_form); |
| 1513 m_form.signon_realm = "http://m.facebook.com"; | 1514 m_form.signon_realm = "http://m.facebook.com"; |
| 1514 m_form.origin = GURL("http://m.facebook.com/index.html"); | 1515 m_form.origin = GURL("http://m.facebook.com/index.html"); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1587 L"password", L"joe_user", L"sekrit", true, false, 0 }; | 1588 L"password", L"joe_user", L"sekrit", true, false, 0 }; |
| 1588 // The old form doesn't have elements names. | 1589 // The old form doesn't have elements names. |
| 1589 PasswordFormData www_form_data_facebook_old = { | 1590 PasswordFormData www_form_data_facebook_old = { |
| 1590 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1591 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1591 "http://www.facebook.com/index.html", "login", L"", L"", | 1592 "http://www.facebook.com/index.html", "login", L"", L"", |
| 1592 L"", L"joe_user", L"oldsekrit", true, false, 0 }; | 1593 L"", L"joe_user", L"oldsekrit", true, false, 0 }; |
| 1593 PasswordFormData www_form_data_other = { | 1594 PasswordFormData www_form_data_other = { |
| 1594 PasswordForm::SCHEME_HTML, "http://different.com/", | 1595 PasswordForm::SCHEME_HTML, "http://different.com/", |
| 1595 "http://different.com/index.html", "login", L"submit", L"username", | 1596 "http://different.com/index.html", "login", L"submit", L"username", |
| 1596 L"password", L"different_joe_user", L"sekrit", true, false, 0 }; | 1597 L"password", L"different_joe_user", L"sekrit", true, false, 0 }; |
| 1597 scoped_ptr<PasswordForm> form_facebook = | 1598 std::unique_ptr<PasswordForm> form_facebook = |
| 1598 CreatePasswordFormFromDataForTesting(www_form_data_facebook); | 1599 CreatePasswordFormFromDataForTesting(www_form_data_facebook); |
| 1599 scoped_ptr<PasswordForm> form_facebook_old = | 1600 std::unique_ptr<PasswordForm> form_facebook_old = |
| 1600 CreatePasswordFormFromDataForTesting(www_form_data_facebook_old); | 1601 CreatePasswordFormFromDataForTesting(www_form_data_facebook_old); |
| 1601 scoped_ptr<PasswordForm> form_other = | 1602 std::unique_ptr<PasswordForm> form_other = |
| 1602 CreatePasswordFormFromDataForTesting(www_form_data_other); | 1603 CreatePasswordFormFromDataForTesting(www_form_data_other); |
| 1603 base::Time now = base::Time::Now(); | 1604 base::Time now = base::Time::Now(); |
| 1604 base::Time next_day = now + base::TimeDelta::FromDays(1); | 1605 base::Time next_day = now + base::TimeDelta::FromDays(1); |
| 1605 if (check_created) { | 1606 if (check_created) { |
| 1606 form_facebook_old->date_created = now; | 1607 form_facebook_old->date_created = now; |
| 1607 form_facebook->date_created = next_day; | 1608 form_facebook->date_created = next_day; |
| 1608 form_other->date_created = next_day; | 1609 form_other->date_created = next_day; |
| 1609 } else { | 1610 } else { |
| 1610 form_facebook_old->date_synced = now; | 1611 form_facebook_old->date_synced = now; |
| 1611 form_facebook->date_synced = next_day; | 1612 form_facebook->date_synced = next_day; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1691 "http://www.facebook.com/index.html", | 1692 "http://www.facebook.com/index.html", |
| 1692 "login", | 1693 "login", |
| 1693 L"submit", | 1694 L"submit", |
| 1694 L"username", | 1695 L"username", |
| 1695 L"password", | 1696 L"password", |
| 1696 L"joe_user", | 1697 L"joe_user", |
| 1697 L"sekrit", | 1698 L"sekrit", |
| 1698 true, | 1699 true, |
| 1699 false, | 1700 false, |
| 1700 0}; | 1701 0}; |
| 1701 scoped_ptr<PasswordForm> form_facebook = | 1702 std::unique_ptr<PasswordForm> form_facebook = |
| 1702 CreatePasswordFormFromDataForTesting(www_form_data_facebook); | 1703 CreatePasswordFormFromDataForTesting(www_form_data_facebook); |
| 1703 form_facebook->skip_zero_click = false; | 1704 form_facebook->skip_zero_click = false; |
| 1704 | 1705 |
| 1705 // Add the zero-clickable form to the database. | 1706 // Add the zero-clickable form to the database. |
| 1706 PasswordsChangeObserver observer(store()); | 1707 PasswordsChangeObserver observer(store()); |
| 1707 store()->AddLogin(*form_facebook); | 1708 store()->AddLogin(*form_facebook); |
| 1708 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook))); | 1709 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook))); |
| 1709 observer.WaitAndVerify(this); | 1710 observer.WaitAndVerify(this); |
| 1710 | 1711 |
| 1711 ScopedVector<autofill::PasswordForm> forms; | 1712 ScopedVector<autofill::PasswordForm> forms; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1732 keychain()->AddTestItem(keychain_data); | 1733 keychain()->AddTestItem(keychain_data); |
| 1733 | 1734 |
| 1734 // Add a password through the adapter. It has the "Chrome" creator tag. | 1735 // Add a password through the adapter. It has the "Chrome" creator tag. |
| 1735 // However, it's not referenced by the password database. | 1736 // However, it's not referenced by the password database. |
| 1736 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); | 1737 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); |
| 1737 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1738 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 1738 PasswordFormData www_form_data1 = { | 1739 PasswordFormData www_form_data1 = { |
| 1739 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1740 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1740 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1741 "http://www.facebook.com/index.html", "login", L"username", L"password", |
| 1741 L"submit", L"joe_user", L"sekrit", true, false, 1 }; | 1742 L"submit", L"joe_user", L"sekrit", true, false, 1 }; |
| 1742 scoped_ptr<PasswordForm> www_form = | 1743 std::unique_ptr<PasswordForm> www_form = |
| 1743 CreatePasswordFormFromDataForTesting(www_form_data1); | 1744 CreatePasswordFormFromDataForTesting(www_form_data1); |
| 1744 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); | 1745 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); |
| 1745 | 1746 |
| 1746 // Add a password from the current profile. | 1747 // Add a password from the current profile. |
| 1747 PasswordFormData www_form_data2 = { | 1748 PasswordFormData www_form_data2 = { |
| 1748 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1749 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1749 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1750 "http://www.facebook.com/index.html", "login", L"username", L"password", |
| 1750 L"submit", L"not_joe_user", L"12345", true, false, 1 }; | 1751 L"submit", L"not_joe_user", L"12345", true, false, 1 }; |
| 1751 www_form = CreatePasswordFormFromDataForTesting(www_form_data2); | 1752 www_form = CreatePasswordFormFromDataForTesting(www_form_data2); |
| 1752 store_->AddLogin(*www_form); | 1753 store_->AddLogin(*www_form); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 testing::StrictMock<password_manager::MockPasswordStoreObserver> | 1785 testing::StrictMock<password_manager::MockPasswordStoreObserver> |
| 1785 mock_observer; | 1786 mock_observer; |
| 1786 store()->AddObserver(&mock_observer); | 1787 store()->AddObserver(&mock_observer); |
| 1787 | 1788 |
| 1788 // 1. Add a password for www.facebook.com to the LoginDatabase. | 1789 // 1. Add a password for www.facebook.com to the LoginDatabase. |
| 1789 PasswordFormData www_form_data = { | 1790 PasswordFormData www_form_data = { |
| 1790 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1791 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1791 "http://www.facebook.com/index.html", "login", | 1792 "http://www.facebook.com/index.html", "login", |
| 1792 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1 | 1793 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1 |
| 1793 }; | 1794 }; |
| 1794 scoped_ptr<PasswordForm> www_form( | 1795 std::unique_ptr<PasswordForm> www_form( |
| 1795 CreatePasswordFormFromDataForTesting(www_form_data)); | 1796 CreatePasswordFormFromDataForTesting(www_form_data)); |
| 1796 EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form)); | 1797 EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form)); |
| 1797 | 1798 |
| 1798 // 2. Get a PSL-matched password for m.facebook.com. The observer isn't | 1799 // 2. Get a PSL-matched password for m.facebook.com. The observer isn't |
| 1799 // notified because the form isn't in the database. | 1800 // notified because the form isn't in the database. |
| 1800 PasswordForm m_form(*www_form); | 1801 PasswordForm m_form(*www_form); |
| 1801 m_form.signon_realm = "http://m.facebook.com"; | 1802 m_form.signon_realm = "http://m.facebook.com"; |
| 1802 m_form.origin = GURL("http://m.facebook.com/index.html"); | 1803 m_form.origin = GURL("http://m.facebook.com/index.html"); |
| 1803 | 1804 |
| 1804 MockPasswordStoreConsumer consumer; | 1805 MockPasswordStoreConsumer consumer; |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1963 histogram_tester_->ExpectUniqueSample( | 1964 histogram_tester_->ExpectUniqueSample( |
| 1964 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1); | 1965 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1); |
| 1965 histogram_tester_->ExpectUniqueSample( | 1966 histogram_tester_->ExpectUniqueSample( |
| 1966 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1); | 1967 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1); |
| 1967 histogram_tester_->ExpectUniqueSample( | 1968 histogram_tester_->ExpectUniqueSample( |
| 1968 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords", | 1969 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords", |
| 1969 2, 1); | 1970 2, 1); |
| 1970 // Don't test the encryption key access. | 1971 // Don't test the encryption key access. |
| 1971 histogram_tester_.reset(); | 1972 histogram_tester_.reset(); |
| 1972 } | 1973 } |
| OLD | NEW |