| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/password_manager/core/browser/login_database.h" | 5 #include "components/password_manager/core/browser/login_database.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
| 9 #include "base/files/scoped_temp_dir.h" | 9 #include "base/files/scoped_temp_dir.h" |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/memory/scoped_vector.h" | 11 #include "base/memory/scoped_vector.h" |
| 12 #include "base/path_service.h" | 12 #include "base/path_service.h" |
| 13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 16 #include "base/test/histogram_tester.h" | 16 #include "base/test/histogram_tester.h" |
| 17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 18 #include "components/autofill/core/common/password_form.h" | 18 #include "components/autofill/core/common/password_form.h" |
| 19 #include "components/password_manager/core/browser/psl_matching_helper.h" | 19 #include "components/password_manager/core/browser/psl_matching_helper.h" |
| 20 #include "sql/connection.h" | 20 #include "sql/connection.h" |
| 21 #include "sql/statement.h" | 21 #include "sql/statement.h" |
| 22 #include "sql/test/test_helpers.h" | 22 #include "sql/test/test_helpers.h" |
| 23 #include "testing/gmock/include/gmock/gmock.h" | 23 #include "testing/gmock/include/gmock/gmock.h" |
| 24 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
| 25 | 25 |
| 26 #if defined(OS_MACOSX) |
| 27 #include "components/os_crypt/os_crypt.h" |
| 28 #endif |
| 29 |
| 26 using autofill::PasswordForm; | 30 using autofill::PasswordForm; |
| 27 using base::ASCIIToUTF16; | 31 using base::ASCIIToUTF16; |
| 28 using ::testing::Eq; | 32 using ::testing::Eq; |
| 29 | 33 |
| 30 namespace password_manager { | 34 namespace password_manager { |
| 31 namespace { | 35 namespace { |
| 32 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) { | 36 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) { |
| 33 return PasswordStoreChangeList( | 37 return PasswordStoreChangeList( |
| 34 1, PasswordStoreChange(PasswordStoreChange::ADD, form)); | 38 1, PasswordStoreChange(PasswordStoreChange::ADD, form)); |
| 35 } | 39 } |
| 36 | 40 |
| 37 PasswordStoreChangeList UpdateChangeForForm(const PasswordForm& form) { | 41 PasswordStoreChangeList UpdateChangeForForm(const PasswordForm& form) { |
| 38 return PasswordStoreChangeList( | 42 return PasswordStoreChangeList( |
| 39 1, PasswordStoreChange(PasswordStoreChange::UPDATE, form)); | 43 1, PasswordStoreChange(PasswordStoreChange::UPDATE, form)); |
| 40 } | 44 } |
| 41 | 45 |
| 42 void FormsAreEqual(const PasswordForm& expected, const PasswordForm& actual) { | |
| 43 PasswordForm expected_copy(expected); | |
| 44 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
| 45 // On the Mac we should never be storing passwords in the database. | |
| 46 expected_copy.password_value = ASCIIToUTF16(""); | |
| 47 #endif | |
| 48 EXPECT_EQ(expected_copy, actual); | |
| 49 } | |
| 50 | |
| 51 void GenerateExamplePasswordForm(PasswordForm* form) { | 46 void GenerateExamplePasswordForm(PasswordForm* form) { |
| 52 form->origin = GURL("http://accounts.google.com/LoginAuth"); | 47 form->origin = GURL("http://accounts.google.com/LoginAuth"); |
| 53 form->action = GURL("http://accounts.google.com/Login"); | 48 form->action = GURL("http://accounts.google.com/Login"); |
| 54 form->username_element = ASCIIToUTF16("Email"); | 49 form->username_element = ASCIIToUTF16("Email"); |
| 55 form->username_value = ASCIIToUTF16("test@gmail.com"); | 50 form->username_value = ASCIIToUTF16("test@gmail.com"); |
| 56 form->password_element = ASCIIToUTF16("Passwd"); | 51 form->password_element = ASCIIToUTF16("Passwd"); |
| 57 form->password_value = ASCIIToUTF16("test"); | 52 form->password_value = ASCIIToUTF16("test"); |
| 58 form->submit_element = ASCIIToUTF16("signIn"); | 53 form->submit_element = ASCIIToUTF16("signIn"); |
| 59 form->signon_realm = "http://www.google.com/"; | 54 form->signon_realm = "http://www.google.com/"; |
| 60 form->ssl_valid = false; | 55 form->ssl_valid = false; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 73 | 68 |
| 74 // Serialization routines for vectors implemented in login_database.cc. | 69 // Serialization routines for vectors implemented in login_database.cc. |
| 75 base::Pickle SerializeVector(const std::vector<base::string16>& vec); | 70 base::Pickle SerializeVector(const std::vector<base::string16>& vec); |
| 76 std::vector<base::string16> DeserializeVector(const base::Pickle& pickle); | 71 std::vector<base::string16> DeserializeVector(const base::Pickle& pickle); |
| 77 | 72 |
| 78 class LoginDatabaseTest : public testing::Test { | 73 class LoginDatabaseTest : public testing::Test { |
| 79 protected: | 74 protected: |
| 80 void SetUp() override { | 75 void SetUp() override { |
| 81 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 76 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 82 file_ = temp_dir_.path().AppendASCII("TestMetadataStoreMacDatabase"); | 77 file_ = temp_dir_.path().AppendASCII("TestMetadataStoreMacDatabase"); |
| 78 #if defined(OS_MACOSX) |
| 79 OSCrypt::UseMockKeychain(true); |
| 80 #endif // defined(OS_MACOSX) |
| 83 | 81 |
| 84 db_.reset(new LoginDatabase(file_)); | 82 db_.reset(new LoginDatabase(file_)); |
| 85 ASSERT_TRUE(db_->Init()); | 83 ASSERT_TRUE(db_->Init()); |
| 86 } | 84 } |
| 87 | 85 |
| 88 LoginDatabase& db() { return *db_; } | 86 LoginDatabase& db() { return *db_; } |
| 89 | 87 |
| 90 void TestNonHTMLFormPSLMatching(const PasswordForm::Scheme& scheme) { | 88 void TestNonHTMLFormPSLMatching(const PasswordForm::Scheme& scheme) { |
| 91 ScopedVector<autofill::PasswordForm> result; | 89 ScopedVector<autofill::PasswordForm> result; |
| 92 | 90 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 | 174 |
| 177 // Example password form. | 175 // Example password form. |
| 178 PasswordForm form; | 176 PasswordForm form; |
| 179 GenerateExamplePasswordForm(&form); | 177 GenerateExamplePasswordForm(&form); |
| 180 | 178 |
| 181 // Add it and make sure it is there and that all the fields were retrieved | 179 // Add it and make sure it is there and that all the fields were retrieved |
| 182 // correctly. | 180 // correctly. |
| 183 EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form)); | 181 EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form)); |
| 184 EXPECT_TRUE(db().GetAutofillableLogins(&result)); | 182 EXPECT_TRUE(db().GetAutofillableLogins(&result)); |
| 185 ASSERT_EQ(1U, result.size()); | 183 ASSERT_EQ(1U, result.size()); |
| 186 FormsAreEqual(form, *result[0]); | 184 EXPECT_EQ(form, *result[0]); |
| 187 result.clear(); | 185 result.clear(); |
| 188 | 186 |
| 189 // Match against an exact copy. | 187 // Match against an exact copy. |
| 190 EXPECT_TRUE(db().GetLogins(form, &result)); | 188 EXPECT_TRUE(db().GetLogins(form, &result)); |
| 191 ASSERT_EQ(1U, result.size()); | 189 ASSERT_EQ(1U, result.size()); |
| 192 FormsAreEqual(form, *result[0]); | 190 EXPECT_EQ(form, *result[0]); |
| 193 result.clear(); | 191 result.clear(); |
| 194 | 192 |
| 195 // The example site changes... | 193 // The example site changes... |
| 196 PasswordForm form2(form); | 194 PasswordForm form2(form); |
| 197 form2.origin = GURL("http://www.google.com/new/accounts/LoginAuth"); | 195 form2.origin = GURL("http://www.google.com/new/accounts/LoginAuth"); |
| 198 form2.submit_element = ASCIIToUTF16("reallySignIn"); | 196 form2.submit_element = ASCIIToUTF16("reallySignIn"); |
| 199 | 197 |
| 200 // Match against an inexact copy | 198 // Match against an inexact copy |
| 201 EXPECT_TRUE(db().GetLogins(form2, &result)); | 199 EXPECT_TRUE(db().GetLogins(form2, &result)); |
| 202 EXPECT_EQ(1U, result.size()); | 200 EXPECT_EQ(1U, result.size()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 // old form, and there is only one record. | 258 // old form, and there is only one record. |
| 261 EXPECT_EQ(UpdateChangeForForm(form6), db().UpdateLogin(form6)); | 259 EXPECT_EQ(UpdateChangeForForm(form6), db().UpdateLogin(form6)); |
| 262 // matches | 260 // matches |
| 263 EXPECT_TRUE(db().GetLogins(form5, &result)); | 261 EXPECT_TRUE(db().GetLogins(form5, &result)); |
| 264 EXPECT_EQ(1U, result.size()); | 262 EXPECT_EQ(1U, result.size()); |
| 265 result.clear(); | 263 result.clear(); |
| 266 // Only one record. | 264 // Only one record. |
| 267 EXPECT_TRUE(db().GetAutofillableLogins(&result)); | 265 EXPECT_TRUE(db().GetAutofillableLogins(&result)); |
| 268 EXPECT_EQ(1U, result.size()); | 266 EXPECT_EQ(1U, result.size()); |
| 269 // Password element was updated. | 267 // Password element was updated. |
| 270 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
| 271 // On the Mac we should never be storing passwords in the database. | |
| 272 EXPECT_EQ(base::string16(), result[0]->password_value); | |
| 273 #else | |
| 274 EXPECT_EQ(form6.password_value, result[0]->password_value); | 268 EXPECT_EQ(form6.password_value, result[0]->password_value); |
| 275 #endif | |
| 276 // Preferred login. | 269 // Preferred login. |
| 277 EXPECT_TRUE(form6.preferred); | 270 EXPECT_TRUE(form6.preferred); |
| 278 result.clear(); | 271 result.clear(); |
| 279 | 272 |
| 280 // Make sure everything can disappear. | 273 // Make sure everything can disappear. |
| 281 EXPECT_TRUE(db().RemoveLogin(form4)); | 274 EXPECT_TRUE(db().RemoveLogin(form4)); |
| 282 EXPECT_TRUE(db().GetAutofillableLogins(&result)); | 275 EXPECT_TRUE(db().GetAutofillableLogins(&result)); |
| 283 EXPECT_EQ(0U, result.size()); | 276 EXPECT_EQ(0U, result.size()); |
| 284 } | 277 } |
| 285 | 278 |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 form.skip_zero_click = true; | 738 form.skip_zero_click = true; |
| 746 EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form)); | 739 EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form)); |
| 747 | 740 |
| 748 // Get all non-blacklisted logins (should be none). | 741 // Get all non-blacklisted logins (should be none). |
| 749 EXPECT_TRUE(db().GetAutofillableLogins(&result)); | 742 EXPECT_TRUE(db().GetAutofillableLogins(&result)); |
| 750 ASSERT_EQ(0U, result.size()); | 743 ASSERT_EQ(0U, result.size()); |
| 751 | 744 |
| 752 // GetLogins should give the blacklisted result. | 745 // GetLogins should give the blacklisted result. |
| 753 EXPECT_TRUE(db().GetLogins(form, &result)); | 746 EXPECT_TRUE(db().GetLogins(form, &result)); |
| 754 ASSERT_EQ(1U, result.size()); | 747 ASSERT_EQ(1U, result.size()); |
| 755 FormsAreEqual(form, *result[0]); | 748 EXPECT_EQ(form, *result[0]); |
| 756 result.clear(); | 749 result.clear(); |
| 757 | 750 |
| 758 // So should GetAllBlacklistedLogins. | 751 // So should GetAllBlacklistedLogins. |
| 759 EXPECT_TRUE(db().GetBlacklistLogins(&result)); | 752 EXPECT_TRUE(db().GetBlacklistLogins(&result)); |
| 760 ASSERT_EQ(1U, result.size()); | 753 ASSERT_EQ(1U, result.size()); |
| 761 FormsAreEqual(form, *result[0]); | 754 EXPECT_EQ(form, *result[0]); |
| 762 result.clear(); | 755 result.clear(); |
| 763 } | 756 } |
| 764 | 757 |
| 765 TEST_F(LoginDatabaseTest, VectorSerialization) { | 758 TEST_F(LoginDatabaseTest, VectorSerialization) { |
| 766 // Empty vector. | 759 // Empty vector. |
| 767 std::vector<base::string16> vec; | 760 std::vector<base::string16> vec; |
| 768 base::Pickle temp = SerializeVector(vec); | 761 base::Pickle temp = SerializeVector(vec); |
| 769 std::vector<base::string16> output = DeserializeVector(temp); | 762 std::vector<base::string16> output = DeserializeVector(temp); |
| 770 EXPECT_THAT(output, Eq(vec)); | 763 EXPECT_THAT(output, Eq(vec)); |
| 771 | 764 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 808 encountered_form.username_element = ASCIIToUTF16("Email"); | 801 encountered_form.username_element = ASCIIToUTF16("Email"); |
| 809 encountered_form.password_element = ASCIIToUTF16("Passwd"); | 802 encountered_form.password_element = ASCIIToUTF16("Passwd"); |
| 810 encountered_form.submit_element = ASCIIToUTF16("signIn"); | 803 encountered_form.submit_element = ASCIIToUTF16("signIn"); |
| 811 | 804 |
| 812 // Get matches for encountered_form. | 805 // Get matches for encountered_form. |
| 813 EXPECT_TRUE(db().GetLogins(encountered_form, &result)); | 806 EXPECT_TRUE(db().GetLogins(encountered_form, &result)); |
| 814 ASSERT_EQ(1U, result.size()); | 807 ASSERT_EQ(1U, result.size()); |
| 815 EXPECT_EQ(incomplete_form.origin, result[0]->origin); | 808 EXPECT_EQ(incomplete_form.origin, result[0]->origin); |
| 816 EXPECT_EQ(incomplete_form.signon_realm, result[0]->signon_realm); | 809 EXPECT_EQ(incomplete_form.signon_realm, result[0]->signon_realm); |
| 817 EXPECT_EQ(incomplete_form.username_value, result[0]->username_value); | 810 EXPECT_EQ(incomplete_form.username_value, result[0]->username_value); |
| 818 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
| 819 // On Mac, passwords are not stored in login database, instead they're in | |
| 820 // the keychain. | |
| 821 EXPECT_TRUE(result[0]->password_value.empty()); | |
| 822 #else | |
| 823 EXPECT_EQ(incomplete_form.password_value, result[0]->password_value); | 811 EXPECT_EQ(incomplete_form.password_value, result[0]->password_value); |
| 824 #endif // OS_MACOSX && !OS_IOS | |
| 825 EXPECT_TRUE(result[0]->preferred); | 812 EXPECT_TRUE(result[0]->preferred); |
| 826 EXPECT_FALSE(result[0]->ssl_valid); | 813 EXPECT_FALSE(result[0]->ssl_valid); |
| 827 | 814 |
| 828 // We should return empty 'action', 'username_element', 'password_element' | 815 // We should return empty 'action', 'username_element', 'password_element' |
| 829 // and 'submit_element' as we can't be sure if the credentials were entered | 816 // and 'submit_element' as we can't be sure if the credentials were entered |
| 830 // in this particular form on the page. | 817 // in this particular form on the page. |
| 831 EXPECT_EQ(GURL(), result[0]->action); | 818 EXPECT_EQ(GURL(), result[0]->action); |
| 832 EXPECT_TRUE(result[0]->username_element.empty()); | 819 EXPECT_TRUE(result[0]->username_element.empty()); |
| 833 EXPECT_TRUE(result[0]->password_element.empty()); | 820 EXPECT_TRUE(result[0]->password_element.empty()); |
| 834 EXPECT_TRUE(result[0]->submit_element.empty()); | 821 EXPECT_TRUE(result[0]->submit_element.empty()); |
| 835 result.clear(); | 822 result.clear(); |
| 836 | 823 |
| 837 // Let's say this login form worked. Now update the stored credentials with | 824 // Let's say this login form worked. Now update the stored credentials with |
| 838 // 'action', 'username_element', 'password_element' and 'submit_element' from | 825 // 'action', 'username_element', 'password_element' and 'submit_element' from |
| 839 // the encountered form. | 826 // the encountered form. |
| 840 PasswordForm completed_form(incomplete_form); | 827 PasswordForm completed_form(incomplete_form); |
| 841 completed_form.action = encountered_form.action; | 828 completed_form.action = encountered_form.action; |
| 842 completed_form.username_element = encountered_form.username_element; | 829 completed_form.username_element = encountered_form.username_element; |
| 843 completed_form.password_element = encountered_form.password_element; | 830 completed_form.password_element = encountered_form.password_element; |
| 844 completed_form.submit_element = encountered_form.submit_element; | 831 completed_form.submit_element = encountered_form.submit_element; |
| 845 EXPECT_EQ(AddChangeForForm(completed_form), db().AddLogin(completed_form)); | 832 EXPECT_EQ(AddChangeForForm(completed_form), db().AddLogin(completed_form)); |
| 846 EXPECT_TRUE(db().RemoveLogin(incomplete_form)); | 833 EXPECT_TRUE(db().RemoveLogin(incomplete_form)); |
| 847 | 834 |
| 848 // Get matches for encountered_form again. | 835 // Get matches for encountered_form again. |
| 849 EXPECT_TRUE(db().GetLogins(encountered_form, &result)); | 836 EXPECT_TRUE(db().GetLogins(encountered_form, &result)); |
| 850 ASSERT_EQ(1U, result.size()); | 837 ASSERT_EQ(1U, result.size()); |
| 851 | 838 |
| 852 // This time we should have all the info available. | 839 // This time we should have all the info available. |
| 853 PasswordForm expected_form(completed_form); | 840 PasswordForm expected_form(completed_form); |
| 854 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
| 855 expected_form.password_value.clear(); | |
| 856 #endif // OS_MACOSX && !OS_IOS | |
| 857 EXPECT_EQ(expected_form, *result[0]); | 841 EXPECT_EQ(expected_form, *result[0]); |
| 858 result.clear(); | 842 result.clear(); |
| 859 } | 843 } |
| 860 | 844 |
| 861 TEST_F(LoginDatabaseTest, UpdateOverlappingCredentials) { | 845 TEST_F(LoginDatabaseTest, UpdateOverlappingCredentials) { |
| 862 // Save an incomplete form. Note that it only has a few fields set, ex. it's | 846 // Save an incomplete form. Note that it only has a few fields set, ex. it's |
| 863 // missing 'action', 'username_element' and 'password_element'. Such forms | 847 // missing 'action', 'username_element' and 'password_element'. Such forms |
| 864 // are sometimes inserted during import from other browsers (which may not | 848 // are sometimes inserted during import from other browsers (which may not |
| 865 // store this info). | 849 // store this info). |
| 866 PasswordForm incomplete_form; | 850 PasswordForm incomplete_form; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 896 // Simulate the user changing their password. | 880 // Simulate the user changing their password. |
| 897 complete_form.password_value = ASCIIToUTF16("new_password"); | 881 complete_form.password_value = ASCIIToUTF16("new_password"); |
| 898 complete_form.date_synced = base::Time::Now(); | 882 complete_form.date_synced = base::Time::Now(); |
| 899 EXPECT_EQ(UpdateChangeForForm(complete_form), | 883 EXPECT_EQ(UpdateChangeForForm(complete_form), |
| 900 db().UpdateLogin(complete_form)); | 884 db().UpdateLogin(complete_form)); |
| 901 | 885 |
| 902 // Both still exist now. | 886 // Both still exist now. |
| 903 EXPECT_TRUE(db().GetAutofillableLogins(&result)); | 887 EXPECT_TRUE(db().GetAutofillableLogins(&result)); |
| 904 ASSERT_EQ(2U, result.size()); | 888 ASSERT_EQ(2U, result.size()); |
| 905 | 889 |
| 906 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
| 907 // On Mac, passwords are not stored in login database, instead they're in | |
| 908 // the keychain. | |
| 909 complete_form.password_value.clear(); | |
| 910 incomplete_form.password_value.clear(); | |
| 911 #endif // OS_MACOSX && !OS_IOS | |
| 912 if (result[0]->username_element.empty()) | 890 if (result[0]->username_element.empty()) |
| 913 std::swap(result[0], result[1]); | 891 std::swap(result[0], result[1]); |
| 914 EXPECT_EQ(complete_form, *result[0]); | 892 EXPECT_EQ(complete_form, *result[0]); |
| 915 EXPECT_EQ(incomplete_form, *result[1]); | 893 EXPECT_EQ(incomplete_form, *result[1]); |
| 916 } | 894 } |
| 917 | 895 |
| 918 TEST_F(LoginDatabaseTest, DoubleAdd) { | 896 TEST_F(LoginDatabaseTest, DoubleAdd) { |
| 919 PasswordForm form; | 897 PasswordForm form; |
| 920 form.origin = GURL("http://accounts.google.com/LoginAuth"); | 898 form.origin = GURL("http://accounts.google.com/LoginAuth"); |
| 921 form.signon_realm = "http://accounts.google.com/"; | 899 form.signon_realm = "http://accounts.google.com/"; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 form.type = PasswordForm::TYPE_GENERATED; | 958 form.type = PasswordForm::TYPE_GENERATED; |
| 981 form.display_name = ASCIIToUTF16("Mr. Smith"); | 959 form.display_name = ASCIIToUTF16("Mr. Smith"); |
| 982 form.avatar_url = GURL("https://accounts.google.com/Avatar"); | 960 form.avatar_url = GURL("https://accounts.google.com/Avatar"); |
| 983 form.federation_url = GURL("https://accounts.google.com/federation"); | 961 form.federation_url = GURL("https://accounts.google.com/federation"); |
| 984 form.skip_zero_click = true; | 962 form.skip_zero_click = true; |
| 985 EXPECT_EQ(UpdateChangeForForm(form), db().UpdateLogin(form)); | 963 EXPECT_EQ(UpdateChangeForForm(form), db().UpdateLogin(form)); |
| 986 | 964 |
| 987 ScopedVector<autofill::PasswordForm> result; | 965 ScopedVector<autofill::PasswordForm> result; |
| 988 EXPECT_TRUE(db().GetLogins(form, &result)); | 966 EXPECT_TRUE(db().GetLogins(form, &result)); |
| 989 ASSERT_EQ(1U, result.size()); | 967 ASSERT_EQ(1U, result.size()); |
| 990 #if defined(OS_MACOSX) && !defined(OS_IOS) | |
| 991 // On Mac, passwords are not stored in login database, instead they're in | |
| 992 // the keychain. | |
| 993 form.password_value.clear(); | |
| 994 #endif // OS_MACOSX && !OS_IOS | |
| 995 EXPECT_EQ(form, *result[0]); | 968 EXPECT_EQ(form, *result[0]); |
| 996 } | 969 } |
| 997 | 970 |
| 998 TEST_F(LoginDatabaseTest, RemoveWrongForm) { | 971 TEST_F(LoginDatabaseTest, RemoveWrongForm) { |
| 999 PasswordForm form; | 972 PasswordForm form; |
| 1000 // |origin| shouldn't be empty. | 973 // |origin| shouldn't be empty. |
| 1001 form.origin = GURL("http://accounts.google.com/LoginAuth"); | 974 form.origin = GURL("http://accounts.google.com/LoginAuth"); |
| 1002 form.signon_realm = "http://accounts.google.com/"; | 975 form.signon_realm = "http://accounts.google.com/"; |
| 1003 form.username_value = ASCIIToUTF16("my_username"); | 976 form.username_value = ASCIIToUTF16("my_username"); |
| 1004 form.password_value = ASCIIToUTF16("my_password"); | 977 form.password_value = ASCIIToUTF16("my_password"); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1114 histogram_tester.ExpectUniqueSample( | 1087 histogram_tester.ExpectUniqueSample( |
| 1115 "PasswordManager.EmptyUsernames.CountInDatabase", | 1088 "PasswordManager.EmptyUsernames.CountInDatabase", |
| 1116 3, | 1089 3, |
| 1117 1); | 1090 1); |
| 1118 histogram_tester.ExpectUniqueSample( | 1091 histogram_tester.ExpectUniqueSample( |
| 1119 "PasswordManager.EmptyUsernames.WithoutCorrespondingNonempty", | 1092 "PasswordManager.EmptyUsernames.WithoutCorrespondingNonempty", |
| 1120 1, | 1093 1, |
| 1121 1); | 1094 1); |
| 1122 } | 1095 } |
| 1123 | 1096 |
| 1097 TEST_F(LoginDatabaseTest, ClearPasswordValues) { |
| 1098 db().set_clear_password_values(true); |
| 1099 |
| 1100 // Add a PasswordForm, the password should be cleared. |
| 1101 base::HistogramTester histogram_tester; |
| 1102 PasswordForm form; |
| 1103 form.origin = GURL("http://accounts.google.com/LoginAuth"); |
| 1104 form.signon_realm = "http://accounts.google.com/"; |
| 1105 form.username_value = ASCIIToUTF16("my_username"); |
| 1106 form.password_value = ASCIIToUTF16("12345"); |
| 1107 EXPECT_EQ(AddChangeForForm(form), db().AddLogin(form)); |
| 1108 |
| 1109 ScopedVector<autofill::PasswordForm> result; |
| 1110 EXPECT_TRUE(db().GetLogins(form, &result)); |
| 1111 ASSERT_EQ(1U, result.size()); |
| 1112 PasswordForm expected_form = form; |
| 1113 expected_form.password_value.clear(); |
| 1114 EXPECT_EQ(expected_form, *result[0]); |
| 1115 |
| 1116 // Update the password, it should stay empty. |
| 1117 form.password_value = ASCIIToUTF16("password"); |
| 1118 EXPECT_EQ(UpdateChangeForForm(form), db().UpdateLogin(form)); |
| 1119 EXPECT_TRUE(db().GetLogins(form, &result)); |
| 1120 ASSERT_EQ(1U, result.size()); |
| 1121 EXPECT_EQ(expected_form, *result[0]); |
| 1122 |
| 1123 // Encrypting/decrypting shouldn't happen. Thus there should be no keychain |
| 1124 // access on Mac. |
| 1125 scoped_ptr<base::HistogramSamples> samples = |
| 1126 histogram_tester.GetHistogramSamplesSinceCreation("OSX.Keychain.Access"); |
| 1127 EXPECT_TRUE(!samples || samples->TotalCount() == 0); |
| 1128 } |
| 1129 |
| 1124 #if defined(OS_POSIX) | 1130 #if defined(OS_POSIX) |
| 1125 // Only the current user has permission to read the database. | 1131 // Only the current user has permission to read the database. |
| 1126 // | 1132 // |
| 1127 // Only POSIX because GetPosixFilePermissions() only exists on POSIX. | 1133 // Only POSIX because GetPosixFilePermissions() only exists on POSIX. |
| 1128 // This tests that sql::Connection::set_restrict_to_user() was called, | 1134 // This tests that sql::Connection::set_restrict_to_user() was called, |
| 1129 // and that function is a noop on non-POSIX platforms in any case. | 1135 // and that function is a noop on non-POSIX platforms in any case. |
| 1130 TEST_F(LoginDatabaseTest, FilePermissions) { | 1136 TEST_F(LoginDatabaseTest, FilePermissions) { |
| 1131 int mode = base::FILE_PERMISSION_MASK; | 1137 int mode = base::FILE_PERMISSION_MASK; |
| 1132 EXPECT_TRUE(base::GetPosixFilePermissions(file_, &mode)); | 1138 EXPECT_TRUE(base::GetPosixFilePermissions(file_, &mode)); |
| 1133 EXPECT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode); | 1139 EXPECT_EQ((mode & base::FILE_PERMISSION_USER_MASK), mode); |
| 1134 } | 1140 } |
| 1135 #endif // defined(OS_POSIX) | 1141 #endif // defined(OS_POSIX) |
| 1136 | 1142 |
| 1137 // Test the migration from GetParam() version to kCurrentVersionNumber. | 1143 // Test the migration from GetParam() version to kCurrentVersionNumber. |
| 1138 class LoginDatabaseMigrationTest : public testing::TestWithParam<int> { | 1144 class LoginDatabaseMigrationTest : public testing::TestWithParam<int> { |
| 1139 protected: | 1145 protected: |
| 1140 void SetUp() override { | 1146 void SetUp() override { |
| 1141 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 1147 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 1142 database_dump_location_ = database_dump_location_.AppendASCII("components") | 1148 database_dump_location_ = database_dump_location_.AppendASCII("components") |
| 1143 .AppendASCII("test") | 1149 .AppendASCII("test") |
| 1144 .AppendASCII("data") | 1150 .AppendASCII("data") |
| 1145 .AppendASCII("password_manager"); | 1151 .AppendASCII("password_manager"); |
| 1146 database_path_ = temp_dir_.path().AppendASCII("test.db"); | 1152 database_path_ = temp_dir_.path().AppendASCII("test.db"); |
| 1153 #if defined(OS_MACOSX) |
| 1154 OSCrypt::UseMockKeychain(true); |
| 1155 #endif // defined(OS_MACOSX) |
| 1147 } | 1156 } |
| 1148 | 1157 |
| 1149 // Creates the databse from |sql_file|. | 1158 // Creates the databse from |sql_file|. |
| 1150 void CreateDatabase(base::StringPiece sql_file) { | 1159 void CreateDatabase(base::StringPiece sql_file) { |
| 1151 base::FilePath database_dump; | 1160 base::FilePath database_dump; |
| 1152 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &database_dump)); | 1161 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &database_dump)); |
| 1153 database_dump = | 1162 database_dump = |
| 1154 database_dump.Append(database_dump_location_).AppendASCII(sql_file); | 1163 database_dump.Append(database_dump_location_).AppendASCII(sql_file); |
| 1155 ASSERT_TRUE( | 1164 ASSERT_TRUE( |
| 1156 sql::test::CreateDatabaseFromSQL(database_path_, database_dump)); | 1165 sql::test::CreateDatabaseFromSQL(database_path_, database_dump)); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 // Add the same form twice to test the constraints in the database. | 1237 // Add the same form twice to test the constraints in the database. |
| 1229 EXPECT_EQ(AddChangeForForm(form), db.AddLogin(form)); | 1238 EXPECT_EQ(AddChangeForForm(form), db.AddLogin(form)); |
| 1230 PasswordStoreChangeList list; | 1239 PasswordStoreChangeList list; |
| 1231 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); | 1240 list.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form)); |
| 1232 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); | 1241 list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); |
| 1233 EXPECT_EQ(list, db.AddLogin(form)); | 1242 EXPECT_EQ(list, db.AddLogin(form)); |
| 1234 | 1243 |
| 1235 ScopedVector<autofill::PasswordForm> result; | 1244 ScopedVector<autofill::PasswordForm> result; |
| 1236 EXPECT_TRUE(db.GetLogins(form, &result)); | 1245 EXPECT_TRUE(db.GetLogins(form, &result)); |
| 1237 ASSERT_EQ(1U, result.size()); | 1246 ASSERT_EQ(1U, result.size()); |
| 1238 FormsAreEqual(form, *result[0]); | 1247 EXPECT_EQ(form, *result[0]); |
| 1239 EXPECT_TRUE(db.RemoveLogin(form)); | 1248 EXPECT_TRUE(db.RemoveLogin(form)); |
| 1240 } | 1249 } |
| 1241 // New date, in microseconds since platform independent epoch. | 1250 // New date, in microseconds since platform independent epoch. |
| 1242 std::vector<int64_t> new_date_created(GetDateCreated()); | 1251 std::vector<int64_t> new_date_created(GetDateCreated()); |
| 1243 if (version() <= 8) { | 1252 if (version() <= 8) { |
| 1244 ASSERT_EQ(2U, new_date_created.size()); | 1253 ASSERT_EQ(2U, new_date_created.size()); |
| 1245 // Check that the two dates match up. | 1254 // Check that the two dates match up. |
| 1246 for (size_t i = 0; i < date_created.size(); ++i) { | 1255 for (size_t i = 0; i < date_created.size(); ++i) { |
| 1247 EXPECT_EQ(base::Time::FromInternalValue(new_date_created[i]), | 1256 EXPECT_EQ(base::Time::FromInternalValue(new_date_created[i]), |
| 1248 base::Time::FromTimeT(date_created[i])); | 1257 base::Time::FromTimeT(date_created[i])); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1274 } | 1283 } |
| 1275 | 1284 |
| 1276 INSTANTIATE_TEST_CASE_P(MigrationToVCurrent, | 1285 INSTANTIATE_TEST_CASE_P(MigrationToVCurrent, |
| 1277 LoginDatabaseMigrationTest, | 1286 LoginDatabaseMigrationTest, |
| 1278 testing::Range(1, kCurrentVersionNumber)); | 1287 testing::Range(1, kCurrentVersionNumber)); |
| 1279 INSTANTIATE_TEST_CASE_P(MigrationToVCurrent, | 1288 INSTANTIATE_TEST_CASE_P(MigrationToVCurrent, |
| 1280 LoginDatabaseMigrationTestV9, | 1289 LoginDatabaseMigrationTestV9, |
| 1281 testing::Values(9)); | 1290 testing::Values(9)); |
| 1282 | 1291 |
| 1283 } // namespace password_manager | 1292 } // namespace password_manager |
| OLD | NEW |