Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(281)

Unified Diff: chrome/browser/password_manager/password_store_mac_unittest.cc

Issue 1207373002: Implement Mac Keychain migration algorithm. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();
+}

Powered by Google App Engine
This is Rietveld 408576698