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 "components/password_manager/core/browser/password_manager.h" | 5 #include "components/password_manager/core/browser/password_manager.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 } | 125 } |
126 | 126 |
127 PasswordForm MakeSimpleForm() { | 127 PasswordForm MakeSimpleForm() { |
128 PasswordForm form; | 128 PasswordForm form; |
129 form.origin = GURL("http://www.google.com/a/LoginAuth"); | 129 form.origin = GURL("http://www.google.com/a/LoginAuth"); |
130 form.action = GURL("http://www.google.com/a/Login"); | 130 form.action = GURL("http://www.google.com/a/Login"); |
131 form.username_element = ASCIIToUTF16("Email"); | 131 form.username_element = ASCIIToUTF16("Email"); |
132 form.password_element = ASCIIToUTF16("Passwd"); | 132 form.password_element = ASCIIToUTF16("Passwd"); |
133 form.username_value = ASCIIToUTF16("google"); | 133 form.username_value = ASCIIToUTF16("google"); |
134 form.password_value = ASCIIToUTF16("password"); | 134 form.password_value = ASCIIToUTF16("password"); |
135 // Default to true so we only need to add tests in autocomplete=off cases. | |
136 form.password_autocomplete_set = true; | |
137 form.submit_element = ASCIIToUTF16("signIn"); | 135 form.submit_element = ASCIIToUTF16("signIn"); |
138 form.signon_realm = "http://www.google.com"; | 136 form.signon_realm = "http://www.google.com"; |
139 return form; | 137 return form; |
140 } | 138 } |
141 | 139 |
142 // Create a sign-up form that only has a new password field. | 140 // Create a sign-up form that only has a new password field. |
143 PasswordForm MakeFormWithOnlyNewPasswordField() { | 141 PasswordForm MakeFormWithOnlyNewPasswordField() { |
144 PasswordForm form = MakeSimpleForm(); | 142 PasswordForm form = MakeSimpleForm(); |
145 form.new_password_element.swap(form.password_element); | 143 form.new_password_element.swap(form.password_element); |
146 form.new_password_value.swap(form.password_value); | 144 form.new_password_value.swap(form.password_value); |
147 return form; | 145 return form; |
148 } | 146 } |
149 | 147 |
150 // Reproduction of the form present on twitter's login page. | 148 // Reproduction of the form present on twitter's login page. |
151 PasswordForm MakeTwitterLoginForm() { | 149 PasswordForm MakeTwitterLoginForm() { |
152 PasswordForm form; | 150 PasswordForm form; |
153 form.origin = GURL("https://twitter.com/"); | 151 form.origin = GURL("https://twitter.com/"); |
154 form.action = GURL("https://twitter.com/sessions"); | 152 form.action = GURL("https://twitter.com/sessions"); |
155 form.username_element = ASCIIToUTF16("Email"); | 153 form.username_element = ASCIIToUTF16("Email"); |
156 form.password_element = ASCIIToUTF16("Passwd"); | 154 form.password_element = ASCIIToUTF16("Passwd"); |
157 form.username_value = ASCIIToUTF16("twitter"); | 155 form.username_value = ASCIIToUTF16("twitter"); |
158 form.password_value = ASCIIToUTF16("password"); | 156 form.password_value = ASCIIToUTF16("password"); |
159 form.password_autocomplete_set = true; | |
160 form.submit_element = ASCIIToUTF16("signIn"); | 157 form.submit_element = ASCIIToUTF16("signIn"); |
161 form.signon_realm = "https://twitter.com"; | 158 form.signon_realm = "https://twitter.com"; |
162 return form; | 159 return form; |
163 } | 160 } |
164 | 161 |
165 // Reproduction of the form present on twitter's failed login page. | 162 // Reproduction of the form present on twitter's failed login page. |
166 PasswordForm MakeTwitterFailedLoginForm() { | 163 PasswordForm MakeTwitterFailedLoginForm() { |
167 PasswordForm form; | 164 PasswordForm form; |
168 form.origin = GURL("https://twitter.com/login/error?redirect_after_login"); | 165 form.origin = GURL("https://twitter.com/login/error?redirect_after_login"); |
169 form.action = GURL("https://twitter.com/sessions"); | 166 form.action = GURL("https://twitter.com/sessions"); |
170 form.username_element = ASCIIToUTF16("EmailField"); | 167 form.username_element = ASCIIToUTF16("EmailField"); |
171 form.password_element = ASCIIToUTF16("PasswdField"); | 168 form.password_element = ASCIIToUTF16("PasswdField"); |
172 form.username_value = ASCIIToUTF16("twitter"); | 169 form.username_value = ASCIIToUTF16("twitter"); |
173 form.password_value = ASCIIToUTF16("password"); | 170 form.password_value = ASCIIToUTF16("password"); |
174 form.password_autocomplete_set = true; | |
175 form.submit_element = ASCIIToUTF16("signIn"); | 171 form.submit_element = ASCIIToUTF16("signIn"); |
176 form.signon_realm = "https://twitter.com"; | 172 form.signon_realm = "https://twitter.com"; |
177 return form; | 173 return form; |
178 } | 174 } |
179 | 175 |
180 PasswordForm MakeSimpleFormWithOnlyPasswordField() { | 176 PasswordForm MakeSimpleFormWithOnlyPasswordField() { |
181 PasswordForm form(MakeSimpleForm()); | 177 PasswordForm form(MakeSimpleForm()); |
182 form.username_element.clear(); | 178 form.username_element.clear(); |
183 form.username_value.clear(); | 179 form.username_value.clear(); |
184 return form; | 180 return form; |
(...skipping 10 matching lines...) Expand all Loading... |
195 if (lhs.password_element != rhs.password_element) | 191 if (lhs.password_element != rhs.password_element) |
196 return false; | 192 return false; |
197 if (lhs.new_password_element != rhs.new_password_element) | 193 if (lhs.new_password_element != rhs.new_password_element) |
198 return false; | 194 return false; |
199 if (lhs.username_value != rhs.username_value) | 195 if (lhs.username_value != rhs.username_value) |
200 return false; | 196 return false; |
201 if (lhs.password_value != rhs.password_value) | 197 if (lhs.password_value != rhs.password_value) |
202 return false; | 198 return false; |
203 if (lhs.new_password_value != rhs.new_password_value) | 199 if (lhs.new_password_value != rhs.new_password_value) |
204 return false; | 200 return false; |
205 if (lhs.password_autocomplete_set != rhs.password_autocomplete_set) | |
206 return false; | |
207 if (lhs.submit_element != rhs.submit_element) | 201 if (lhs.submit_element != rhs.submit_element) |
208 return false; | 202 return false; |
209 if (lhs.signon_realm != rhs.signon_realm) | 203 if (lhs.signon_realm != rhs.signon_realm) |
210 return false; | 204 return false; |
211 return true; | 205 return true; |
212 } | 206 } |
213 | 207 |
214 TestPasswordManager* manager() { return manager_.get(); } | 208 TestPasswordManager* manager() { return manager_.get(); } |
215 | 209 |
216 void OnPasswordFormSubmitted(const autofill::PasswordForm& form) { | 210 void OnPasswordFormSubmitted(const autofill::PasswordForm& form) { |
(...skipping 17 matching lines...) Expand all Loading... |
234 scoped_ptr<TestPasswordManager> manager_; | 228 scoped_ptr<TestPasswordManager> manager_; |
235 PasswordForm submitted_form_; | 229 PasswordForm submitted_form_; |
236 }; | 230 }; |
237 | 231 |
238 MATCHER_P(FormMatches, form, "") { | 232 MATCHER_P(FormMatches, form, "") { |
239 return form.signon_realm == arg.signon_realm && form.origin == arg.origin && | 233 return form.signon_realm == arg.signon_realm && form.origin == arg.origin && |
240 form.action == arg.action && | 234 form.action == arg.action && |
241 form.username_element == arg.username_element && | 235 form.username_element == arg.username_element && |
242 form.password_element == arg.password_element && | 236 form.password_element == arg.password_element && |
243 form.new_password_element == arg.new_password_element && | 237 form.new_password_element == arg.new_password_element && |
244 form.password_autocomplete_set == arg.password_autocomplete_set && | |
245 form.submit_element == arg.submit_element; | 238 form.submit_element == arg.submit_element; |
246 } | 239 } |
247 | 240 |
248 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) { | 241 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) { |
249 // Test that observing a newly submitted form shows the save password bar. | 242 // Test that observing a newly submitted form shows the save password bar. |
250 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); | 243 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); |
251 std::vector<PasswordForm> observed; | 244 std::vector<PasswordForm> observed; |
252 PasswordForm form(MakeSimpleForm()); | 245 PasswordForm form(MakeSimpleForm()); |
253 observed.push_back(form); | 246 observed.push_back(form); |
254 // The initial load. | 247 // The initial load. |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 EXPECT_CALL(driver_, FillPasswordForm(_)); | 581 EXPECT_CALL(driver_, FillPasswordForm(_)); |
589 EXPECT_CALL(*store_, | 582 EXPECT_CALL(*store_, |
590 GetLogins(_, testing::Eq(PasswordStore::DISALLOW_PROMPT), _)) | 583 GetLogins(_, testing::Eq(PasswordStore::DISALLOW_PROMPT), _)) |
591 .WillOnce(WithArg<2>(InvokeConsumer(&result))); | 584 .WillOnce(WithArg<2>(InvokeConsumer(&result))); |
592 std::vector<PasswordForm> observed; | 585 std::vector<PasswordForm> observed; |
593 PasswordForm form(MakeSimpleForm()); | 586 PasswordForm form(MakeSimpleForm()); |
594 observed.push_back(form); | 587 observed.push_back(form); |
595 manager()->OnPasswordFormsParsed(&driver_, observed); | 588 manager()->OnPasswordFormsParsed(&driver_, observed); |
596 } | 589 } |
597 | 590 |
598 TEST_F(PasswordManagerTest, FormSavedWithAutocompleteOff) { | |
599 // Test password form with non-generated password will be saved even if | |
600 // autocomplete=off. | |
601 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); | |
602 std::vector<PasswordForm> observed; | |
603 PasswordForm form(MakeSimpleForm()); | |
604 form.password_autocomplete_set = false; | |
605 observed.push_back(form); | |
606 manager()->OnPasswordFormsParsed(&driver_, observed); // The initial load. | |
607 manager()->OnPasswordFormsRendered(&driver_, observed, | |
608 true); // The initial layout. | |
609 | |
610 // And the form submit contract is to call ProvisionallySavePassword. | |
611 manager()->ProvisionallySavePassword(form); | |
612 | |
613 // Password form should be saved. | |
614 scoped_ptr<PasswordFormManager> form_to_save; | |
615 EXPECT_CALL(client_, | |
616 PromptUserToSavePasswordPtr( | |
617 _, CredentialSourceType::CREDENTIAL_SOURCE_PASSWORD_MANAGER)) | |
618 .Times(Exactly(1)) | |
619 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); | |
620 EXPECT_CALL(*store_, AddLogin(FormMatches(form))).Times(Exactly(0)); | |
621 | |
622 // Now the password manager waits for the navigation to complete. | |
623 observed.clear(); | |
624 manager()->OnPasswordFormsParsed(&driver_, | |
625 observed); // The post-navigation load. | |
626 manager()->OnPasswordFormsRendered(&driver_, observed, | |
627 true); // The post-navigation layout. | |
628 | |
629 ASSERT_TRUE(form_to_save.get()); | |
630 } | |
631 | |
632 TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) { | |
633 // Test password form with generated password will still be saved if | |
634 // autocomplete=off. | |
635 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); | |
636 std::vector<PasswordForm> observed; | |
637 PasswordForm form(MakeSimpleForm()); | |
638 form.password_autocomplete_set = false; | |
639 observed.push_back(form); | |
640 manager()->OnPasswordFormsParsed(&driver_, observed); // The initial load. | |
641 manager()->OnPasswordFormsRendered(&driver_, observed, | |
642 true); // The initial layout. | |
643 | |
644 // Simulate the user generating the password and submitting the form. | |
645 manager()->SetHasGeneratedPasswordForForm(&driver_, form, true); | |
646 manager()->ProvisionallySavePassword(form); | |
647 | |
648 // The user should not be presented with an infobar as they have already given | |
649 // consent by using the generated password. The form should be saved once | |
650 // navigation occurs. The client will be informed that automatic saving has | |
651 // occured. | |
652 EXPECT_CALL(client_, | |
653 PromptUserToSavePasswordPtr( | |
654 _, CredentialSourceType::CREDENTIAL_SOURCE_PASSWORD_MANAGER)) | |
655 .Times(Exactly(0)); | |
656 EXPECT_CALL(*store_, AddLogin(FormMatches(form))); | |
657 scoped_ptr<PasswordFormManager> saved_form_manager; | |
658 EXPECT_CALL(client_, AutomaticPasswordSavePtr(_)) | |
659 .Times(Exactly(1)) | |
660 .WillOnce(WithArg<0>(SaveToScopedPtr(&saved_form_manager))); | |
661 | |
662 // Now the password manager waits for the navigation to complete. | |
663 observed.clear(); | |
664 manager()->OnPasswordFormsParsed(&driver_, | |
665 observed); // The post-navigation load. | |
666 manager()->OnPasswordFormsRendered(&driver_, observed, | |
667 true); // The post-navigation layout. | |
668 } | |
669 | |
670 TEST_F(PasswordManagerTest, SubmissionCallbackTest) { | 591 TEST_F(PasswordManagerTest, SubmissionCallbackTest) { |
671 manager()->AddSubmissionCallback(SubmissionCallback()); | 592 manager()->AddSubmissionCallback(SubmissionCallback()); |
672 PasswordForm form = MakeSimpleForm(); | 593 PasswordForm form = MakeSimpleForm(); |
673 OnPasswordFormSubmitted(form); | 594 OnPasswordFormSubmitted(form); |
674 EXPECT_TRUE(FormsAreEqual(form, submitted_form_)); | 595 EXPECT_TRUE(FormsAreEqual(form, submitted_form_)); |
675 } | 596 } |
676 | 597 |
677 TEST_F(PasswordManagerTest, PasswordFormReappearance) { | 598 TEST_F(PasswordManagerTest, PasswordFormReappearance) { |
678 // Test the heuristic to know if a password form reappears. | 599 // Test the heuristic to know if a password form reappears. |
679 // We assume that if we send our credentials and there | 600 // We assume that if we send our credentials and there |
(...skipping 19 matching lines...) Expand all Loading... |
699 } | 620 } |
700 | 621 |
701 TEST_F(PasswordManagerTest, SyncCredentialsNotSaved) { | 622 TEST_F(PasswordManagerTest, SyncCredentialsNotSaved) { |
702 EXPECT_CALL(client_, IsSyncAccountCredential(_, _)) | 623 EXPECT_CALL(client_, IsSyncAccountCredential(_, _)) |
703 .WillRepeatedly(Return(true)); | 624 .WillRepeatedly(Return(true)); |
704 | 625 |
705 // Simulate loading a simple form with no existing stored password. | 626 // Simulate loading a simple form with no existing stored password. |
706 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); | 627 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); |
707 std::vector<PasswordForm> observed; | 628 std::vector<PasswordForm> observed; |
708 PasswordForm form(MakeSimpleForm()); | 629 PasswordForm form(MakeSimpleForm()); |
709 form.password_autocomplete_set = false; | |
710 observed.push_back(form); | 630 observed.push_back(form); |
711 manager()->OnPasswordFormsParsed(&driver_, observed); // The initial load. | 631 manager()->OnPasswordFormsParsed(&driver_, observed); // The initial load. |
712 manager()->OnPasswordFormsRendered(&driver_, observed, | 632 manager()->OnPasswordFormsRendered(&driver_, observed, |
713 true); // The initial layout. | 633 true); // The initial layout. |
714 | 634 |
715 // User should not be prompted and password should not be saved. | 635 // User should not be prompted and password should not be saved. |
716 EXPECT_CALL(client_, | 636 EXPECT_CALL(client_, |
717 PromptUserToSavePasswordPtr( | 637 PromptUserToSavePasswordPtr( |
718 _, CredentialSourceType::CREDENTIAL_SOURCE_PASSWORD_MANAGER)) | 638 _, CredentialSourceType::CREDENTIAL_SOURCE_PASSWORD_MANAGER)) |
719 .Times(Exactly(0)); | 639 .Times(Exactly(0)); |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 manager()->OnPasswordFormsRendered(&driver_, observed, true); | 1022 manager()->OnPasswordFormsRendered(&driver_, observed, true); |
1103 | 1023 |
1104 ASSERT_TRUE(form_to_save); | 1024 ASSERT_TRUE(form_to_save); |
1105 EXPECT_CALL(*store_, AddLogin(FormMatches(form))); | 1025 EXPECT_CALL(*store_, AddLogin(FormMatches(form))); |
1106 | 1026 |
1107 // Simulate saving the form, as if the info bar was accepted. | 1027 // Simulate saving the form, as if the info bar was accepted. |
1108 form_to_save->Save(); | 1028 form_to_save->Save(); |
1109 } | 1029 } |
1110 | 1030 |
1111 } // namespace password_manager | 1031 } // namespace password_manager |
OLD | NEW |