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..6c6b32b91aacf23fdcf5131075a13831217b5814 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. |
@@ -1194,12 +1195,17 @@ class PasswordStoreMacTest : public testing::Test { |
ClosePasswordStore(); |
thread_.reset(); |
login_db_.reset(); |
+ crypto::MockAppleKeychain::set_locked(false); |
// Whatever a test did, PasswordStoreMac stores only empty password values |
// 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 +1310,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 +1764,115 @@ 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) { |
+ crypto::MockAppleKeychain::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(); |
+ crypto::MockAppleKeychain::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.NumPasswords", 1, 1); |
+ histogram_tester_->ExpectUniqueSample( |
+ "PasswordManager.KeychainMigration.NumLockedPasswords", 1, 1); |
+ histogram_tester_->ExpectUniqueSample( |
+ "PasswordManager.KeychainMigration.NumChromeOwnedLockedPasswords", 1, 1); |
+ // Don't test the encryption key access. |
+ histogram_tester_.reset(); |
+} |