| 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 <stdarg.h> | 5 #include <stdarg.h> |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/prefs/pref_service.h" | 8 #include "base/prefs/pref_service.h" |
| 9 #include "base/stl_util.h" | |
| 10 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 12 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 15 #include "chrome/browser/password_manager/native_backend_gnome_x.h" | 14 #include "chrome/browser/password_manager/native_backend_gnome_x.h" |
| 16 #include "chrome/test/base/testing_profile.h" | 15 #include "chrome/test/base/testing_profile.h" |
| 17 #include "components/autofill/core/common/password_form.h" | 16 #include "components/autofill/core/common/password_form.h" |
| 18 #include "components/password_manager/core/browser/psl_matching_helper.h" | 17 #include "components/password_manager/core/browser/psl_matching_helper.h" |
| 19 #include "components/password_manager/core/common/password_manager_pref_names.h" | 18 #include "components/password_manager/core/common/password_manager_pref_names.h" |
| (...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 PasswordForm target_form; | 494 PasswordForm target_form; |
| 496 target_form.origin = url; | 495 target_form.origin = url; |
| 497 target_form.signon_realm = url.spec(); | 496 target_form.signon_realm = url.spec(); |
| 498 if (scheme != PasswordForm::SCHEME_HTML) { | 497 if (scheme != PasswordForm::SCHEME_HTML) { |
| 499 // For non-HTML forms, the realm used for authentication | 498 // For non-HTML forms, the realm used for authentication |
| 500 // (http://tools.ietf.org/html/rfc1945#section-10.2) is appended to the | 499 // (http://tools.ietf.org/html/rfc1945#section-10.2) is appended to the |
| 501 // signon_realm. Just use a default value for now. | 500 // signon_realm. Just use a default value for now. |
| 502 target_form.signon_realm.append("Realm"); | 501 target_form.signon_realm.append("Realm"); |
| 503 target_form.scheme = scheme; | 502 target_form.scheme = scheme; |
| 504 } | 503 } |
| 505 std::vector<PasswordForm*> form_list; | 504 ScopedVector<autofill::PasswordForm> form_list; |
| 506 BrowserThread::PostTask( | 505 BrowserThread::PostTask( |
| 507 BrowserThread::DB, | 506 BrowserThread::DB, |
| 508 FROM_HERE, | 507 FROM_HERE, |
| 509 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), | 508 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), |
| 510 base::Unretained(&backend), | 509 base::Unretained(&backend), |
| 511 target_form, | 510 target_form, |
| 512 &form_list)); | 511 &form_list)); |
| 513 | 512 |
| 514 RunBothThreads(); | 513 RunBothThreads(); |
| 515 | 514 |
| 516 EXPECT_EQ(1u, mock_keyring_items.size()); | 515 EXPECT_EQ(1u, mock_keyring_items.size()); |
| 517 if (mock_keyring_items.size() > 0) | 516 if (mock_keyring_items.size() > 0) |
| 518 CheckMockKeyringItem(&mock_keyring_items[0], credentials, "chrome-321"); | 517 CheckMockKeyringItem(&mock_keyring_items[0], credentials, "chrome-321"); |
| 519 mock_keyring_items.clear(); | 518 mock_keyring_items.clear(); |
| 520 | 519 |
| 521 if (form_list.empty()) | 520 if (form_list.empty()) |
| 522 return false; | 521 return false; |
| 523 EXPECT_EQ(1u, form_list.size()); | 522 EXPECT_EQ(1u, form_list.size()); |
| 524 if (result) | 523 if (result) |
| 525 *result = *form_list[0]; | 524 *result = *form_list[0]; |
| 526 STLDeleteElements(&form_list); | |
| 527 return true; | 525 return true; |
| 528 } | 526 } |
| 529 | 527 |
| 530 // Test that updating does not use PSL matching: Add a www.facebook.com | 528 // Test that updating does not use PSL matching: Add a www.facebook.com |
| 531 // password, then use PSL matching to get a copy of it for m.facebook.com, and | 529 // password, then use PSL matching to get a copy of it for m.facebook.com, and |
| 532 // add that copy as well. Now update the www.facebook.com password -- the | 530 // add that copy as well. Now update the www.facebook.com password -- the |
| 533 // m.facebook.com password should not get updated. Depending on the argument, | 531 // m.facebook.com password should not get updated. Depending on the argument, |
| 534 // the credential update is done via UpdateLogin or AddLogin. | 532 // the credential update is done via UpdateLogin or AddLogin. |
| 535 void CheckPSLUpdate(UpdateType update_type) { | 533 void CheckPSLUpdate(UpdateType update_type) { |
| 536 NativeBackendGnome backend(321); | 534 NativeBackendGnome backend(321); |
| 537 backend.Init(); | 535 backend.Init(); |
| 538 | 536 |
| 539 // Add |form_facebook_| to saved logins. | 537 // Add |form_facebook_| to saved logins. |
| 540 BrowserThread::PostTask( | 538 BrowserThread::PostTask( |
| 541 BrowserThread::DB, | 539 BrowserThread::DB, |
| 542 FROM_HERE, | 540 FROM_HERE, |
| 543 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), | 541 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), |
| 544 base::Unretained(&backend), | 542 base::Unretained(&backend), |
| 545 form_facebook_)); | 543 form_facebook_)); |
| 546 | 544 |
| 547 // Get the PSL-matched copy of the saved login for m.facebook. | 545 // Get the PSL-matched copy of the saved login for m.facebook. |
| 548 const GURL kMobileURL("http://m.facebook.com/"); | 546 const GURL kMobileURL("http://m.facebook.com/"); |
| 549 PasswordForm m_facebook_lookup; | 547 PasswordForm m_facebook_lookup; |
| 550 m_facebook_lookup.origin = kMobileURL; | 548 m_facebook_lookup.origin = kMobileURL; |
| 551 m_facebook_lookup.signon_realm = kMobileURL.spec(); | 549 m_facebook_lookup.signon_realm = kMobileURL.spec(); |
| 552 std::vector<PasswordForm*> form_list; | 550 ScopedVector<autofill::PasswordForm> form_list; |
| 553 BrowserThread::PostTask( | 551 BrowserThread::PostTask( |
| 554 BrowserThread::DB, | 552 BrowserThread::DB, |
| 555 FROM_HERE, | 553 FROM_HERE, |
| 556 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), | 554 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), |
| 557 base::Unretained(&backend), | 555 base::Unretained(&backend), |
| 558 m_facebook_lookup, | 556 m_facebook_lookup, |
| 559 &form_list)); | 557 &form_list)); |
| 560 RunBothThreads(); | 558 RunBothThreads(); |
| 561 EXPECT_EQ(1u, mock_keyring_items.size()); | 559 EXPECT_EQ(1u, mock_keyring_items.size()); |
| 562 EXPECT_EQ(1u, form_list.size()); | 560 EXPECT_EQ(1u, form_list.size()); |
| 563 PasswordForm m_facebook = *form_list[0]; | 561 PasswordForm m_facebook = *form_list[0]; |
| 564 STLDeleteElements(&form_list); | 562 form_list.clear(); |
| 565 EXPECT_EQ(kMobileURL, m_facebook.origin); | 563 EXPECT_EQ(kMobileURL, m_facebook.origin); |
| 566 EXPECT_EQ(kMobileURL.spec(), m_facebook.signon_realm); | 564 EXPECT_EQ(kMobileURL.spec(), m_facebook.signon_realm); |
| 567 | 565 |
| 568 // Add the PSL-matched copy to saved logins. | 566 // Add the PSL-matched copy to saved logins. |
| 569 BrowserThread::PostTask( | 567 BrowserThread::PostTask( |
| 570 BrowserThread::DB, | 568 BrowserThread::DB, |
| 571 FROM_HERE, | 569 FROM_HERE, |
| 572 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), | 570 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), |
| 573 base::Unretained(&backend), | 571 base::Unretained(&backend), |
| 574 m_facebook)); | 572 m_facebook)); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 &form_list)); | 612 &form_list)); |
| 615 RunBothThreads(); | 613 RunBothThreads(); |
| 616 // There should be two results -- the exact one, and the PSL-matched one. | 614 // There should be two results -- the exact one, and the PSL-matched one. |
| 617 EXPECT_EQ(2u, form_list.size()); | 615 EXPECT_EQ(2u, form_list.size()); |
| 618 size_t index_non_psl = 0; | 616 size_t index_non_psl = 0; |
| 619 if (!form_list[index_non_psl]->original_signon_realm.empty()) | 617 if (!form_list[index_non_psl]->original_signon_realm.empty()) |
| 620 index_non_psl = 1; | 618 index_non_psl = 1; |
| 621 EXPECT_EQ(kMobileURL, form_list[index_non_psl]->origin); | 619 EXPECT_EQ(kMobileURL, form_list[index_non_psl]->origin); |
| 622 EXPECT_EQ(kMobileURL.spec(), form_list[index_non_psl]->signon_realm); | 620 EXPECT_EQ(kMobileURL.spec(), form_list[index_non_psl]->signon_realm); |
| 623 EXPECT_EQ(kOldPassword, form_list[index_non_psl]->password_value); | 621 EXPECT_EQ(kOldPassword, form_list[index_non_psl]->password_value); |
| 624 STLDeleteElements(&form_list); | 622 form_list.clear(); |
| 625 | 623 |
| 626 // Check that www.facebook.com login was modified by the update. | 624 // Check that www.facebook.com login was modified by the update. |
| 627 BrowserThread::PostTask( | 625 BrowserThread::PostTask( |
| 628 BrowserThread::DB, | 626 BrowserThread::DB, |
| 629 FROM_HERE, | 627 FROM_HERE, |
| 630 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), | 628 base::Bind(base::IgnoreResult(&NativeBackendGnome::GetLogins), |
| 631 base::Unretained(&backend), | 629 base::Unretained(&backend), |
| 632 form_facebook_, | 630 form_facebook_, |
| 633 &form_list)); | 631 &form_list)); |
| 634 RunBothThreads(); | 632 RunBothThreads(); |
| 635 // There should be two results -- the exact one, and the PSL-matched one. | 633 // There should be two results -- the exact one, and the PSL-matched one. |
| 636 EXPECT_EQ(2u, form_list.size()); | 634 EXPECT_EQ(2u, form_list.size()); |
| 637 index_non_psl = 0; | 635 index_non_psl = 0; |
| 638 if (!form_list[index_non_psl]->original_signon_realm.empty()) | 636 if (!form_list[index_non_psl]->original_signon_realm.empty()) |
| 639 index_non_psl = 1; | 637 index_non_psl = 1; |
| 640 EXPECT_EQ(form_facebook_.origin, form_list[index_non_psl]->origin); | 638 EXPECT_EQ(form_facebook_.origin, form_list[index_non_psl]->origin); |
| 641 EXPECT_EQ(form_facebook_.signon_realm, | 639 EXPECT_EQ(form_facebook_.signon_realm, |
| 642 form_list[index_non_psl]->signon_realm); | 640 form_list[index_non_psl]->signon_realm); |
| 643 EXPECT_EQ(kNewPassword, form_list[index_non_psl]->password_value); | 641 EXPECT_EQ(kNewPassword, form_list[index_non_psl]->password_value); |
| 644 STLDeleteElements(&form_list); | |
| 645 } | 642 } |
| 646 | 643 |
| 647 void CheckMatchingWithScheme(const PasswordForm::Scheme& scheme) { | 644 void CheckMatchingWithScheme(const PasswordForm::Scheme& scheme) { |
| 648 other_auth_.scheme = scheme; | 645 other_auth_.scheme = scheme; |
| 649 | 646 |
| 650 // Don't match a non-HTML form with an HTML form. | 647 // Don't match a non-HTML form with an HTML form. |
| 651 EXPECT_FALSE(CheckCredentialAvailability( | 648 EXPECT_FALSE(CheckCredentialAvailability( |
| 652 other_auth_, GURL("http://www.example.com"), | 649 other_auth_, GURL("http://www.example.com"), |
| 653 PasswordForm::SCHEME_HTML, NULL)); | 650 PasswordForm::SCHEME_HTML, NULL)); |
| 654 // Don't match an HTML form with non-HTML auth form. | 651 // Don't match an HTML form with non-HTML auth form. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 | 765 |
| 769 TEST_F(NativeBackendGnomeTest, BasicListLogins) { | 766 TEST_F(NativeBackendGnomeTest, BasicListLogins) { |
| 770 NativeBackendGnome backend(42); | 767 NativeBackendGnome backend(42); |
| 771 backend.Init(); | 768 backend.Init(); |
| 772 | 769 |
| 773 BrowserThread::PostTask( | 770 BrowserThread::PostTask( |
| 774 BrowserThread::DB, FROM_HERE, | 771 BrowserThread::DB, FROM_HERE, |
| 775 base::Bind(base::IgnoreResult( &NativeBackendGnome::AddLogin), | 772 base::Bind(base::IgnoreResult( &NativeBackendGnome::AddLogin), |
| 776 base::Unretained(&backend), form_google_)); | 773 base::Unretained(&backend), form_google_)); |
| 777 | 774 |
| 778 std::vector<PasswordForm*> form_list; | 775 ScopedVector<autofill::PasswordForm> form_list; |
| 779 BrowserThread::PostTask( | 776 BrowserThread::PostTask( |
| 780 BrowserThread::DB, FROM_HERE, | 777 BrowserThread::DB, FROM_HERE, |
| 781 base::Bind( | 778 base::Bind( |
| 782 base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins), | 779 base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins), |
| 783 base::Unretained(&backend), &form_list)); | 780 base::Unretained(&backend), &form_list)); |
| 784 | 781 |
| 785 RunBothThreads(); | 782 RunBothThreads(); |
| 786 | 783 |
| 787 // Quick check that we got something back. | 784 // Quick check that we got something back. |
| 788 EXPECT_EQ(1u, form_list.size()); | 785 EXPECT_EQ(1u, form_list.size()); |
| 789 STLDeleteElements(&form_list); | |
| 790 | 786 |
| 791 EXPECT_EQ(1u, mock_keyring_items.size()); | 787 EXPECT_EQ(1u, mock_keyring_items.size()); |
| 792 if (mock_keyring_items.size() > 0) | 788 if (mock_keyring_items.size() > 0) |
| 793 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); | 789 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); |
| 794 } | 790 } |
| 795 | 791 |
| 796 // Save a password for www.facebook.com and see it suggested for m.facebook.com. | 792 // Save a password for www.facebook.com and see it suggested for m.facebook.com. |
| 797 TEST_F(NativeBackendGnomeTest, PSLMatchingPositive) { | 793 TEST_F(NativeBackendGnomeTest, PSLMatchingPositive) { |
| 798 PasswordForm result; | 794 PasswordForm result; |
| 799 const GURL kMobileURL("http://m.facebook.com/"); | 795 const GURL kMobileURL("http://m.facebook.com/"); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 if (mock_keyring_items.size() > 0) | 941 if (mock_keyring_items.size() > 0) |
| 946 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); | 942 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); |
| 947 | 943 |
| 948 // Attempt to remove a login that doesn't exist. | 944 // Attempt to remove a login that doesn't exist. |
| 949 BrowserThread::PostTask( | 945 BrowserThread::PostTask( |
| 950 BrowserThread::DB, FROM_HERE, | 946 BrowserThread::DB, FROM_HERE, |
| 951 base::Bind(base::IgnoreResult(&NativeBackendGnome::RemoveLogin), | 947 base::Bind(base::IgnoreResult(&NativeBackendGnome::RemoveLogin), |
| 952 base::Unretained(&backend), form_isc_)); | 948 base::Unretained(&backend), form_isc_)); |
| 953 | 949 |
| 954 // Make sure we can still get the first form back. | 950 // Make sure we can still get the first form back. |
| 955 std::vector<PasswordForm*> form_list; | 951 ScopedVector<autofill::PasswordForm> form_list; |
| 956 BrowserThread::PostTask( | 952 BrowserThread::PostTask( |
| 957 BrowserThread::DB, FROM_HERE, | 953 BrowserThread::DB, FROM_HERE, |
| 958 base::Bind( | 954 base::Bind( |
| 959 base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins), | 955 base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins), |
| 960 base::Unretained(&backend), &form_list)); | 956 base::Unretained(&backend), &form_list)); |
| 961 | 957 |
| 962 RunBothThreads(); | 958 RunBothThreads(); |
| 963 | 959 |
| 964 // Quick check that we got something back. | 960 // Quick check that we got something back. |
| 965 EXPECT_EQ(1u, form_list.size()); | 961 EXPECT_EQ(1u, form_list.size()); |
| 966 STLDeleteElements(&form_list); | |
| 967 | 962 |
| 968 EXPECT_EQ(1u, mock_keyring_items.size()); | 963 EXPECT_EQ(1u, mock_keyring_items.size()); |
| 969 if (mock_keyring_items.size() > 0) | 964 if (mock_keyring_items.size() > 0) |
| 970 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); | 965 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); |
| 971 } | 966 } |
| 972 | 967 |
| 973 TEST_F(NativeBackendGnomeTest, UpdateNonexistentLogin) { | 968 TEST_F(NativeBackendGnomeTest, UpdateNonexistentLogin) { |
| 974 NativeBackendGnome backend(42); | 969 NativeBackendGnome backend(42); |
| 975 backend.Init(); | 970 backend.Init(); |
| 976 | 971 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 TEST_F(NativeBackendGnomeTest, ListLoginsAppends) { | 1034 TEST_F(NativeBackendGnomeTest, ListLoginsAppends) { |
| 1040 NativeBackendGnome backend(42); | 1035 NativeBackendGnome backend(42); |
| 1041 backend.Init(); | 1036 backend.Init(); |
| 1042 | 1037 |
| 1043 BrowserThread::PostTask( | 1038 BrowserThread::PostTask( |
| 1044 BrowserThread::DB, FROM_HERE, | 1039 BrowserThread::DB, FROM_HERE, |
| 1045 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), | 1040 base::Bind(base::IgnoreResult(&NativeBackendGnome::AddLogin), |
| 1046 base::Unretained(&backend), form_google_)); | 1041 base::Unretained(&backend), form_google_)); |
| 1047 | 1042 |
| 1048 // Send the same request twice with the same list both times. | 1043 // Send the same request twice with the same list both times. |
| 1049 std::vector<PasswordForm*> form_list; | 1044 ScopedVector<autofill::PasswordForm> form_list; |
| 1050 BrowserThread::PostTask( | 1045 BrowserThread::PostTask( |
| 1051 BrowserThread::DB, FROM_HERE, | 1046 BrowserThread::DB, FROM_HERE, |
| 1052 base::Bind( | 1047 base::Bind( |
| 1053 base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins), | 1048 base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins), |
| 1054 base::Unretained(&backend), &form_list)); | 1049 base::Unretained(&backend), &form_list)); |
| 1055 BrowserThread::PostTask( | 1050 BrowserThread::PostTask( |
| 1056 BrowserThread::DB, FROM_HERE, | 1051 BrowserThread::DB, FROM_HERE, |
| 1057 base::Bind( | 1052 base::Bind( |
| 1058 base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins), | 1053 base::IgnoreResult(&NativeBackendGnome::GetAutofillableLogins), |
| 1059 base::Unretained(&backend), &form_list)); | 1054 base::Unretained(&backend), &form_list)); |
| 1060 | 1055 |
| 1061 RunBothThreads(); | 1056 RunBothThreads(); |
| 1062 | 1057 |
| 1063 // Quick check that we got two results back. | 1058 // Quick check that we got two results back. |
| 1064 EXPECT_EQ(2u, form_list.size()); | 1059 EXPECT_EQ(2u, form_list.size()); |
| 1065 STLDeleteElements(&form_list); | |
| 1066 | 1060 |
| 1067 EXPECT_EQ(1u, mock_keyring_items.size()); | 1061 EXPECT_EQ(1u, mock_keyring_items.size()); |
| 1068 if (mock_keyring_items.size() > 0) | 1062 if (mock_keyring_items.size() > 0) |
| 1069 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); | 1063 CheckMockKeyringItem(&mock_keyring_items[0], form_google_, "chrome-42"); |
| 1070 } | 1064 } |
| 1071 | 1065 |
| 1072 TEST_F(NativeBackendGnomeTest, RemoveLoginsCreatedBetween) { | 1066 TEST_F(NativeBackendGnomeTest, RemoveLoginsCreatedBetween) { |
| 1073 CheckRemoveLoginsBetween(CREATED); | 1067 CheckRemoveLoginsBetween(CREATED); |
| 1074 } | 1068 } |
| 1075 | 1069 |
| 1076 TEST_F(NativeBackendGnomeTest, RemoveLoginsSyncedBetween) { | 1070 TEST_F(NativeBackendGnomeTest, RemoveLoginsSyncedBetween) { |
| 1077 CheckRemoveLoginsBetween(SYNCED); | 1071 CheckRemoveLoginsBetween(SYNCED); |
| 1078 } | 1072 } |
| 1079 | 1073 |
| 1080 // TODO(mdm): add more basic tests here at some point. | 1074 // TODO(mdm): add more basic tests here at some point. |
| OLD | NEW |