Index: chrome/browser/password_manager/password_store_mac_unittest.cc |
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc |
index 39f1c7d1b0232560073d70fef988909dc8b2f37d..0aa5ef4d030871eb26a74c66721f947e16c531ee 100644 |
--- a/chrome/browser/password_manager/password_store_mac_unittest.cc |
+++ b/chrome/browser/password_manager/password_store_mac_unittest.cc |
@@ -1173,6 +1173,7 @@ class PasswordStoreMacTest : public testing::Test { |
void SetUp() override { |
ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); |
+ histogram_tester_.reset(new base::HistogramTester); |
// Ensure that LoginDatabase will use the mock keychain if it needs to |
// encrypt/decrypt a password. |
@@ -1198,8 +1199,12 @@ class PasswordStoreMacTest : public testing::Test { |
// in LoginDatabase. The empty valus do not require encryption and therefore |
// OSCrypt shouldn't call the Keychain. The histogram doesn't cover the |
// internet passwords. |
- EXPECT_FALSE(histogram_tester_.GetHistogramSamplesSinceCreation( |
- "OSX.Keychain.Access")); |
+ if (histogram_tester_) { |
+ scoped_ptr<base::HistogramSamples> samples = |
+ histogram_tester_->GetHistogramSamplesSinceCreation( |
+ "OSX.Keychain.Access"); |
+ EXPECT_TRUE(!samples || samples->TotalCount() == 0); |
+ } |
} |
static void InitLoginDatabase(password_manager::LoginDatabase* login_db) { |
@@ -1304,7 +1309,7 @@ class PasswordStoreMacTest : public testing::Test { |
base::ScopedTempDir db_dir_; |
scoped_ptr<password_manager::LoginDatabase> login_db_; |
scoped_refptr<PasswordStoreMac> store_; |
- base::HistogramTester histogram_tester_; |
+ scoped_ptr<base::HistogramTester> histogram_tester_; |
}; |
TEST_F(PasswordStoreMacTest, TestStoreUpdate) { |
@@ -1758,3 +1763,122 @@ TEST_F(PasswordStoreMacTest, StoringAndRetrievingFederatedCredentials) { |
VerifyCredentialLifecycle(form); |
} |
+ |
+void CheckMigrationResult(PasswordStoreMac::MigrationResult expected_result, |
+ PasswordStoreMac::MigrationResult result) { |
+ EXPECT_EQ(expected_result, result); |
+ QuitUIMessageLoop(); |
+} |
+ |
+// Import the passwords from the Keychain to LoginDatabase. |
+TEST_F(PasswordStoreMacTest, ImportFromKeychain) { |
+ PasswordForm form1; |
+ form1.origin = GURL("http://accounts.google.com/LoginAuth"); |
+ form1.signon_realm = "http://accounts.google.com/"; |
+ form1.username_value = ASCIIToUTF16("my_username"); |
+ form1.password_value = ASCIIToUTF16("my_password"); |
+ |
+ PasswordForm form2; |
+ form2.origin = GURL("http://facebook.com/Login"); |
+ form2.signon_realm = "http://facebook.com/"; |
+ form2.username_value = ASCIIToUTF16("my_username"); |
+ form2.password_value = ASCIIToUTF16("my_password"); |
+ |
+ PasswordForm blacklisted_form; |
+ blacklisted_form.origin = GURL("http://badsite.com/Login"); |
+ blacklisted_form.signon_realm = "http://badsite.com/"; |
+ blacklisted_form.blacklisted_by_user = true; |
+ |
+ store()->AddLogin(form1); |
+ store()->AddLogin(form2); |
+ store()->AddLogin(blacklisted_form); |
+ FinishAsyncProcessing(); |
+ |
+ ASSERT_TRUE(base::PostTaskAndReplyWithResult( |
+ thread_->task_runner().get(), FROM_HERE, |
+ base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), |
+ base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); |
+ FinishAsyncProcessing(); |
+ |
+ // The password should be stored in the database by now. |
+ ScopedVector<PasswordForm> matching_items; |
+ EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); |
+ ASSERT_EQ(1u, matching_items.size()); |
+ EXPECT_EQ(form1, *matching_items[0]); |
+ |
+ EXPECT_TRUE(login_db()->GetLogins(form2, &matching_items)); |
+ ASSERT_EQ(1u, matching_items.size()); |
+ EXPECT_EQ(form2, *matching_items[0]); |
+ |
+ EXPECT_TRUE(login_db()->GetLogins(blacklisted_form, &matching_items)); |
+ ASSERT_EQ(1u, matching_items.size()); |
+ EXPECT_EQ(blacklisted_form, *matching_items[0]); |
+ |
+ // The passwords are encrypted using a key from the Keychain. |
+ EXPECT_TRUE(histogram_tester_->GetHistogramSamplesSinceCreation( |
+ "OSX.Keychain.Access")->TotalCount()); |
+ histogram_tester_.reset(); |
+} |
+ |
+// Import a federated credential while the Keychain is locked. |
+TEST_F(PasswordStoreMacTest, ImportFederatedFromLockedKeychain) { |
+ keychain()->set_locked(true); |
+ PasswordForm form1; |
+ form1.origin = GURL("http://example.com/Login"); |
+ form1.signon_realm = "http://example.com/"; |
+ form1.username_value = ASCIIToUTF16("my_username"); |
+ form1.federation_url = GURL("https://accounts.google.com/"); |
+ |
+ store()->AddLogin(form1); |
+ FinishAsyncProcessing(); |
+ ASSERT_TRUE(base::PostTaskAndReplyWithResult( |
+ thread_->task_runner().get(), FROM_HERE, |
+ base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), |
+ base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); |
+ FinishAsyncProcessing(); |
+ |
+ ScopedVector<PasswordForm> matching_items; |
+ EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); |
+ ASSERT_EQ(1u, matching_items.size()); |
+ EXPECT_EQ(form1, *matching_items[0]); |
+} |
+ |
+// Try to import while the Keychain is locked but the encryption key had been |
+// read earlier. |
+TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) { |
+ PasswordForm form1; |
+ form1.origin = GURL("http://accounts.google.com/LoginAuth"); |
+ form1.signon_realm = "http://accounts.google.com/"; |
+ form1.username_value = ASCIIToUTF16("my_username"); |
+ form1.password_value = ASCIIToUTF16("my_password"); |
+ store()->AddLogin(form1); |
+ FinishAsyncProcessing(); |
+ |
+ // Add a second keychain item matching the Database entry. |
+ PasswordForm form2 = form1; |
+ form2.origin = GURL("http://accounts.google.com/Login"); |
+ form2.password_value = ASCIIToUTF16("1234"); |
+ MacKeychainPasswordFormAdapter adapter(keychain()); |
+ EXPECT_TRUE(adapter.AddPassword(form2)); |
+ |
+ keychain()->set_locked(true); |
+ ASSERT_TRUE(base::PostTaskAndReplyWithResult( |
+ thread_->task_runner().get(), FROM_HERE, |
+ base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), |
+ base::Bind(&CheckMigrationResult, PasswordStoreMac::KEYCHAIN_BLOCKED))); |
+ FinishAsyncProcessing(); |
+ |
+ ScopedVector<PasswordForm> matching_items; |
+ EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); |
+ ASSERT_EQ(1u, matching_items.size()); |
+ EXPECT_EQ(base::string16(), matching_items[0]->password_value); |
+ |
+ histogram_tester_->ExpectUniqueSample( |
+ "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1); |
+ histogram_tester_->ExpectUniqueSample( |
+ "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1); |
+ histogram_tester_->ExpectUniqueSample( |
+ "PasswordManager.KeychainMigration.NumChromeOwnedFailedPasswords", 2, 1); |
Ilya Sherman
2015/06/27 05:45:34
How is it possible that the number of Chrome-owned
vasilii
2015/06/29 14:12:45
NumChromeOwnedFailedPasswords counts entries in th
|
+ // Don't test the encryption key access. |
+ histogram_tester_.reset(); |
+} |