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 |