| 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 <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
| 11 #include "base/scoped_observer.h" | 11 #include "base/scoped_observer.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
| 16 #include "base/test/histogram_tester.h" | 16 #include "base/test/histogram_tester.h" |
| 17 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
| 18 #include "chrome/browser/password_manager/password_store_mac_internal.h" | 18 #include "chrome/browser/password_manager/password_store_mac_internal.h" |
| 19 #include "chrome/common/chrome_paths.h" | 19 #include "chrome/common/chrome_paths.h" |
| 20 #include "components/os_crypt/os_crypt.h" | 20 #include "components/os_crypt/os_crypt.h" |
| 21 #include "components/password_manager/core/browser/login_database.h" | 21 #include "components/password_manager/core/browser/login_database.h" |
| 22 #include "components/password_manager/core/browser/password_manager_test_utils.h
" | 22 #include "components/password_manager/core/browser/password_manager_test_utils.h
" |
| 23 #include "components/password_manager/core/browser/password_store_consumer.h" | 23 #include "components/password_manager/core/browser/password_store_consumer.h" |
| 24 #include "components/password_manager/core/browser/password_store_origin_unittes
t.h" |
| 24 #include "content/public/test/test_browser_thread.h" | 25 #include "content/public/test/test_browser_thread.h" |
| 25 #include "content/public/test/test_utils.h" | 26 #include "content/public/test/test_utils.h" |
| 26 #include "crypto/mock_apple_keychain.h" | 27 #include "crypto/mock_apple_keychain.h" |
| 27 #include "testing/gmock/include/gmock/gmock.h" | 28 #include "testing/gmock/include/gmock/gmock.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
| 29 | 30 |
| 30 using autofill::PasswordForm; | 31 using autofill::PasswordForm; |
| 31 using base::ASCIIToUTF16; | 32 using base::ASCIIToUTF16; |
| 32 using base::WideToUTF16; | 33 using base::WideToUTF16; |
| 33 using content::BrowserThread; | 34 using content::BrowserThread; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 public: | 70 public: |
| 70 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, | 71 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, |
| 71 void(const std::vector<PasswordForm*>&)); | 72 void(const std::vector<PasswordForm*>&)); |
| 72 | 73 |
| 73 // GMock cannot mock methods with move-only args. | 74 // GMock cannot mock methods with move-only args. |
| 74 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override { | 75 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override { |
| 75 OnGetPasswordStoreResultsConstRef(results.get()); | 76 OnGetPasswordStoreResultsConstRef(results.get()); |
| 76 } | 77 } |
| 77 }; | 78 }; |
| 78 | 79 |
| 79 class MockPasswordStoreObserver : public PasswordStore::Observer { | |
| 80 public: | |
| 81 MOCK_METHOD1(OnLoginsChanged, | |
| 82 void(const password_manager::PasswordStoreChangeList& changes)); | |
| 83 }; | |
| 84 | |
| 85 // A LoginDatabase that simulates an Init() method that takes a long time. | 80 // A LoginDatabase that simulates an Init() method that takes a long time. |
| 86 class SlowToInitLoginDatabase : public password_manager::LoginDatabase { | 81 class SlowToInitLoginDatabase : public password_manager::LoginDatabase { |
| 87 public: | 82 public: |
| 88 // Creates an instance whose Init() method will block until |event| is | 83 // Creates an instance whose Init() method will block until |event| is |
| 89 // signaled. |event| must outlive |this|. | 84 // signaled. |event| must outlive |this|. |
| 90 SlowToInitLoginDatabase(const base::FilePath& db_path, | 85 SlowToInitLoginDatabase(const base::FilePath& db_path, |
| 91 base::WaitableEvent* event) | 86 base::WaitableEvent* event) |
| 92 : password_manager::LoginDatabase(db_path), event_(event) {} | 87 : password_manager::LoginDatabase(db_path), event_(event) {} |
| 93 ~SlowToInitLoginDatabase() override {} | 88 ~SlowToInitLoginDatabase() override {} |
| 94 | 89 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 form->date_synced); | 162 form->date_synced); |
| 168 EXPECT_EQ(GURL(password_manager::kTestingIconUrlSpec), form->icon_url); | 163 EXPECT_EQ(GURL(password_manager::kTestingIconUrlSpec), form->icon_url); |
| 169 } | 164 } |
| 170 } | 165 } |
| 171 | 166 |
| 172 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) { | 167 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) { |
| 173 return PasswordStoreChangeList( | 168 return PasswordStoreChangeList( |
| 174 1, PasswordStoreChange(PasswordStoreChange::ADD, form)); | 169 1, PasswordStoreChange(PasswordStoreChange::ADD, form)); |
| 175 } | 170 } |
| 176 | 171 |
| 172 class PasswordStoreMacTestDelegate { |
| 173 public: |
| 174 PasswordStoreMacTestDelegate(); |
| 175 ~PasswordStoreMacTestDelegate(); |
| 176 |
| 177 PasswordStoreMac* store() { return store_.get(); } |
| 178 |
| 179 static void FinishAsyncProcessing(); |
| 180 |
| 181 private: |
| 182 void Initialize(); |
| 183 |
| 184 void ClosePasswordStore(); |
| 185 |
| 186 base::FilePath test_login_db_file_path() const; |
| 187 |
| 188 base::MessageLoopForUI message_loop_; |
| 189 base::ScopedTempDir db_dir_; |
| 190 scoped_ptr<LoginDatabase> login_db_; |
| 191 scoped_refptr<PasswordStoreMac> store_; |
| 192 |
| 193 DISALLOW_COPY_AND_ASSIGN(PasswordStoreMacTestDelegate); |
| 194 }; |
| 195 |
| 196 PasswordStoreMacTestDelegate::PasswordStoreMacTestDelegate() { |
| 197 Initialize(); |
| 198 } |
| 199 |
| 200 PasswordStoreMacTestDelegate::~PasswordStoreMacTestDelegate() { |
| 201 ClosePasswordStore(); |
| 202 } |
| 203 |
| 204 void PasswordStoreMacTestDelegate::FinishAsyncProcessing() { |
| 205 base::MessageLoop::current()->RunUntilIdle(); |
| 206 } |
| 207 |
| 208 void PasswordStoreMacTestDelegate::Initialize() { |
| 209 ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); |
| 210 |
| 211 // Ensure that LoginDatabase will use the mock keychain if it needs to |
| 212 // encrypt/decrypt a password. |
| 213 OSCrypt::UseMockKeychain(true); |
| 214 login_db_.reset(new LoginDatabase(test_login_db_file_path())); |
| 215 ASSERT_TRUE(login_db_->Init()); |
| 216 |
| 217 // Create and initialize the password store. |
| 218 store_ = new PasswordStoreMac(base::ThreadTaskRunnerHandle::Get(), |
| 219 base::ThreadTaskRunnerHandle::Get(), |
| 220 make_scoped_ptr(new MockAppleKeychain)); |
| 221 store_->set_login_metadata_db(login_db_.get()); |
| 222 } |
| 223 |
| 224 void PasswordStoreMacTestDelegate::ClosePasswordStore() { |
| 225 store_->ShutdownOnUIThread(); |
| 226 FinishAsyncProcessing(); |
| 227 } |
| 228 |
| 229 base::FilePath PasswordStoreMacTestDelegate::test_login_db_file_path() const { |
| 230 return db_dir_.path().Append(FILE_PATH_LITERAL("login.db")); |
| 231 } |
| 232 |
| 177 } // namespace | 233 } // namespace |
| 178 | 234 |
| 235 namespace password_manager { |
| 236 |
| 237 INSTANTIATE_TYPED_TEST_CASE_P(Mac, |
| 238 PasswordStoreOriginTest, |
| 239 PasswordStoreMacTestDelegate); |
| 240 |
| 241 } // namespace password_manager |
| 242 |
| 179 #pragma mark - | 243 #pragma mark - |
| 180 | 244 |
| 181 class PasswordStoreMacInternalsTest : public testing::Test { | 245 class PasswordStoreMacInternalsTest : public testing::Test { |
| 182 public: | 246 public: |
| 183 void SetUp() override { | 247 void SetUp() override { |
| 184 MockAppleKeychain::KeychainTestData test_data[] = { | 248 MockAppleKeychain::KeychainTestData test_data[] = { |
| 185 // Basic HTML form. | 249 // Basic HTML form. |
| 186 {kSecAuthenticationTypeHTMLForm, | 250 {kSecAuthenticationTypeHTMLForm, |
| 187 "some.domain.com", | 251 "some.domain.com", |
| 188 kSecProtocolTypeHTTP, | 252 kSecProtocolTypeHTTP, |
| (...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1669 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); | 1733 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); |
| 1670 matching_items = owned_keychain_adapter.PasswordsFillingForm( | 1734 matching_items = owned_keychain_adapter.PasswordsFillingForm( |
| 1671 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML); | 1735 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML); |
| 1672 ASSERT_EQ(1u, matching_items.size()); | 1736 ASSERT_EQ(1u, matching_items.size()); |
| 1673 } | 1737 } |
| 1674 | 1738 |
| 1675 // Add a facebook form to the store but not to the keychain. The form is to be | 1739 // Add a facebook form to the store but not to the keychain. The form is to be |
| 1676 // implicitly deleted. However, the observers shouldn't get notified about | 1740 // implicitly deleted. However, the observers shouldn't get notified about |
| 1677 // deletion of non-existent forms like m.facebook.com. | 1741 // deletion of non-existent forms like m.facebook.com. |
| 1678 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) { | 1742 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) { |
| 1679 testing::StrictMock<MockPasswordStoreObserver> mock_observer; | 1743 testing::StrictMock<password_manager::MockPasswordStoreObserver> |
| 1744 mock_observer; |
| 1680 store()->AddObserver(&mock_observer); | 1745 store()->AddObserver(&mock_observer); |
| 1681 | 1746 |
| 1682 // 1. Add a password for www.facebook.com to the LoginDatabase. | 1747 // 1. Add a password for www.facebook.com to the LoginDatabase. |
| 1683 PasswordFormData www_form_data = { | 1748 PasswordFormData www_form_data = { |
| 1684 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1749 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1685 "http://www.facebook.com/index.html", "login", | 1750 "http://www.facebook.com/index.html", "login", |
| 1686 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1 | 1751 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1 |
| 1687 }; | 1752 }; |
| 1688 scoped_ptr<PasswordForm> www_form( | 1753 scoped_ptr<PasswordForm> www_form( |
| 1689 CreatePasswordFormFromDataForTesting(www_form_data)); | 1754 CreatePasswordFormFromDataForTesting(www_form_data)); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1856 histogram_tester_->ExpectUniqueSample( | 1921 histogram_tester_->ExpectUniqueSample( |
| 1857 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1); | 1922 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1); |
| 1858 histogram_tester_->ExpectUniqueSample( | 1923 histogram_tester_->ExpectUniqueSample( |
| 1859 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1); | 1924 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1); |
| 1860 histogram_tester_->ExpectUniqueSample( | 1925 histogram_tester_->ExpectUniqueSample( |
| 1861 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords", | 1926 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords", |
| 1862 2, 1); | 1927 2, 1); |
| 1863 // Don't test the encryption key access. | 1928 // Don't test the encryption key access. |
| 1864 histogram_tester_.reset(); | 1929 histogram_tester_.reset(); |
| 1865 } | 1930 } |
| OLD | NEW |