Chromium Code Reviews| 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 "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" |
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "base/synchronization/waitable_event.h" | 13 #include "base/synchronization/waitable_event.h" |
| 14 #include "chrome/browser/password_manager/password_store_mac_internal.h" | 14 #include "chrome/browser/password_manager/password_store_mac_internal.h" |
| 15 #include "chrome/common/chrome_paths.h" | 15 #include "chrome/common/chrome_paths.h" |
| 16 #include "components/password_manager/core/browser/login_database.h" | 16 #include "components/password_manager/core/browser/login_database.h" |
| 17 #include "components/password_manager/core/browser/password_form_data.h" | |
| 17 #include "components/password_manager/core/browser/password_store_consumer.h" | 18 #include "components/password_manager/core/browser/password_store_consumer.h" |
| 18 #include "content/public/test/test_browser_thread.h" | 19 #include "content/public/test/test_browser_thread.h" |
| 19 #include "crypto/mock_apple_keychain.h" | 20 #include "crypto/mock_apple_keychain.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 23 |
| 23 using autofill::PasswordForm; | 24 using autofill::PasswordForm; |
| 24 using base::ASCIIToUTF16; | 25 using base::ASCIIToUTF16; |
| 25 using base::WideToUTF16; | 26 using base::WideToUTF16; |
| 26 using content::BrowserThread; | 27 using content::BrowserThread; |
| 27 using crypto::MockAppleKeychain; | 28 using crypto::MockAppleKeychain; |
| 28 using internal_keychain_helpers::FormsMatchForMerge; | 29 using internal_keychain_helpers::FormsMatchForMerge; |
| 29 using internal_keychain_helpers::STRICT_FORM_MATCH; | 30 using internal_keychain_helpers::STRICT_FORM_MATCH; |
| 30 using password_manager::LoginDatabase; | 31 using password_manager::LoginDatabase; |
| 31 using password_manager::PasswordStore; | 32 using password_manager::PasswordStore; |
| 32 using password_manager::PasswordStoreConsumer; | 33 using password_manager::PasswordStoreConsumer; |
| 33 using testing::_; | 34 using testing::_; |
| 34 using testing::DoAll; | 35 using testing::DoAll; |
| 36 using testing::ElementsAre; | |
| 35 using testing::Invoke; | 37 using testing::Invoke; |
| 38 using testing::SizeIs; | |
| 36 using testing::WithArg; | 39 using testing::WithArg; |
| 37 | 40 |
| 38 namespace { | 41 namespace { |
| 39 | 42 |
| 40 ACTION(STLDeleteElements0) { | |
| 41 STLDeleteContainerPointers(arg0.begin(), arg0.end()); | |
| 42 } | |
| 43 | |
| 44 ACTION(QuitUIMessageLoop) { | 43 ACTION(QuitUIMessageLoop) { |
| 45 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 46 base::MessageLoop::current()->Quit(); | 45 base::MessageLoop::current()->Quit(); |
| 47 } | 46 } |
| 48 | 47 |
| 49 class MockPasswordStoreConsumer : public PasswordStoreConsumer { | 48 class MockPasswordStoreConsumer : public PasswordStoreConsumer { |
| 50 public: | 49 public: |
| 51 MOCK_METHOD1(OnGetPasswordStoreResults, | 50 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, |
| 52 void(const std::vector<autofill::PasswordForm*>&)); | 51 void(const std::vector<PasswordForm*>&)); |
| 53 | 52 |
| 54 void CopyElements(const std::vector<autofill::PasswordForm*>& forms) { | 53 // GMock cannot mock methods with move-only args. |
| 55 last_result.clear(); | 54 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override { |
| 56 for (size_t i = 0; i < forms.size(); ++i) { | 55 OnGetPasswordStoreResultsConstRef(results.get()); |
| 57 last_result.push_back(*forms[i]); | |
| 58 } | |
| 59 } | 56 } |
| 60 | 57 |
| 61 // Runs the current thread's message loop until OnGetPasswordStoreResults() | 58 void SaveACopyOfFirstForm(const std::vector<PasswordForm*>& result) { |
|
vasilii
2015/02/05 19:23:27
Turn it to the action taking an argument (Password
vabr (Chromium)
2015/02/06 14:16:05
Done.
| |
| 62 // is posted to it. This method should be called immediately after GetLogins, | 59 DCHECK(!result.empty()); |
| 63 // without pumping the message loop in-between. | 60 first_form = *result[0]; |
| 64 void WaitOnGetPasswordStoreResults() { | |
| 65 EXPECT_CALL(*this, OnGetPasswordStoreResults(_)).WillOnce(DoAll( | |
| 66 WithArg<0>(Invoke(this, &MockPasswordStoreConsumer::CopyElements)), | |
| 67 WithArg<0>(STLDeleteElements0()), | |
| 68 QuitUIMessageLoop())); | |
| 69 base::MessageLoop::current()->Run(); | |
| 70 } | 61 } |
| 71 | 62 |
| 72 std::vector<PasswordForm> last_result; | 63 PasswordForm first_form; // First form of the returned result, if any. |
| 73 }; | 64 }; |
| 74 | 65 |
| 75 class MockPasswordStoreObserver : public PasswordStore::Observer { | 66 class MockPasswordStoreObserver : public PasswordStore::Observer { |
| 76 public: | 67 public: |
| 77 MOCK_METHOD1(OnLoginsChanged, | 68 MOCK_METHOD1(OnLoginsChanged, |
| 78 void(const password_manager::PasswordStoreChangeList& changes)); | 69 void(const password_manager::PasswordStoreChangeList& changes)); |
| 79 }; | 70 }; |
| 80 | 71 |
| 81 // A mock LoginDatabase that simulates a failing Init() method. | 72 // A mock LoginDatabase that simulates a failing Init() method. |
| 82 class BadLoginDatabase : public password_manager::LoginDatabase { | 73 class BadLoginDatabase : public password_manager::LoginDatabase { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 const wchar_t* submit_element; | 214 const wchar_t* submit_element; |
| 224 const wchar_t* username_element; | 215 const wchar_t* username_element; |
| 225 const wchar_t* password_element; | 216 const wchar_t* password_element; |
| 226 const wchar_t* username_value; // Set to NULL for a blacklist entry. | 217 const wchar_t* username_value; // Set to NULL for a blacklist entry. |
| 227 const wchar_t* password_value; | 218 const wchar_t* password_value; |
| 228 const bool preferred; | 219 const bool preferred; |
| 229 const bool ssl_valid; | 220 const bool ssl_valid; |
| 230 const double creation_time; | 221 const double creation_time; |
| 231 }; | 222 }; |
| 232 | 223 |
| 233 // Creates and returns a new PasswordForm built from form_data. Caller is | 224 // Creates and returns a new PasswordForm built from form_data. |
| 234 // responsible for deleting the object when finished with it. | 225 static scoped_ptr<PasswordForm> CreatePasswordFormFromData( |
|
vasilii
2015/02/05 19:23:26
I'd put this method and it's neighbors to the name
vabr (Chromium)
2015/02/06 14:16:05
Done.
BTW., this method and the struct will be rem
| |
| 235 static PasswordForm* CreatePasswordFormFromData( | |
| 236 const PasswordFormData& form_data) { | 226 const PasswordFormData& form_data) { |
| 237 PasswordForm* form = new PasswordForm(); | 227 scoped_ptr<PasswordForm> form(new PasswordForm()); |
| 238 form->scheme = form_data.scheme; | 228 form->scheme = form_data.scheme; |
| 239 form->preferred = form_data.preferred; | 229 form->preferred = form_data.preferred; |
| 240 form->ssl_valid = form_data.ssl_valid; | 230 form->ssl_valid = form_data.ssl_valid; |
| 241 form->date_created = base::Time::FromDoubleT(form_data.creation_time); | 231 form->date_created = base::Time::FromDoubleT(form_data.creation_time); |
| 242 form->date_synced = form->date_created + base::TimeDelta::FromDays(1); | 232 form->date_synced = form->date_created + base::TimeDelta::FromDays(1); |
| 243 if (form_data.signon_realm) | 233 if (form_data.signon_realm) |
| 244 form->signon_realm = std::string(form_data.signon_realm); | 234 form->signon_realm = std::string(form_data.signon_realm); |
| 245 if (form_data.origin) | 235 if (form_data.origin) |
| 246 form->origin = GURL(form_data.origin); | 236 form->origin = GURL(form_data.origin); |
| 247 if (form_data.action) | 237 if (form_data.action) |
| 248 form->action = GURL(form_data.action); | 238 form->action = GURL(form_data.action); |
| 249 if (form_data.submit_element) | 239 if (form_data.submit_element) |
| 250 form->submit_element = WideToUTF16(form_data.submit_element); | 240 form->submit_element = WideToUTF16(form_data.submit_element); |
| 251 if (form_data.username_element) | 241 if (form_data.username_element) |
| 252 form->username_element = WideToUTF16(form_data.username_element); | 242 form->username_element = WideToUTF16(form_data.username_element); |
| 253 if (form_data.password_element) | 243 if (form_data.password_element) |
| 254 form->password_element = WideToUTF16(form_data.password_element); | 244 form->password_element = WideToUTF16(form_data.password_element); |
| 255 if (form_data.username_value) { | 245 if (form_data.username_value) { |
| 256 form->username_value = WideToUTF16(form_data.username_value); | 246 form->username_value = WideToUTF16(form_data.username_value); |
| 257 form->display_name = form->username_value; | 247 form->display_name = form->username_value; |
| 258 form->is_zero_click = true; | 248 form->is_zero_click = true; |
| 259 if (form_data.password_value) | 249 if (form_data.password_value) |
| 260 form->password_value = WideToUTF16(form_data.password_value); | 250 form->password_value = WideToUTF16(form_data.password_value); |
| 261 } else { | 251 } else { |
| 262 form->blacklisted_by_user = true; | 252 form->blacklisted_by_user = true; |
| 263 } | 253 } |
| 264 form->avatar_url = GURL("https://accounts.google.com/Avatar"); | 254 form->avatar_url = GURL("https://accounts.google.com/Avatar"); |
| 265 form->federation_url = GURL("https://accounts.google.com/login"); | 255 form->federation_url = GURL("https://accounts.google.com/login"); |
| 266 return form; | 256 return form.Pass(); |
| 267 } | 257 } |
| 268 | 258 |
| 269 // Macro to simplify calling CheckFormsAgainstExpectations with a useful label. | 259 // Macro to simplify calling CheckFormsAgainstExpectations with a useful label. |
| 270 #define CHECK_FORMS(forms, expectations, i) \ | 260 #define CHECK_FORMS(forms, expectations, i) \ |
| 271 CheckFormsAgainstExpectations(forms, expectations, #forms, i) | 261 CheckFormsAgainstExpectations(forms, expectations, #forms, i) |
| 272 | 262 |
| 273 // Ensures that the data in |forms| match |expectations|, causing test failures | 263 // Ensures that the data in |forms| match |expectations|, causing test failures |
| 274 // for any discrepencies. | 264 // for any discrepencies. |
| 275 // TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't | 265 // TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't |
| 276 // matter if |forms| and |expectations| are scrambled. | 266 // matter if |forms| and |expectations| are scrambled. |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 0, 0 }, | 460 0, 0 }, |
| 471 // Garbage forms should have no matches. | 461 // Garbage forms should have no matches. |
| 472 { { PasswordForm::SCHEME_HTML, "foo/bar/baz", | 462 { { PasswordForm::SCHEME_HTML, "foo/bar/baz", |
| 473 NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 }, | 463 NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 }, |
| 474 }; | 464 }; |
| 475 | 465 |
| 476 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); | 466 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); |
| 477 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); | 467 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); |
| 478 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 468 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 479 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | 469 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
| 480 scoped_ptr<PasswordForm> query_form( | 470 scoped_ptr<PasswordForm> query_form = |
| 481 CreatePasswordFormFromData(test_data[i].data)); | 471 CreatePasswordFormFromData(test_data[i].data); |
| 482 | 472 |
| 483 // Check matches treating the form as a fill target. | 473 // Check matches treating the form as a fill target. |
| 484 ScopedVector<autofill::PasswordForm> matching_items = | 474 ScopedVector<autofill::PasswordForm> matching_items = |
| 485 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, | 475 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, |
| 486 query_form->scheme); | 476 query_form->scheme); |
| 487 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size()); | 477 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size()); |
| 488 matching_items.clear(); | 478 matching_items.clear(); |
| 489 | 479 |
| 490 // Check matches treating the form as a merging target. | 480 // Check matches treating the form as a merging target. |
| 491 EXPECT_EQ(test_data[i].expected_merge_matches > 0, | 481 EXPECT_EQ(test_data[i].expected_merge_matches > 0, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", | 540 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", |
| 551 "http://some.domain.com:4567/insecure.html", | 541 "http://some.domain.com:4567/insecure.html", |
| 552 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 }, | 542 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 }, |
| 553 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", | 543 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", |
| 554 "https://some.domain.com", | 544 "https://some.domain.com", |
| 555 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 }, | 545 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 }, |
| 556 }; | 546 }; |
| 557 | 547 |
| 558 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) { | 548 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) { |
| 559 // Create a base form and make sure we find a match. | 549 // Create a base form and make sure we find a match. |
| 560 scoped_ptr<PasswordForm> base_form(CreatePasswordFormFromData( | 550 scoped_ptr<PasswordForm> base_form = |
| 561 base_form_data[i])); | 551 CreatePasswordFormFromData(base_form_data[i]); |
| 562 EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form)); | 552 EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form)); |
| 563 EXPECT_TRUE(keychain_adapter.HasPasswordExactlyMatchingForm(*base_form)); | 553 EXPECT_TRUE(keychain_adapter.HasPasswordExactlyMatchingForm(*base_form)); |
| 564 | 554 |
| 565 // Make sure that the matching isn't looser than it should be by checking | 555 // Make sure that the matching isn't looser than it should be by checking |
| 566 // that slightly altered forms don't match. | 556 // that slightly altered forms don't match. |
| 567 ScopedVector<autofill::PasswordForm> modified_forms; | 557 ScopedVector<autofill::PasswordForm> modified_forms; |
| 568 | 558 |
| 569 modified_forms.push_back(new PasswordForm(*base_form)); | 559 modified_forms.push_back(new PasswordForm(*base_form)); |
| 570 modified_forms.back()->username_value = ASCIIToUTF16("wrong_user"); | 560 modified_forms.back()->username_value = ASCIIToUTF16("wrong_user"); |
| 571 | 561 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 // reported. | 614 // reported. |
| 625 { { PasswordForm::SCHEME_HTML, "http://some.domain.com", | 615 { { PasswordForm::SCHEME_HTML, "http://some.domain.com", |
| 626 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, | 616 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, |
| 627 L"joe_user", L"fail_me", false, false, 0 }, false }, | 617 L"joe_user", L"fail_me", false, false, 0 }, false }, |
| 628 }; | 618 }; |
| 629 | 619 |
| 630 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); | 620 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); |
| 631 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 621 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 632 | 622 |
| 633 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | 623 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
| 634 scoped_ptr<PasswordForm> in_form( | 624 scoped_ptr<PasswordForm> in_form = |
| 635 CreatePasswordFormFromData(test_data[i].data)); | 625 CreatePasswordFormFromData(test_data[i].data); |
| 636 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); | 626 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); |
| 637 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); | 627 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); |
| 638 if (add_succeeded) { | 628 if (add_succeeded) { |
| 639 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm( | 629 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm( |
| 640 *in_form)); | 630 *in_form)); |
| 641 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm( | 631 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm( |
| 642 *in_form)); | 632 *in_form)); |
| 643 } | 633 } |
| 644 } | 634 } |
| 645 | 635 |
| 646 // Test that adding duplicate item updates the existing item. | 636 // Test that adding duplicate item updates the existing item. |
| 647 { | 637 { |
| 648 PasswordFormData data = { | 638 PasswordFormData data = { |
| 649 PasswordForm::SCHEME_HTML, "http://some.domain.com", | 639 PasswordForm::SCHEME_HTML, "http://some.domain.com", |
| 650 "http://some.domain.com/insecure.html", NULL, | 640 "http://some.domain.com/insecure.html", NULL, |
| 651 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 | 641 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 |
| 652 }; | 642 }; |
| 653 scoped_ptr<PasswordForm> update_form(CreatePasswordFormFromData(data)); | 643 scoped_ptr<PasswordForm> update_form = CreatePasswordFormFromData(data); |
| 654 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); | 644 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); |
| 655 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); | 645 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); |
| 656 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); | 646 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); |
| 657 PasswordForm stored_form; | 647 PasswordForm stored_form; |
| 658 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, | 648 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, |
| 659 keychain_item, | 649 keychain_item, |
| 660 &stored_form, | 650 &stored_form, |
| 661 true); | 651 true); |
| 662 EXPECT_EQ(update_form->password_value, stored_form.password_value); | 652 EXPECT_EQ(update_form->password_value, stored_form.password_value); |
| 663 } | 653 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 676 // Make sure we don't delete items we don't own. | 666 // Make sure we don't delete items we don't own. |
| 677 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", | 667 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", |
| 678 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, | 668 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, |
| 679 L"joe_user", NULL, true, false, 0 }, false }, | 669 L"joe_user", NULL, true, false, 0 }, false }, |
| 680 }; | 670 }; |
| 681 | 671 |
| 682 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); | 672 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); |
| 683 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 673 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 684 | 674 |
| 685 // Add our test item so that we can delete it. | 675 // Add our test item so that we can delete it. |
| 686 PasswordForm* add_form = CreatePasswordFormFromData(test_data[0].data); | 676 scoped_ptr<PasswordForm> add_form = |
| 677 CreatePasswordFormFromData(test_data[0].data); | |
| 687 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form)); | 678 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form)); |
| 688 delete add_form; | |
| 689 | 679 |
| 690 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | 680 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
| 691 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( | 681 scoped_ptr<PasswordForm> form = |
| 692 test_data[i].data)); | 682 CreatePasswordFormFromData(test_data[i].data); |
| 693 EXPECT_EQ(test_data[i].should_succeed, | 683 EXPECT_EQ(test_data[i].should_succeed, |
| 694 owned_keychain_adapter.RemovePassword(*form)); | 684 owned_keychain_adapter.RemovePassword(*form)); |
| 695 | 685 |
| 696 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); | 686 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); |
| 697 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form); | 687 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form); |
| 698 EXPECT_EQ(test_data[i].should_succeed, !match); | 688 EXPECT_EQ(test_data[i].should_succeed, !match); |
| 699 } | 689 } |
| 700 } | 690 } |
| 701 | 691 |
| 702 TEST_F(PasswordStoreMacInternalsTest, TestFormMatch) { | 692 TEST_F(PasswordStoreMacInternalsTest, TestFormMatch) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 883 test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path); | 873 test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path); |
| 884 test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1); | 874 test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1); |
| 885 test_data[MERGE_OUTPUT][current_test].push_back( | 875 test_data[MERGE_OUTPUT][current_test].push_back( |
| 886 &merged_user_1_with_both_paths); | 876 &merged_user_1_with_both_paths); |
| 887 | 877 |
| 888 for (unsigned int test_case = 0; test_case <= current_test; ++test_case) { | 878 for (unsigned int test_case = 0; test_case <= current_test; ++test_case) { |
| 889 ScopedVector<autofill::PasswordForm> keychain_forms; | 879 ScopedVector<autofill::PasswordForm> keychain_forms; |
| 890 for (std::vector<PasswordFormData*>::iterator i = | 880 for (std::vector<PasswordFormData*>::iterator i = |
| 891 test_data[KEYCHAIN_INPUT][test_case].begin(); | 881 test_data[KEYCHAIN_INPUT][test_case].begin(); |
| 892 i != test_data[KEYCHAIN_INPUT][test_case].end(); ++i) { | 882 i != test_data[KEYCHAIN_INPUT][test_case].end(); ++i) { |
| 893 keychain_forms.push_back(CreatePasswordFormFromData(*(*i))); | 883 keychain_forms.push_back(CreatePasswordFormFromData(*(*i)).release()); |
| 894 } | 884 } |
| 895 ScopedVector<autofill::PasswordForm> database_forms; | 885 ScopedVector<autofill::PasswordForm> database_forms; |
| 896 for (std::vector<PasswordFormData*>::iterator i = | 886 for (std::vector<PasswordFormData*>::iterator i = |
| 897 test_data[DATABASE_INPUT][test_case].begin(); | 887 test_data[DATABASE_INPUT][test_case].begin(); |
| 898 i != test_data[DATABASE_INPUT][test_case].end(); ++i) { | 888 i != test_data[DATABASE_INPUT][test_case].end(); ++i) { |
| 899 database_forms.push_back(CreatePasswordFormFromData(*(*i))); | 889 database_forms.push_back(CreatePasswordFormFromData(*(*i)).release()); |
| 900 } | 890 } |
| 901 | 891 |
| 902 ScopedVector<autofill::PasswordForm> merged_forms; | 892 ScopedVector<autofill::PasswordForm> merged_forms; |
| 903 internal_keychain_helpers::MergePasswordForms(&keychain_forms, | 893 internal_keychain_helpers::MergePasswordForms(&keychain_forms, |
| 904 &database_forms, | 894 &database_forms, |
| 905 &merged_forms); | 895 &merged_forms); |
| 906 | 896 |
| 907 CHECK_FORMS(keychain_forms.get(), test_data[KEYCHAIN_OUTPUT][test_case], | 897 CHECK_FORMS(keychain_forms.get(), test_data[KEYCHAIN_OUTPUT][test_case], |
| 908 test_case); | 898 test_case); |
| 909 CHECK_FORMS(database_forms.get(), test_data[DATABASE_OUTPUT][test_case], | 899 CHECK_FORMS(database_forms.get(), test_data[DATABASE_OUTPUT][test_case], |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 934 "http://dont.remember.com/handlepage.cgi", | 924 "http://dont.remember.com/handlepage.cgi", |
| 935 L"submit", L"username", L"password", L"joe_user", L"", | 925 L"submit", L"username", L"password", L"joe_user", L"", |
| 936 true, false, 1240000000 }, | 926 true, false, 1240000000 }, |
| 937 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", | 927 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", |
| 938 "http://some.domain.com/path.html", "http://some.domain.com/action.cgi", | 928 "http://some.domain.com/path.html", "http://some.domain.com/action.cgi", |
| 939 L"submit", L"username", L"password", NULL, NULL, | 929 L"submit", L"username", L"password", NULL, NULL, |
| 940 true, false, 1212121212 }, | 930 true, false, 1212121212 }, |
| 941 }; | 931 }; |
| 942 ScopedVector<autofill::PasswordForm> database_forms; | 932 ScopedVector<autofill::PasswordForm> database_forms; |
| 943 for (unsigned int i = 0; i < arraysize(db_data); ++i) { | 933 for (unsigned int i = 0; i < arraysize(db_data); ++i) { |
| 944 database_forms.push_back(CreatePasswordFormFromData(db_data[i])); | 934 database_forms.push_back(CreatePasswordFormFromData(db_data[i]).release()); |
| 945 } | 935 } |
| 946 ScopedVector<autofill::PasswordForm> merged_forms; | 936 ScopedVector<autofill::PasswordForm> merged_forms; |
| 947 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 937 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, |
| 948 &merged_forms); | 938 &merged_forms); |
| 949 EXPECT_EQ(2U, database_forms.size()); | 939 EXPECT_EQ(2U, database_forms.size()); |
| 950 ASSERT_EQ(3U, merged_forms.size()); | 940 ASSERT_EQ(3U, merged_forms.size()); |
| 951 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value); | 941 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value); |
| 952 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value); | 942 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value); |
| 953 EXPECT_TRUE(merged_forms[2]->blacklisted_by_user); | 943 EXPECT_TRUE(merged_forms[2]->blacklisted_by_user); |
| 954 } | 944 } |
| 955 | 945 |
| 956 TEST_F(PasswordStoreMacInternalsTest, TestBlacklistedFiltering) { | 946 TEST_F(PasswordStoreMacInternalsTest, TestBlacklistedFiltering) { |
| 957 PasswordFormData db_data[] = { | 947 PasswordFormData db_data[] = { |
| 958 { PasswordForm::SCHEME_HTML, "http://dont.remember.com/", | 948 { PasswordForm::SCHEME_HTML, "http://dont.remember.com/", |
| 959 "http://dont.remember.com/", | 949 "http://dont.remember.com/", |
| 960 "http://dont.remember.com/handlepage.cgi", | 950 "http://dont.remember.com/handlepage.cgi", |
| 961 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", | 951 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", |
| 962 true, false, 1240000000 }, | 952 true, false, 1240000000 }, |
| 963 { PasswordForm::SCHEME_HTML, "https://dont.remember.com/", | 953 { PasswordForm::SCHEME_HTML, "https://dont.remember.com/", |
| 964 "https://dont.remember.com/", | 954 "https://dont.remember.com/", |
| 965 "https://dont.remember.com/handlepage_secure.cgi", | 955 "https://dont.remember.com/handlepage_secure.cgi", |
| 966 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", | 956 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", |
| 967 true, false, 1240000000 }, | 957 true, false, 1240000000 }, |
| 968 }; | 958 }; |
| 969 ScopedVector<autofill::PasswordForm> database_forms; | 959 ScopedVector<autofill::PasswordForm> database_forms; |
| 970 for (unsigned int i = 0; i < arraysize(db_data); ++i) { | 960 for (unsigned int i = 0; i < arraysize(db_data); ++i) { |
| 971 database_forms.push_back(CreatePasswordFormFromData(db_data[i])); | 961 database_forms.push_back(CreatePasswordFormFromData(db_data[i]).release()); |
| 972 } | 962 } |
| 973 ScopedVector<autofill::PasswordForm> merged_forms; | 963 ScopedVector<autofill::PasswordForm> merged_forms; |
| 974 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 964 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, |
| 975 &merged_forms); | 965 &merged_forms); |
| 976 EXPECT_EQ(2U, database_forms.size()); | 966 EXPECT_EQ(2U, database_forms.size()); |
| 977 ASSERT_EQ(0U, merged_forms.size()); | 967 ASSERT_EQ(0U, merged_forms.size()); |
| 978 } | 968 } |
| 979 | 969 |
| 980 TEST_F(PasswordStoreMacInternalsTest, TestFillPasswordFormFromKeychainItem) { | 970 TEST_F(PasswordStoreMacInternalsTest, TestFillPasswordFormFromKeychainItem) { |
| 981 // When |extract_password_data| is false, the password field must be empty, | 971 // When |extract_password_data| is false, the password field must be empty, |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1062 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, | 1052 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, |
| 1063 L"anonymous", L"knock-knock", false, false, 0 }, | 1053 L"anonymous", L"knock-knock", false, false, 0 }, |
| 1064 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", | 1054 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", |
| 1065 "http://a.site.com:2222/", NULL, NULL, NULL, NULL, | 1055 "http://a.site.com:2222/", NULL, NULL, NULL, NULL, |
| 1066 L"username", L"password", false, false, 0 }, | 1056 L"username", L"password", false, false, 0 }, |
| 1067 { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", | 1057 { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", |
| 1068 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, | 1058 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, |
| 1069 L"testname", L"testpass", false, false, 0 }, | 1059 L"testname", L"testpass", false, false, 0 }, |
| 1070 }; | 1060 }; |
| 1071 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) { | 1061 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) { |
| 1072 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( | 1062 scoped_ptr<PasswordForm> form = |
| 1073 owned_password_data[i])); | 1063 CreatePasswordFormFromData(owned_password_data[i]); |
| 1074 owned_keychain_adapter.AddPassword(*form); | 1064 owned_keychain_adapter.AddPassword(*form); |
| 1075 } | 1065 } |
| 1076 | 1066 |
| 1077 ScopedVector<autofill::PasswordForm> all_passwords = | 1067 ScopedVector<autofill::PasswordForm> all_passwords = |
| 1078 keychain_adapter.GetAllPasswordFormPasswords(); | 1068 keychain_adapter.GetAllPasswordFormPasswords(); |
| 1079 EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size()); | 1069 EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size()); |
| 1080 | 1070 |
| 1081 ScopedVector<autofill::PasswordForm> owned_passwords = | 1071 ScopedVector<autofill::PasswordForm> owned_passwords = |
| 1082 owned_keychain_adapter.GetAllPasswordFormPasswords(); | 1072 owned_keychain_adapter.GetAllPasswordFormPasswords(); |
| 1083 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); | 1073 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1130 | 1120 |
| 1131 MockAppleKeychain* keychain() { | 1121 MockAppleKeychain* keychain() { |
| 1132 return static_cast<MockAppleKeychain*>(store_->keychain()); | 1122 return static_cast<MockAppleKeychain*>(store_->keychain()); |
| 1133 } | 1123 } |
| 1134 | 1124 |
| 1135 void FinishAsyncProcessing() { | 1125 void FinishAsyncProcessing() { |
| 1136 // Do a store-level query to wait for all the previously enqueued operations | 1126 // Do a store-level query to wait for all the previously enqueued operations |
| 1137 // to finish. | 1127 // to finish. |
| 1138 MockPasswordStoreConsumer consumer; | 1128 MockPasswordStoreConsumer consumer; |
| 1139 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer); | 1129 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer); |
| 1140 consumer.WaitOnGetPasswordStoreResults(); | 1130 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(_)) |
| 1131 .WillOnce(QuitUIMessageLoop()); | |
| 1132 base::MessageLoop::current()->Run(); | |
| 1141 } | 1133 } |
| 1142 | 1134 |
| 1143 TestPasswordStoreMac* store() { return store_.get(); } | 1135 TestPasswordStoreMac* store() { return store_.get(); } |
| 1144 | 1136 |
| 1145 protected: | 1137 protected: |
| 1146 base::MessageLoopForUI message_loop_; | 1138 base::MessageLoopForUI message_loop_; |
| 1147 content::TestBrowserThread ui_thread_; | 1139 content::TestBrowserThread ui_thread_; |
| 1148 | 1140 |
| 1149 base::ScopedTempDir db_dir_; | 1141 base::ScopedTempDir db_dir_; |
| 1150 scoped_refptr<TestPasswordStoreMac> store_; | 1142 scoped_refptr<TestPasswordStoreMac> store_; |
| 1151 }; | 1143 }; |
| 1152 | 1144 |
| 1153 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { | 1145 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { |
| 1154 // Insert a password into both the database and the keychain. | 1146 // Insert a password into both the database and the keychain. |
| 1155 // This is done manually, rather than through store_->AddLogin, because the | 1147 // This is done manually, rather than through store_->AddLogin, because the |
| 1156 // Mock Keychain isn't smart enough to be able to support update generically, | 1148 // Mock Keychain isn't smart enough to be able to support update generically, |
| 1157 // so some.domain.com triggers special handling to test it that make inserting | 1149 // so some.domain.com triggers special handling to test it that make inserting |
| 1158 // fail. | 1150 // fail. |
| 1159 PasswordFormData joint_data = { | 1151 PasswordFormData joint_data = { |
| 1160 PasswordForm::SCHEME_HTML, "http://some.domain.com/", | 1152 PasswordForm::SCHEME_HTML, "http://some.domain.com/", |
| 1161 "http://some.domain.com/insecure.html", "login.cgi", | 1153 "http://some.domain.com/insecure.html", "login.cgi", |
| 1162 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 | 1154 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 |
| 1163 }; | 1155 }; |
| 1164 scoped_ptr<PasswordForm> joint_form(CreatePasswordFormFromData(joint_data)); | 1156 scoped_ptr<PasswordForm> joint_form = CreatePasswordFormFromData(joint_data); |
| 1165 login_db()->AddLogin(*joint_form); | 1157 login_db()->AddLogin(*joint_form); |
| 1166 MockAppleKeychain::KeychainTestData joint_keychain_data = { | 1158 MockAppleKeychain::KeychainTestData joint_keychain_data = { |
| 1167 kSecAuthenticationTypeHTMLForm, "some.domain.com", | 1159 kSecAuthenticationTypeHTMLForm, "some.domain.com", |
| 1168 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z", | 1160 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z", |
| 1169 "joe_user", "sekrit", false }; | 1161 "joe_user", "sekrit", false }; |
| 1170 keychain()->AddTestItem(joint_keychain_data); | 1162 keychain()->AddTestItem(joint_keychain_data); |
| 1171 | 1163 |
| 1172 // Insert a password into the keychain only. | 1164 // Insert a password into the keychain only. |
| 1173 MockAppleKeychain::KeychainTestData keychain_only_data = { | 1165 MockAppleKeychain::KeychainTestData keychain_only_data = { |
| 1174 kSecAuthenticationTypeHTMLForm, "keychain.only.com", | 1166 kSecAuthenticationTypeHTMLForm, "keychain.only.com", |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1203 // case where a form is filled, then the stored login is removed, then the | 1195 // case where a form is filled, then the stored login is removed, then the |
| 1204 // form is submitted. | 1196 // form is submitted. |
| 1205 { { PasswordForm::SCHEME_HTML, "http://different.com/", | 1197 { { PasswordForm::SCHEME_HTML, "http://different.com/", |
| 1206 "http://different.com/index.html", "login.cgi", | 1198 "http://different.com/index.html", "login.cgi", |
| 1207 L"username", L"password", L"submit", L"abc", L"123", | 1199 L"username", L"password", L"submit", L"abc", L"123", |
| 1208 true, false, 2 }, | 1200 true, false, 2 }, |
| 1209 NULL, | 1201 NULL, |
| 1210 }, | 1202 }, |
| 1211 }; | 1203 }; |
| 1212 for (unsigned int i = 0; i < arraysize(updates); ++i) { | 1204 for (unsigned int i = 0; i < arraysize(updates); ++i) { |
| 1213 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( | 1205 scoped_ptr<PasswordForm> form = |
| 1214 updates[i].form_data)); | 1206 CreatePasswordFormFromData(updates[i].form_data); |
| 1215 store_->UpdateLogin(*form); | 1207 store_->UpdateLogin(*form); |
| 1216 } | 1208 } |
| 1217 | 1209 |
| 1218 FinishAsyncProcessing(); | 1210 FinishAsyncProcessing(); |
| 1219 | 1211 |
| 1220 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); | 1212 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); |
| 1221 for (unsigned int i = 0; i < arraysize(updates); ++i) { | 1213 for (unsigned int i = 0; i < arraysize(updates); ++i) { |
| 1222 scoped_ptr<PasswordForm> query_form( | 1214 scoped_ptr<PasswordForm> query_form = |
| 1223 CreatePasswordFormFromData(updates[i].form_data)); | 1215 CreatePasswordFormFromData(updates[i].form_data); |
| 1224 | 1216 |
| 1225 ScopedVector<autofill::PasswordForm> matching_items = | 1217 ScopedVector<autofill::PasswordForm> matching_items = |
| 1226 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, | 1218 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, |
| 1227 query_form->scheme); | 1219 query_form->scheme); |
| 1228 if (updates[i].password) { | 1220 if (updates[i].password) { |
| 1229 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i; | 1221 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i; |
| 1230 if (matching_items.size() >= 1) | 1222 if (matching_items.size() >= 1) |
| 1231 EXPECT_EQ(ASCIIToUTF16(updates[i].password), | 1223 EXPECT_EQ(ASCIIToUTF16(updates[i].password), |
| 1232 matching_items[0]->password_value) << "iteration " << i; | 1224 matching_items[0]->password_value) << "iteration " << i; |
| 1233 } else { | 1225 } else { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1256 // www.facebook.com password from the login database, we should not be blocked | 1248 // www.facebook.com password from the login database, we should not be blocked |
| 1257 // from deleting it from the keystore just becaus the m.facebook.com password | 1249 // from deleting it from the keystore just becaus the m.facebook.com password |
| 1258 // fuzzy-matches the www.facebook.com one.) | 1250 // fuzzy-matches the www.facebook.com one.) |
| 1259 | 1251 |
| 1260 // 1. Add a password for www.facebook.com | 1252 // 1. Add a password for www.facebook.com |
| 1261 PasswordFormData www_form_data = { | 1253 PasswordFormData www_form_data = { |
| 1262 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1254 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1263 "http://www.facebook.com/index.html", "login", | 1255 "http://www.facebook.com/index.html", "login", |
| 1264 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 | 1256 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 |
| 1265 }; | 1257 }; |
| 1266 scoped_ptr<PasswordForm> www_form(CreatePasswordFormFromData(www_form_data)); | 1258 scoped_ptr<PasswordForm> www_form = CreatePasswordFormFromData(www_form_data); |
| 1267 login_db()->AddLogin(*www_form); | 1259 login_db()->AddLogin(*www_form); |
| 1268 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); | 1260 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); |
| 1269 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1261 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 1270 owned_keychain_adapter.AddPassword(*www_form); | 1262 owned_keychain_adapter.AddPassword(*www_form); |
| 1271 | 1263 |
| 1272 // 2. Get a password for m.facebook.com. | 1264 // 2. Get a password for m.facebook.com. |
| 1273 PasswordForm m_form(*www_form); | 1265 PasswordForm m_form(*www_form); |
| 1274 m_form.signon_realm = "http://m.facebook.com"; | 1266 m_form.signon_realm = "http://m.facebook.com"; |
| 1275 m_form.origin = GURL("http://m.facebook.com/index.html"); | 1267 m_form.origin = GURL("http://m.facebook.com/index.html"); |
| 1276 | 1268 |
| 1277 MockPasswordStoreConsumer consumer; | 1269 MockPasswordStoreConsumer consumer; |
| 1278 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); | 1270 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); |
| 1279 consumer.WaitOnGetPasswordStoreResults(); | 1271 PasswordForm returned_form; |
|
vasilii
2015/02/05 19:23:26
Unused now, but to be used in your next PatchSet :
vabr (Chromium)
2015/02/06 14:16:05
Acknowledged. :)
| |
| 1280 EXPECT_EQ(1u, consumer.last_result.size()); | 1272 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) |
| 1273 .WillOnce(DoAll( | |
| 1274 Invoke(&consumer, &MockPasswordStoreConsumer::SaveACopyOfFirstForm), | |
| 1275 QuitUIMessageLoop())); | |
| 1276 base::MessageLoop::current()->Run(); | |
| 1281 | 1277 |
| 1282 // 3. Add the returned password for m.facebook.com. | 1278 // 3. Add the returned password for m.facebook.com. |
| 1283 login_db()->AddLogin(consumer.last_result[0]); | 1279 login_db()->AddLogin(consumer.first_form); |
| 1284 owned_keychain_adapter.AddPassword(m_form); | 1280 owned_keychain_adapter.AddPassword(m_form); |
| 1285 | 1281 |
| 1286 // 4. Remove both passwords. | 1282 // 4. Remove both passwords. |
| 1287 store_->RemoveLogin(*www_form); | 1283 store_->RemoveLogin(*www_form); |
| 1288 store_->RemoveLogin(m_form); | 1284 store_->RemoveLogin(m_form); |
| 1289 FinishAsyncProcessing(); | 1285 FinishAsyncProcessing(); |
| 1290 | 1286 |
| 1291 // No trace of www.facebook.com. | 1287 // No trace of www.facebook.com. |
| 1292 ScopedVector<autofill::PasswordForm> matching_items = | 1288 ScopedVector<autofill::PasswordForm> matching_items = |
| 1293 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm, | 1289 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1342 L"password", L"joe_user", L"sekrit", true, false, 0 }; | 1338 L"password", L"joe_user", L"sekrit", true, false, 0 }; |
| 1343 // The old form doesn't have elements names. | 1339 // The old form doesn't have elements names. |
| 1344 PasswordFormData www_form_data_facebook_old = { | 1340 PasswordFormData www_form_data_facebook_old = { |
| 1345 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1341 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1346 "http://www.facebook.com/index.html", "login", L"", L"", | 1342 "http://www.facebook.com/index.html", "login", L"", L"", |
| 1347 L"", L"joe_user", L"oldsekrit", true, false, 0 }; | 1343 L"", L"joe_user", L"oldsekrit", true, false, 0 }; |
| 1348 PasswordFormData www_form_data_other = { | 1344 PasswordFormData www_form_data_other = { |
| 1349 PasswordForm::SCHEME_HTML, "http://different.com/", | 1345 PasswordForm::SCHEME_HTML, "http://different.com/", |
| 1350 "http://different.com/index.html", "login", L"submit", L"username", | 1346 "http://different.com/index.html", "login", L"submit", L"username", |
| 1351 L"password", L"different_joe_user", L"sekrit", true, false, 0 }; | 1347 L"password", L"different_joe_user", L"sekrit", true, false, 0 }; |
| 1352 scoped_ptr<PasswordForm> form_facebook( | 1348 scoped_ptr<PasswordForm> form_facebook = |
| 1353 CreatePasswordFormFromData(www_form_data_facebook)); | 1349 CreatePasswordFormFromData(www_form_data_facebook); |
| 1354 scoped_ptr<PasswordForm> form_facebook_old( | 1350 scoped_ptr<PasswordForm> form_facebook_old = |
| 1355 CreatePasswordFormFromData(www_form_data_facebook_old)); | 1351 CreatePasswordFormFromData(www_form_data_facebook_old); |
| 1356 scoped_ptr<PasswordForm> form_other( | 1352 scoped_ptr<PasswordForm> form_other = |
| 1357 CreatePasswordFormFromData(www_form_data_other)); | 1353 CreatePasswordFormFromData(www_form_data_other); |
| 1358 base::Time now = base::Time::Now(); | 1354 base::Time now = base::Time::Now(); |
| 1359 // TODO(vasilii): remove the next line once crbug/374132 is fixed. | 1355 // TODO(vasilii): remove the next line once crbug/374132 is fixed. |
| 1360 now = base::Time::FromTimeT(now.ToTimeT()); | 1356 now = base::Time::FromTimeT(now.ToTimeT()); |
| 1361 base::Time next_day = now + base::TimeDelta::FromDays(1); | 1357 base::Time next_day = now + base::TimeDelta::FromDays(1); |
| 1362 if (check_created) { | 1358 if (check_created) { |
| 1363 form_facebook_old->date_created = now; | 1359 form_facebook_old->date_created = now; |
| 1364 form_facebook->date_created = next_day; | 1360 form_facebook->date_created = next_day; |
| 1365 form_other->date_created = next_day; | 1361 form_other->date_created = next_day; |
| 1366 } else { | 1362 } else { |
| 1367 form_facebook_old->date_synced = now; | 1363 form_facebook_old->date_synced = now; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1446 keychain()->AddTestItem(keychain_data); | 1442 keychain()->AddTestItem(keychain_data); |
| 1447 | 1443 |
| 1448 // Add a password through the adapter. It has the "Chrome" creator tag. | 1444 // Add a password through the adapter. It has the "Chrome" creator tag. |
| 1449 // However, it's not referenced by the password database. | 1445 // However, it's not referenced by the password database. |
| 1450 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); | 1446 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); |
| 1451 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1447 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
| 1452 PasswordFormData www_form_data1 = { | 1448 PasswordFormData www_form_data1 = { |
| 1453 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1449 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1454 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1450 "http://www.facebook.com/index.html", "login", L"username", L"password", |
| 1455 L"submit", L"joe_user", L"sekrit", true, false, 1 }; | 1451 L"submit", L"joe_user", L"sekrit", true, false, 1 }; |
| 1456 scoped_ptr<PasswordForm> www_form(CreatePasswordFormFromData(www_form_data1)); | 1452 scoped_ptr<PasswordForm> www_form = |
| 1453 CreatePasswordFormFromData(www_form_data1); | |
| 1457 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); | 1454 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); |
| 1458 | 1455 |
| 1459 // Add a password from the current profile. | 1456 // Add a password from the current profile. |
| 1460 PasswordFormData www_form_data2 = { | 1457 PasswordFormData www_form_data2 = { |
| 1461 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1458 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1462 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1459 "http://www.facebook.com/index.html", "login", L"username", L"password", |
| 1463 L"submit", L"not_joe_user", L"12345", true, false, 1 }; | 1460 L"submit", L"not_joe_user", L"12345", true, false, 1 }; |
| 1464 www_form.reset(CreatePasswordFormFromData(www_form_data2)); | 1461 www_form = CreatePasswordFormFromData(www_form_data2); |
| 1465 store_->AddLogin(*www_form); | 1462 store_->AddLogin(*www_form); |
| 1466 FinishAsyncProcessing(); | 1463 FinishAsyncProcessing(); |
| 1467 | 1464 |
| 1468 ScopedVector<PasswordForm> matching_items; | 1465 ScopedVector<PasswordForm> matching_items; |
| 1469 login_db()->GetLogins(*www_form, &matching_items); | 1466 login_db()->GetLogins(*www_form, &matching_items); |
| 1470 EXPECT_EQ(1u, matching_items.size()); | 1467 EXPECT_EQ(1u, matching_items.size()); |
| 1471 matching_items.clear(); | 1468 matching_items.clear(); |
| 1472 | 1469 |
| 1473 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time()); | 1470 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time()); |
| 1474 FinishAsyncProcessing(); | 1471 FinishAsyncProcessing(); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1499 ClosePasswordStore(); | 1496 ClosePasswordStore(); |
| 1500 | 1497 |
| 1501 base::WaitableEvent event(false, false); | 1498 base::WaitableEvent event(false, false); |
| 1502 CreateAndInitPasswordStore(make_scoped_ptr<password_manager::LoginDatabase>( | 1499 CreateAndInitPasswordStore(make_scoped_ptr<password_manager::LoginDatabase>( |
| 1503 new SlowToInitLoginDatabase(test_login_db_file_path(), &event))); | 1500 new SlowToInitLoginDatabase(test_login_db_file_path(), &event))); |
| 1504 | 1501 |
| 1505 PasswordFormData www_form_data = { | 1502 PasswordFormData www_form_data = { |
| 1506 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1503 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1507 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1504 "http://www.facebook.com/index.html", "login", L"username", L"password", |
| 1508 L"submit", L"not_joe_user", L"12345", true, false, 1}; | 1505 L"submit", L"not_joe_user", L"12345", true, false, 1}; |
| 1509 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(www_form_data)); | 1506 scoped_ptr<PasswordForm> form = CreatePasswordFormFromData(www_form_data); |
| 1510 store()->AddLogin(*form); | 1507 store()->AddLogin(*form); |
| 1511 | 1508 |
| 1512 MockPasswordStoreConsumer mock_consumer; | 1509 MockPasswordStoreConsumer mock_consumer; |
| 1513 store()->GetLogins(*form, PasswordStore::ALLOW_PROMPT, &mock_consumer); | 1510 store()->GetLogins(*form, PasswordStore::ALLOW_PROMPT, &mock_consumer); |
| 1514 | 1511 |
| 1515 // Now the read/write tasks are scheduled, let the DB initialization proceed. | 1512 // Now the read/write tasks are scheduled, let the DB initialization proceed. |
| 1516 event.Signal(); | 1513 event.Signal(); |
| 1517 | 1514 |
| 1518 mock_consumer.WaitOnGetPasswordStoreResults(); | 1515 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) |
| 1519 EXPECT_EQ(1u, mock_consumer.last_result.size()); | 1516 .WillOnce(QuitUIMessageLoop()); |
| 1517 base::MessageLoop::current()->Run(); | |
| 1520 EXPECT_TRUE(login_db()); | 1518 EXPECT_TRUE(login_db()); |
| 1521 } | 1519 } |
| 1522 | 1520 |
| 1523 // Verify that operations on a PasswordStore with a bad database cause no | 1521 // Verify that operations on a PasswordStore with a bad database cause no |
| 1524 // explosions, but fail without side effect, return no data and trigger no | 1522 // explosions, but fail without side effect, return no data and trigger no |
| 1525 // notifications. | 1523 // notifications. |
| 1526 TEST_F(PasswordStoreMacTest, OperationsOnABadDatabaseSilentlyFail) { | 1524 TEST_F(PasswordStoreMacTest, OperationsOnABadDatabaseSilentlyFail) { |
| 1527 ClosePasswordStore(); | 1525 ClosePasswordStore(); |
| 1528 CreateAndInitPasswordStore( | 1526 CreateAndInitPasswordStore( |
| 1529 make_scoped_ptr<password_manager::LoginDatabase>(new BadLoginDatabase)); | 1527 make_scoped_ptr<password_manager::LoginDatabase>(new BadLoginDatabase)); |
| 1530 FinishAsyncProcessing(); | 1528 FinishAsyncProcessing(); |
| 1531 EXPECT_FALSE(login_db()); | 1529 EXPECT_FALSE(login_db()); |
| 1532 | 1530 |
| 1533 testing::StrictMock<MockPasswordStoreObserver> mock_observer; | 1531 testing::StrictMock<MockPasswordStoreObserver> mock_observer; |
| 1534 store()->AddObserver(&mock_observer); | 1532 store()->AddObserver(&mock_observer); |
| 1535 | 1533 |
| 1536 // Add a new autofillable login + a blacklisted login. | 1534 // Add a new autofillable login + a blacklisted login. |
| 1537 PasswordFormData www_form_data = { | 1535 PasswordFormData www_form_data = { |
| 1538 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1536 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1539 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1537 "http://www.facebook.com/index.html", "login", L"username", L"password", |
| 1540 L"submit", L"not_joe_user", L"12345", true, false, 1}; | 1538 L"submit", L"not_joe_user", L"12345", true, false, 1}; |
| 1541 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(www_form_data)); | 1539 scoped_ptr<PasswordForm> form = CreatePasswordFormFromData(www_form_data); |
| 1542 scoped_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form)); | 1540 scoped_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form)); |
| 1543 blacklisted_form->signon_realm = "http://foo.example.com"; | 1541 blacklisted_form->signon_realm = "http://foo.example.com"; |
| 1544 blacklisted_form->origin = GURL("http://foo.example.com/origin"); | 1542 blacklisted_form->origin = GURL("http://foo.example.com/origin"); |
| 1545 blacklisted_form->action = GURL("http://foo.example.com/action"); | 1543 blacklisted_form->action = GURL("http://foo.example.com/action"); |
| 1546 blacklisted_form->blacklisted_by_user = true; | 1544 blacklisted_form->blacklisted_by_user = true; |
| 1547 store()->AddLogin(*form); | 1545 store()->AddLogin(*form); |
| 1548 store()->AddLogin(*blacklisted_form); | 1546 store()->AddLogin(*blacklisted_form); |
| 1549 FinishAsyncProcessing(); | 1547 FinishAsyncProcessing(); |
| 1550 | 1548 |
| 1551 // Get all logins; autofillable logins; blacklisted logins. | 1549 // Get all logins; autofillable logins; blacklisted logins. |
| 1552 MockPasswordStoreConsumer mock_consumer; | 1550 MockPasswordStoreConsumer mock_consumer; |
| 1553 store()->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &mock_consumer); | 1551 store()->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &mock_consumer); |
| 1554 mock_consumer.WaitOnGetPasswordStoreResults(); | 1552 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(ElementsAre())) |
|
vasilii
2015/02/05 19:23:26
IsEmpty()
vabr (Chromium)
2015/02/06 14:16:04
Done.
| |
| 1555 EXPECT_TRUE(mock_consumer.last_result.empty()); | 1553 .WillOnce(QuitUIMessageLoop()); |
| 1554 base::MessageLoop::current()->Run(); | |
| 1555 | |
| 1556 store()->GetAutofillableLogins(&mock_consumer); | 1556 store()->GetAutofillableLogins(&mock_consumer); |
| 1557 mock_consumer.WaitOnGetPasswordStoreResults(); | 1557 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(ElementsAre())) |
| 1558 EXPECT_TRUE(mock_consumer.last_result.empty()); | 1558 .WillOnce(QuitUIMessageLoop()); |
| 1559 base::MessageLoop::current()->Run(); | |
| 1560 | |
| 1559 store()->GetBlacklistLogins(&mock_consumer); | 1561 store()->GetBlacklistLogins(&mock_consumer); |
| 1560 mock_consumer.WaitOnGetPasswordStoreResults(); | 1562 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(ElementsAre())) |
| 1561 EXPECT_TRUE(mock_consumer.last_result.empty()); | 1563 .WillOnce(QuitUIMessageLoop()); |
|
vasilii
2015/02/05 19:23:26
This is repeated many times here. Sounds like a ca
vabr (Chromium)
2015/02/06 14:16:04
Done.
| |
| 1564 base::MessageLoop::current()->Run(); | |
| 1562 | 1565 |
| 1563 // Report metrics. | 1566 // Report metrics. |
| 1564 store()->ReportMetrics("Test Username", true); | 1567 store()->ReportMetrics("Test Username", true); |
| 1565 FinishAsyncProcessing(); | 1568 FinishAsyncProcessing(); |
| 1566 | 1569 |
| 1567 // Change the login. | 1570 // Change the login. |
| 1568 form->password_value = base::ASCIIToUTF16("a different password"); | 1571 form->password_value = base::ASCIIToUTF16("a different password"); |
| 1569 store()->UpdateLogin(*form); | 1572 store()->UpdateLogin(*form); |
| 1570 FinishAsyncProcessing(); | 1573 FinishAsyncProcessing(); |
| 1571 | 1574 |
| 1572 // Delete one login; a range of logins. | 1575 // Delete one login; a range of logins. |
| 1573 store()->RemoveLogin(*form); | 1576 store()->RemoveLogin(*form); |
| 1574 store()->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max()); | 1577 store()->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max()); |
| 1575 store()->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max()); | 1578 store()->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max()); |
| 1576 FinishAsyncProcessing(); | 1579 FinishAsyncProcessing(); |
| 1577 | 1580 |
| 1578 // Verify no notifications are fired during shutdown either. | 1581 // Verify no notifications are fired during shutdown either. |
| 1579 ClosePasswordStore(); | 1582 ClosePasswordStore(); |
| 1580 } | 1583 } |
| OLD | NEW |