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

Side by Side Diff: chrome/browser/password_manager/password_store_mac_unittest.cc

Issue 1089233002: Fix KeychainItemForForm so that it understands not to specify a path in case of Android credentials (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add TODO. Created 5 years, 8 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 unified diff | Download patch
« no previous file with comments | « chrome/browser/password_manager/password_store_mac.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/files/scoped_temp_dir.h" 8 #include "base/files/scoped_temp_dir.h"
9 #include "base/scoped_observer.h" 9 #include "base/scoped_observer.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 {kSecAuthenticationTypeDefault, 290 {kSecAuthenticationTypeDefault,
291 "a.server.com", 291 "a.server.com",
292 kSecProtocolTypeFTP, 292 kSecProtocolTypeFTP,
293 NULL, 293 NULL,
294 0, 294 0,
295 NULL, 295 NULL,
296 "20010203040", 296 "20010203040",
297 "abc", 297 "abc",
298 "123", 298 "123",
299 false}, 299 false},
300 // Password for an Android application.
301 {kSecAuthenticationTypeHTMLForm,
302 "android://hash@com.domain.some/",
303 kSecProtocolTypeHTTP,
304 "",
305 0,
306 NULL,
307 "20150515141312Z",
308 "joe_user",
309 "secret",
310 false},
300 }; 311 };
301 312
302 keychain_ = new MockAppleKeychain(); 313 keychain_ = new MockAppleKeychain();
303 314
304 for (unsigned int i = 0; i < arraysize(test_data); ++i) { 315 for (unsigned int i = 0; i < arraysize(test_data); ++i) {
305 keychain_->AddTestItem(test_data[i]); 316 keychain_->AddTestItem(test_data[i]);
306 } 317 }
307 } 318 }
308 319
309 void TearDown() override { 320 void TearDown() override {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 "http://some.domain.com:4567/insecure.html", L"basic_auth_user", L"basic", 383 "http://some.domain.com:4567/insecure.html", L"basic_auth_user", L"basic",
373 false, 1998, 03, 30, 10, 00, 00 }, 384 false, 1998, 03, 30, 10, 00, 00 },
374 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", 385 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security",
375 "https://some.domain.com/", L"digest_auth_user", L"digest", true, 386 "https://some.domain.com/", L"digest_auth_user", L"digest", true,
376 1998, 3, 30, 10, 0, 0 }, 387 1998, 3, 30, 10, 0, 0 },
377 // This one gives us an invalid date, which we will treat as a "NULL" date 388 // This one gives us an invalid date, which we will treat as a "NULL" date
378 // which is 1601. 389 // which is 1601.
379 { PasswordForm::SCHEME_OTHER, "http://a.server.com/", 390 { PasswordForm::SCHEME_OTHER, "http://a.server.com/",
380 "http://a.server.com/", L"abc", L"123", false, 391 "http://a.server.com/", L"abc", L"123", false,
381 1601, 1, 1, 0, 0, 0 }, 392 1601, 1, 1, 0, 0, 0 },
393 { PasswordForm::SCHEME_HTML, "android://hash@com.domain.some/",
394 "", L"joe_user", L"secret", true,
395 2015, 5, 15, 14, 13, 12 },
382 }; 396 };
383 397
384 for (unsigned int i = 0; i < arraysize(expected); ++i) { 398 for (unsigned int i = 0; i < arraysize(expected); ++i) {
385 // Create our fake KeychainItemRef; see MockAppleKeychain docs. 399 // Create our fake KeychainItemRef; see MockAppleKeychain docs.
386 SecKeychainItemRef keychain_item = 400 SecKeychainItemRef keychain_item =
387 reinterpret_cast<SecKeychainItemRef>(i + 1); 401 reinterpret_cast<SecKeychainItemRef>(i + 1);
388 PasswordForm form; 402 PasswordForm form;
389 bool parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem( 403 bool parsed = internal_keychain_helpers::FillPasswordFormFromKeychainItem(
390 *keychain_, keychain_item, &form, true); 404 *keychain_, keychain_item, &form, true);
391 405
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 << " of base form " << i; 613 << " of base form " << i;
600 } 614 }
601 } 615 }
602 } 616 }
603 617
604 TEST_F(PasswordStoreMacInternalsTest, TestKeychainAdd) { 618 TEST_F(PasswordStoreMacInternalsTest, TestKeychainAdd) {
605 struct TestDataAndExpectation { 619 struct TestDataAndExpectation {
606 PasswordFormData data; 620 PasswordFormData data;
607 bool should_succeed; 621 bool should_succeed;
608 }; 622 };
623 /* clang-format off */
609 TestDataAndExpectation test_data[] = { 624 TestDataAndExpectation test_data[] = {
610 // Test a variety of scheme/port/protocol/path variations. 625 // Test a variety of scheme/port/protocol/path variations.
611 { { PasswordForm::SCHEME_HTML, "http://web.site.com/", 626 { { PasswordForm::SCHEME_HTML, "http://web.site.com/",
612 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, 627 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
613 L"anonymous", L"knock-knock", false, false, 0 }, true }, 628 L"anonymous", L"knock-knock", false, false, 0 }, true },
614 { { PasswordForm::SCHEME_HTML, "https://web.site.com/", 629 { { PasswordForm::SCHEME_HTML, "https://web.site.com/",
615 "https://web.site.com/", NULL, NULL, NULL, NULL, 630 "https://web.site.com/", NULL, NULL, NULL, NULL,
616 L"admin", L"p4ssw0rd", false, false, 0 }, true }, 631 L"admin", L"p4ssw0rd", false, false, 0 }, true },
617 { { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", 632 { { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm",
618 "http://a.site.com:2222/", NULL, NULL, NULL, NULL, 633 "http://a.site.com:2222/", NULL, NULL, NULL, NULL,
619 L"username", L"password", false, false, 0 }, true }, 634 L"username", L"password", false, false, 0 }, true },
620 { { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", 635 { { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm",
621 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, 636 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL,
622 L"testname", L"testpass", false, false, 0 }, true }, 637 L"testname", L"testpass", false, false, 0 }, true },
638 // Test that Android credentials can be stored. Also check the legacy form
639 // when |origin| was still filled with the Android URI (and not left empty).
640 { { PasswordForm::SCHEME_HTML, "android://hash@com.example.alpha/",
641 "", NULL, NULL, NULL, NULL,
642 L"joe_user", L"password", false, true, 0 }, true },
643 { { PasswordForm::SCHEME_HTML, "android://hash@com.example.beta/",
644 "android://hash@com.example.beta/", NULL, NULL, NULL, NULL,
645 L"jane_user", L"password2", false, true, 0 }, true },
623 // Make sure that garbage forms are rejected. 646 // Make sure that garbage forms are rejected.
624 { { PasswordForm::SCHEME_HTML, "gobbledygook", 647 { { PasswordForm::SCHEME_HTML, "gobbledygook",
625 "gobbledygook", NULL, NULL, NULL, NULL, 648 "gobbledygook", NULL, NULL, NULL, NULL,
626 L"anonymous", L"knock-knock", false, false, 0 }, false }, 649 L"anonymous", L"knock-knock", false, false, 0 }, false },
627 // Test that failing to update a duplicate (forced using the magic failure 650 // Test that failing to update a duplicate (forced using the magic failure
628 // password; see MockAppleKeychain::ItemModifyAttributesAndData) is 651 // password; see MockAppleKeychain::ItemModifyAttributesAndData) is
629 // reported. 652 // reported.
630 { { PasswordForm::SCHEME_HTML, "http://some.domain.com", 653 { { PasswordForm::SCHEME_HTML, "http://some.domain.com",
631 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, 654 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL,
632 L"joe_user", L"fail_me", false, false, 0 }, false }, 655 L"joe_user", L"fail_me", false, false, 0 }, false },
633 }; 656 };
657 /* clang-format on */
634 658
635 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 659 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
636 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 660 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
637 661
638 for (unsigned int i = 0; i < arraysize(test_data); ++i) { 662 for (unsigned int i = 0; i < arraysize(test_data); ++i) {
639 scoped_ptr<PasswordForm> in_form = 663 scoped_ptr<PasswordForm> in_form =
640 CreatePasswordFormFromDataForTesting(test_data[i].data); 664 CreatePasswordFormFromDataForTesting(test_data[i].data);
641 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); 665 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form);
642 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); 666 EXPECT_EQ(test_data[i].should_succeed, add_succeeded);
643 if (add_succeeded) { 667 if (add_succeeded) {
644 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm( 668 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm(
645 *in_form)); 669 *in_form));
646 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm( 670 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm(
647 *in_form)); 671 *in_form));
648 } 672 }
649 } 673 }
650 674
651 // Test that adding duplicate item updates the existing item. 675 // Test that adding duplicate item updates the existing item.
676 // TODO(engedy): Add a test to verify that updating Android credentials work.
677 // See: https://crbug.com/476851.
652 { 678 {
653 PasswordFormData data = { 679 PasswordFormData data = {
654 PasswordForm::SCHEME_HTML, "http://some.domain.com", 680 PasswordForm::SCHEME_HTML, "http://some.domain.com",
655 "http://some.domain.com/insecure.html", NULL, 681 "http://some.domain.com/insecure.html", NULL,
656 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 682 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0
657 }; 683 };
658 scoped_ptr<PasswordForm> update_form = 684 scoped_ptr<PasswordForm> update_form =
659 CreatePasswordFormFromDataForTesting(data); 685 CreatePasswordFormFromDataForTesting(data);
660 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 686 MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
661 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); 687 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form));
662 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); 688 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2);
663 PasswordForm stored_form; 689 PasswordForm stored_form;
664 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, 690 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_,
665 keychain_item, 691 keychain_item,
666 &stored_form, 692 &stored_form,
667 true); 693 true);
668 EXPECT_EQ(update_form->password_value, stored_form.password_value); 694 EXPECT_EQ(update_form->password_value, stored_form.password_value);
669 } 695 }
670 } 696 }
671 697
672 TEST_F(PasswordStoreMacInternalsTest, TestKeychainRemove) { 698 TEST_F(PasswordStoreMacInternalsTest, TestKeychainRemove) {
673 struct TestDataAndExpectation { 699 struct TestDataAndExpectation {
674 PasswordFormData data; 700 PasswordFormData data;
675 bool should_succeed; 701 bool should_succeed;
676 }; 702 };
703 /* clang-format off */
677 TestDataAndExpectation test_data[] = { 704 TestDataAndExpectation test_data[] = {
678 // Test deletion of an item that we add. 705 // Test deletion of an item that we add.
679 { { PasswordForm::SCHEME_HTML, "http://web.site.com/", 706 { { PasswordForm::SCHEME_HTML, "http://web.site.com/",
680 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, 707 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL,
681 L"anonymous", L"knock-knock", false, false, 0 }, true }, 708 L"anonymous", L"knock-knock", false, false, 0 }, true },
709 // Test that Android credentials can be removed. Also check the legacy case
710 // when |origin| was still filled with the Android URI (and not left empty).
711 { { PasswordForm::SCHEME_HTML, "android://hash@com.example.alpha/",
712 "", NULL, NULL, NULL, NULL,
713 L"joe_user", L"secret", false, true, 0 }, true },
714 { { PasswordForm::SCHEME_HTML, "android://hash@com.example.beta/",
715 "android://hash@com.example.beta/", NULL, NULL, NULL, NULL,
716 L"jane_user", L"secret", false, true, 0 }, true },
682 // Make sure we don't delete items we don't own. 717 // Make sure we don't delete items we don't own.
683 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", 718 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/",
684 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, 719 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL,
685 L"joe_user", NULL, true, false, 0 }, false }, 720 L"joe_user", NULL, true, false, 0 }, false },
686 }; 721 };
722 /* clang-format on */
687 723
688 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 724 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
689 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 725 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
690 726
691 // Add our test item so that we can delete it. 727 // Add our test items (except the last one) so that we can delete them.
692 scoped_ptr<PasswordForm> add_form = 728 for (unsigned int i = 0; i + 1 < arraysize(test_data); ++i) {
693 CreatePasswordFormFromDataForTesting(test_data[0].data); 729 scoped_ptr<PasswordForm> add_form =
694 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form)); 730 CreatePasswordFormFromDataForTesting(test_data[i].data);
731 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form));
732 }
695 733
696 for (unsigned int i = 0; i < arraysize(test_data); ++i) { 734 for (unsigned int i = 0; i < arraysize(test_data); ++i) {
697 scoped_ptr<PasswordForm> form = 735 scoped_ptr<PasswordForm> form =
698 CreatePasswordFormFromDataForTesting(test_data[i].data); 736 CreatePasswordFormFromDataForTesting(test_data[i].data);
699 EXPECT_EQ(test_data[i].should_succeed, 737 EXPECT_EQ(test_data[i].should_succeed,
700 owned_keychain_adapter.RemovePassword(*form)); 738 owned_keychain_adapter.RemovePassword(*form));
701 739
702 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); 740 MacKeychainPasswordFormAdapter keychain_adapter(keychain_);
703 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form); 741 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form);
704 EXPECT_EQ(test_data[i].should_succeed, !match); 742 EXPECT_EQ(test_data[i].should_succeed, !match);
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 L"testname", L"testpass", false, false, 0 }, 1117 L"testname", L"testpass", false, false, 0 },
1080 }; 1118 };
1081 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) { 1119 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) {
1082 scoped_ptr<PasswordForm> form = 1120 scoped_ptr<PasswordForm> form =
1083 CreatePasswordFormFromDataForTesting(owned_password_data[i]); 1121 CreatePasswordFormFromDataForTesting(owned_password_data[i]);
1084 owned_keychain_adapter.AddPassword(*form); 1122 owned_keychain_adapter.AddPassword(*form);
1085 } 1123 }
1086 1124
1087 ScopedVector<autofill::PasswordForm> all_passwords = 1125 ScopedVector<autofill::PasswordForm> all_passwords =
1088 keychain_adapter.GetAllPasswordFormPasswords(); 1126 keychain_adapter.GetAllPasswordFormPasswords();
1089 EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size()); 1127 EXPECT_EQ(9 + arraysize(owned_password_data), all_passwords.size());
1090 1128
1091 ScopedVector<autofill::PasswordForm> owned_passwords = 1129 ScopedVector<autofill::PasswordForm> owned_passwords =
1092 owned_keychain_adapter.GetAllPasswordFormPasswords(); 1130 owned_keychain_adapter.GetAllPasswordFormPasswords();
1093 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); 1131 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size());
1094 } 1132 }
1095 1133
1096 #pragma mark - 1134 #pragma mark -
1097 1135
1098 class PasswordStoreMacTest : public testing::Test { 1136 class PasswordStoreMacTest : public testing::Test {
1099 public: 1137 public:
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 query_form.password_value.clear(); 1715 query_form.password_value.clear();
1678 query_form.username_value.clear(); 1716 query_form.username_value.clear();
1679 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) 1717 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
1680 .WillOnce( 1718 .WillOnce(
1681 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); 1719 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));
1682 store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT, &mock_consumer); 1720 store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT, &mock_consumer);
1683 base::MessageLoop::current()->Run(); 1721 base::MessageLoop::current()->Run();
1684 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); 1722 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
1685 EXPECT_EQ(form, returned_form); 1723 EXPECT_EQ(form, returned_form);
1686 } 1724 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_store_mac.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698