• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "base/memory/scoped_ptr.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/prefs/pref_registry_simple.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/prefs/testing_pref_service.h"
10 #include "base/run_loop.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "components/autofill/core/common/password_form.h"
14 #include "components/password_manager/core/browser/mock_password_store.h"
15 #include "components/password_manager/core/browser/password_form_manager.h"
16 #include "components/password_manager/core/browser/password_manager.h"
17 #include "components/password_manager/core/browser/password_manager_driver.h"
18 #include "components/password_manager/core/browser/password_store.h"
19 #include "components/password_manager/core/browser/stub_password_manager_client.h"
20 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
21 #include "components/password_manager/core/browser/test_password_store.h"
22 #include "components/password_manager/core/common/password_manager_pref_names.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 
26 using autofill::PasswordForm;
27 using base::ASCIIToUTF16;
28 using ::testing::_;
29 using ::testing::Eq;
30 using ::testing::Mock;
31 using ::testing::Return;
32 
33 namespace autofill {
34 class AutofillManager;
35 }
36 
37 namespace password_manager {
38 
39 namespace {
40 
RunAllPendingTasks()41 void RunAllPendingTasks() {
42   base::RunLoop run_loop;
43   base::MessageLoop::current()->PostTask(
44       FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
45   run_loop.Run();
46 }
47 
48 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
49  public:
50   MOCK_METHOD0(IsOffTheRecord, bool());
51   MOCK_METHOD1(AllowPasswordGenerationForForm, void(autofill::PasswordForm*));
52 };
53 
54 class TestPasswordManagerClient : public StubPasswordManagerClient {
55  public:
TestPasswordManagerClient(PasswordStore * password_store)56   explicit TestPasswordManagerClient(PasswordStore* password_store)
57       : password_store_(password_store) {
58     prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
59                                            true);
60   }
61 
PromptUserToSavePassword(PasswordFormManager * form_to_save)62   virtual void PromptUserToSavePassword(PasswordFormManager* form_to_save)
63       OVERRIDE {}
GetPrefs()64   virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; }
GetPasswordStore()65   virtual PasswordStore* GetPasswordStore() OVERRIDE { return password_store_; }
GetDriver()66   virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; }
AuthenticateAutofillAndFillForm(scoped_ptr<autofill::PasswordFormFillData> fill_data)67   virtual void AuthenticateAutofillAndFillForm(
68       scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {
69     driver_.FillPasswordForm(*fill_data.get());
70   }
71 
GetMockDriver()72   MockPasswordManagerDriver* GetMockDriver() { return &driver_; }
73 
74  private:
75   TestingPrefServiceSimple prefs_;
76   PasswordStore* password_store_;
77   MockPasswordManagerDriver driver_;
78 };
79 
80 class TestPasswordManager : public PasswordManager {
81  public:
TestPasswordManager(PasswordManagerClient * client)82   explicit TestPasswordManager(PasswordManagerClient* client)
83       : PasswordManager(client) {}
84 
Autofill(const autofill::PasswordForm & form_for_autofill,const autofill::PasswordFormMap & best_matches,const autofill::PasswordForm & preferred_match,bool wait_for_username) const85   virtual void Autofill(const autofill::PasswordForm& form_for_autofill,
86                         const autofill::PasswordFormMap& best_matches,
87                         const autofill::PasswordForm& preferred_match,
88                         bool wait_for_username) const OVERRIDE {
89     best_matches_ = best_matches;
90   }
91 
GetLatestBestMatches()92   const autofill::PasswordFormMap& GetLatestBestMatches() {
93     return best_matches_;
94   }
95 
96  private:
97   // Marked mutable to get around constness of Autofill().
98   mutable autofill::PasswordFormMap best_matches_;
99 };
100 
101 }  // namespace
102 
103 class PasswordFormManagerTest : public testing::Test {
104  public:
PasswordFormManagerTest()105   PasswordFormManagerTest() {}
106 
SetUp()107   virtual void SetUp() {
108     observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
109     observed_form_.action = GURL("http://accounts.google.com/a/Login");
110     observed_form_.username_element = ASCIIToUTF16("Email");
111     observed_form_.password_element = ASCIIToUTF16("Passwd");
112     observed_form_.submit_element = ASCIIToUTF16("signIn");
113     observed_form_.signon_realm = "http://accounts.google.com";
114 
115     saved_match_ = observed_form_;
116     saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
117     saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin");
118     saved_match_.preferred = true;
119     saved_match_.username_value = ASCIIToUTF16("test@gmail.com");
120     saved_match_.password_value = ASCIIToUTF16("test1");
121     saved_match_.other_possible_usernames.push_back(
122         ASCIIToUTF16("test2@gmail.com"));
123   }
124 
TearDown()125   virtual void TearDown() {
126     if (mock_store_)
127       mock_store_->Shutdown();
128   }
129 
InitializeMockStore()130   void InitializeMockStore() {
131     if (!mock_store_) {
132       mock_store_ = new MockPasswordStore();
133       ASSERT_TRUE(mock_store_);
134     }
135   }
136 
mock_store() const137   MockPasswordStore* mock_store() const { return mock_store_.get(); }
138 
GetPendingCredentials(PasswordFormManager * p)139   PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
140     return &p->pending_credentials_;
141   }
142 
SimulateMatchingPhase(PasswordFormManager * p,bool find_match)143   void SimulateMatchingPhase(PasswordFormManager* p, bool find_match) {
144     // Roll up the state to mock out the matching phase.
145     p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
146     if (!find_match)
147       return;
148 
149     PasswordForm* match = new PasswordForm(saved_match_);
150     // Heap-allocated form is owned by p.
151     p->best_matches_[match->username_value] = match;
152     p->preferred_match_ = match;
153   }
154 
SimulateFetchMatchingLoginsFromPasswordStore(PasswordFormManager * manager)155   void SimulateFetchMatchingLoginsFromPasswordStore(
156       PasswordFormManager* manager) {
157     // Just need to update the internal states.
158     manager->state_ = PasswordFormManager::MATCHING_PHASE;
159   }
160 
SimulateResponseFromPasswordStore(PasswordFormManager * manager,const std::vector<PasswordForm * > & result)161   void SimulateResponseFromPasswordStore(
162       PasswordFormManager* manager,
163       const std::vector<PasswordForm*>& result) {
164     // Simply call the callback method when request done. This will transfer
165     // the ownership of the objects in |result| to the |manager|.
166     manager->OnGetPasswordStoreResults(result);
167   }
168 
SanitizePossibleUsernames(PasswordFormManager * p,PasswordForm * form)169   void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) {
170     p->SanitizePossibleUsernames(form);
171   }
172 
IgnoredResult(PasswordFormManager * p,PasswordForm * form)173   bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
174     return p->IgnoreResult(*form);
175   }
176 
observed_form()177   PasswordForm* observed_form() { return &observed_form_; }
saved_match()178   PasswordForm* saved_match() { return &saved_match_; }
CreateSavedMatch(bool blacklisted)179   PasswordForm* CreateSavedMatch(bool blacklisted) {
180     // Owned by the caller of this method.
181     PasswordForm* match = new PasswordForm(saved_match_);
182     match->blacklisted_by_user = blacklisted;
183     return match;
184   }
185 
186  private:
187   PasswordForm observed_form_;
188   PasswordForm saved_match_;
189   scoped_refptr<MockPasswordStore> mock_store_;
190 };
191 
TEST_F(PasswordFormManagerTest,TestNewLogin)192 TEST_F(PasswordFormManagerTest, TestNewLogin) {
193   scoped_ptr<TestPasswordManagerClient> client(
194       new TestPasswordManagerClient(NULL));
195   scoped_ptr<StubPasswordManagerDriver> driver;
196   PasswordFormManager* manager = new PasswordFormManager(
197       NULL, client.get(), driver.get(), *observed_form(), false);
198 
199   SimulateMatchingPhase(manager, false);
200   // User submits credentials for the observed form.
201   PasswordForm credentials = *observed_form();
202   credentials.username_value = saved_match()->username_value;
203   credentials.password_value = saved_match()->password_value;
204   credentials.preferred = true;
205   manager->ProvisionallySave(
206       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
207 
208   // Successful login. The PasswordManager would instruct PasswordFormManager
209   // to save, which should know this is a new login.
210   EXPECT_TRUE(manager->IsNewLogin());
211   // Make sure the credentials that would be submitted on successful login
212   // are going to match the stored entry in the db.
213   EXPECT_EQ(observed_form()->origin.spec(),
214             GetPendingCredentials(manager)->origin.spec());
215   EXPECT_EQ(observed_form()->signon_realm,
216             GetPendingCredentials(manager)->signon_realm);
217   EXPECT_EQ(observed_form()->action, GetPendingCredentials(manager)->action);
218   EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
219   EXPECT_EQ(saved_match()->password_value,
220             GetPendingCredentials(manager)->password_value);
221   EXPECT_EQ(saved_match()->username_value,
222             GetPendingCredentials(manager)->username_value);
223 
224   // Now, suppose the user re-visits the site and wants to save an additional
225   // login for the site with a new username. In this case, the matching phase
226   // will yield the previously saved login.
227   SimulateMatchingPhase(manager, true);
228   // Set up the new login.
229   base::string16 new_user = ASCIIToUTF16("newuser");
230   base::string16 new_pass = ASCIIToUTF16("newpass");
231   credentials.username_value = new_user;
232   credentials.password_value = new_pass;
233   manager->ProvisionallySave(
234       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
235 
236   // Again, the PasswordFormManager should know this is still a new login.
237   EXPECT_TRUE(manager->IsNewLogin());
238   // And make sure everything squares up again.
239   EXPECT_EQ(observed_form()->origin.spec(),
240             GetPendingCredentials(manager)->origin.spec());
241   EXPECT_EQ(observed_form()->signon_realm,
242             GetPendingCredentials(manager)->signon_realm);
243   EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
244   EXPECT_EQ(new_pass, GetPendingCredentials(manager)->password_value);
245   EXPECT_EQ(new_user, GetPendingCredentials(manager)->username_value);
246   delete manager;
247 }
248 
TEST_F(PasswordFormManagerTest,TestUpdatePassword)249 TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
250   // Create a PasswordFormManager with observed_form, as if we just
251   // saw this form and need to find matching logins.
252   scoped_ptr<TestPasswordManagerClient> client(
253       new TestPasswordManagerClient(NULL));
254   scoped_ptr<StubPasswordManagerDriver> driver;
255   PasswordFormManager* manager = new PasswordFormManager(
256       NULL, client.get(), driver.get(), *observed_form(), false);
257 
258   SimulateMatchingPhase(manager, true);
259 
260   // User submits credentials for the observed form using a username previously
261   // stored, but a new password. Note that the observed form may have different
262   // origin URL (as it does in this case) than the saved_match, but we want to
263   // make sure the updated password is reflected in saved_match, because that is
264   // what we autofilled.
265   base::string16 new_pass = ASCIIToUTF16("newpassword");
266   PasswordForm credentials = *observed_form();
267   credentials.username_value = saved_match()->username_value;
268   credentials.password_value = new_pass;
269   credentials.preferred = true;
270   manager->ProvisionallySave(
271       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
272 
273   // Successful login. The PasswordManager would instruct PasswordFormManager
274   // to save, and since this is an update, it should know not to save as a new
275   // login.
276   EXPECT_FALSE(manager->IsNewLogin());
277 
278   // Make sure the credentials that would be submitted on successful login
279   // are going to match the stored entry in the db. (This verifies correct
280   // behaviour for bug 1074420).
281   EXPECT_EQ(GetPendingCredentials(manager)->origin.spec(),
282             saved_match()->origin.spec());
283   EXPECT_EQ(GetPendingCredentials(manager)->signon_realm,
284             saved_match()->signon_realm);
285   EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
286   EXPECT_EQ(new_pass, GetPendingCredentials(manager)->password_value);
287   // Done.
288   delete manager;
289 }
290 
TEST_F(PasswordFormManagerTest,TestIgnoreResult)291 TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
292   scoped_ptr<TestPasswordManagerClient> client(
293       new TestPasswordManagerClient(NULL));
294   scoped_ptr<StubPasswordManagerDriver> driver;
295   PasswordFormManager* manager = new PasswordFormManager(
296       NULL, client.get(), driver.get(), *observed_form(), false);
297 
298   // Make sure we don't match a PasswordForm if it was originally saved on
299   // an SSL-valid page and we are now on a page with invalid certificate.
300   saved_match()->ssl_valid = true;
301   EXPECT_TRUE(IgnoredResult(manager, saved_match()));
302 
303   saved_match()->ssl_valid = false;
304   // Different paths for action / origin are okay.
305   saved_match()->action = GURL("http://www.google.com/b/Login");
306   saved_match()->origin = GURL("http://www.google.com/foo");
307   EXPECT_FALSE(IgnoredResult(manager, saved_match()));
308 
309   // Done.
310   delete manager;
311 }
312 
TEST_F(PasswordFormManagerTest,TestEmptyAction)313 TEST_F(PasswordFormManagerTest, TestEmptyAction) {
314   scoped_ptr<TestPasswordManagerClient> client(
315       new TestPasswordManagerClient(NULL));
316   scoped_ptr<StubPasswordManagerDriver> driver;
317   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
318       NULL, client.get(), driver.get(), *observed_form(), false));
319 
320   saved_match()->action = GURL();
321   SimulateMatchingPhase(manager.get(), true);
322   // User logs in with the autofilled username / password from saved_match.
323   PasswordForm login = *observed_form();
324   login.username_value = saved_match()->username_value;
325   login.password_value = saved_match()->password_value;
326   manager->ProvisionallySave(
327       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
328   EXPECT_FALSE(manager->IsNewLogin());
329   // We bless our saved PasswordForm entry with the action URL of the
330   // observed form.
331   EXPECT_EQ(observed_form()->action,
332             GetPendingCredentials(manager.get())->action);
333 }
334 
TEST_F(PasswordFormManagerTest,TestUpdateAction)335 TEST_F(PasswordFormManagerTest, TestUpdateAction) {
336   scoped_ptr<TestPasswordManagerClient> client(
337       new TestPasswordManagerClient(NULL));
338   scoped_ptr<StubPasswordManagerDriver> driver;
339   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
340       NULL, client.get(), driver.get(), *observed_form(), false));
341 
342   SimulateMatchingPhase(manager.get(), true);
343   // User logs in with the autofilled username / password from saved_match.
344   PasswordForm login = *observed_form();
345   login.username_value = saved_match()->username_value;
346   login.password_value = saved_match()->password_value;
347 
348   manager->ProvisionallySave(
349       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
350   EXPECT_FALSE(manager->IsNewLogin());
351   // The observed action URL is different from the previously saved one, and
352   // is the same as the one that would be submitted on successful login.
353   EXPECT_NE(observed_form()->action, saved_match()->action);
354   EXPECT_EQ(observed_form()->action,
355             GetPendingCredentials(manager.get())->action);
356 }
357 
TEST_F(PasswordFormManagerTest,TestDynamicAction)358 TEST_F(PasswordFormManagerTest, TestDynamicAction) {
359   scoped_ptr<TestPasswordManagerClient> client(
360       new TestPasswordManagerClient(NULL));
361   scoped_ptr<StubPasswordManagerDriver> driver;
362   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
363       NULL, client.get(), driver.get(), *observed_form(), false));
364 
365   SimulateMatchingPhase(manager.get(), false);
366   PasswordForm login(*observed_form());
367   // The submitted action URL is different from the one observed on page load.
368   GURL new_action = GURL("http://www.google.com/new_action");
369   login.action = new_action;
370 
371   manager->ProvisionallySave(
372       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
373   EXPECT_TRUE(manager->IsNewLogin());
374   // Check that the provisionally saved action URL is the same as the submitted
375   // action URL, not the one observed on page load.
376   EXPECT_EQ(new_action, GetPendingCredentials(manager.get())->action);
377 }
378 
TEST_F(PasswordFormManagerTest,TestAlternateUsername)379 TEST_F(PasswordFormManagerTest, TestAlternateUsername) {
380   // Need a MessageLoop for callbacks.
381   base::MessageLoop message_loop;
382   scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
383   CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare()));
384 
385   TestPasswordManagerClient client(password_store.get());
386   TestPasswordManager password_manager(&client);
387   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
388       &password_manager, &client, client.GetDriver(), *observed_form(), false));
389   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
390       .Times(1);
391   EXPECT_CALL(*client.GetMockDriver(), IsOffTheRecord())
392       .WillRepeatedly(Return(false));
393 
394   password_store->AddLogin(*saved_match());
395   manager->FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
396   RunAllPendingTasks();
397 
398   // The saved match has the right username already.
399   PasswordForm login(*observed_form());
400   login.username_value = saved_match()->username_value;
401   login.password_value = saved_match()->password_value;
402   login.preferred = true;
403   manager->ProvisionallySave(
404       login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
405 
406   EXPECT_FALSE(manager->IsNewLogin());
407   manager->Save();
408   RunAllPendingTasks();
409 
410   // Should be only one password stored, and should not have
411   // |other_possible_usernames| set anymore.
412   TestPasswordStore::PasswordMap passwords = password_store->stored_passwords();
413   EXPECT_EQ(1U, passwords.size());
414   ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
415   EXPECT_EQ(saved_match()->username_value,
416             passwords[saved_match()->signon_realm][0].username_value);
417   EXPECT_EQ(0U,
418             passwords[saved_match()->signon_realm][0]
419                 .other_possible_usernames.size());
420 
421   // This time use an alternate username
422   manager.reset(new PasswordFormManager(
423       &password_manager, &client, client.GetDriver(), *observed_form(), false));
424   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
425       .Times(1);
426   password_store->Clear();
427   password_store->AddLogin(*saved_match());
428   manager->FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
429   RunAllPendingTasks();
430 
431   base::string16 new_username = saved_match()->other_possible_usernames[0];
432   login.username_value = new_username;
433   manager->ProvisionallySave(
434       login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
435 
436   EXPECT_FALSE(manager->IsNewLogin());
437   manager->Save();
438   RunAllPendingTasks();
439 
440   // |other_possible_usernames| should also be empty, but username_value should
441   // be changed to match |new_username|
442   passwords = password_store->stored_passwords();
443   EXPECT_EQ(1U, passwords.size());
444   ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
445   EXPECT_EQ(new_username,
446             passwords[saved_match()->signon_realm][0].username_value);
447   EXPECT_EQ(0U,
448             passwords[saved_match()->signon_realm][0]
449                 .other_possible_usernames.size());
450   password_store->Shutdown();
451 }
452 
TEST_F(PasswordFormManagerTest,TestValidForms)453 TEST_F(PasswordFormManagerTest, TestValidForms) {
454   // User submits credentials for the observed form.
455   PasswordForm credentials = *observed_form();
456   credentials.scheme = PasswordForm::SCHEME_HTML;
457   credentials.username_value = saved_match()->username_value;
458   credentials.password_value = saved_match()->password_value;
459 
460   // Form with both username_element and password_element.
461   PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
462   SimulateMatchingPhase(&manager1, false);
463   EXPECT_TRUE(manager1.HasValidPasswordForm());
464 
465   // Form without a username_element but with a password_element.
466   credentials.username_element.clear();
467   PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
468   SimulateMatchingPhase(&manager2, false);
469   EXPECT_FALSE(manager2.HasValidPasswordForm());
470 
471   // Form without a password_element but with a username_element.
472   credentials.username_element = saved_match()->username_element;
473   credentials.password_element.clear();
474   PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
475   SimulateMatchingPhase(&manager3, false);
476   EXPECT_FALSE(manager3.HasValidPasswordForm());
477 
478   // Form with neither a password_element nor a username_element.
479   credentials.username_element.clear();
480   credentials.password_element.clear();
481   PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
482   SimulateMatchingPhase(&manager4, false);
483   EXPECT_FALSE(manager4.HasValidPasswordForm());
484 }
485 
TEST_F(PasswordFormManagerTest,TestValidFormsBasic)486 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
487   // User submits credentials for the observed form.
488   PasswordForm credentials = *observed_form();
489   credentials.scheme = PasswordForm::SCHEME_BASIC;
490   credentials.username_value = saved_match()->username_value;
491   credentials.password_value = saved_match()->password_value;
492 
493   // Form with both username_element and password_element.
494   PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
495   SimulateMatchingPhase(&manager1, false);
496   EXPECT_TRUE(manager1.HasValidPasswordForm());
497 
498   // Form without a username_element but with a password_element.
499   credentials.username_element.clear();
500   PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
501   SimulateMatchingPhase(&manager2, false);
502   EXPECT_TRUE(manager2.HasValidPasswordForm());
503 
504   // Form without a password_element but with a username_element.
505   credentials.username_element = saved_match()->username_element;
506   credentials.password_element.clear();
507   PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
508   SimulateMatchingPhase(&manager3, false);
509   EXPECT_TRUE(manager3.HasValidPasswordForm());
510 
511   // Form with neither a password_element nor a username_element.
512   credentials.username_element.clear();
513   credentials.password_element.clear();
514   PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
515   SimulateMatchingPhase(&manager4, false);
516   EXPECT_TRUE(manager4.HasValidPasswordForm());
517 }
518 
TEST_F(PasswordFormManagerTest,TestSendNotBlacklistedMessage)519 TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) {
520   base::MessageLoop message_loop;
521 
522   // A dumb password manager.
523   TestPasswordManagerClient client(NULL);
524   TestPasswordManager password_manager(&client);
525   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
526       &password_manager, &client, client.GetDriver(), *observed_form(), false));
527 
528   // First time sign up attempt; No login result is found from password store;
529   // We should send the not blacklisted message.
530   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
531       .Times(1);
532   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
533   std::vector<PasswordForm*> result;
534   SimulateResponseFromPasswordStore(manager.get(), result);
535   Mock::VerifyAndClearExpectations(client.GetMockDriver());
536 
537   // Sign up attempt to previously visited sites; Login result is found from
538   // password store, and is not blacklisted; We should send the not blacklisted
539   // message.
540   manager.reset(new PasswordFormManager(
541       &password_manager, &client, client.GetDriver(), *observed_form(), false));
542   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
543       .Times(1);
544   EXPECT_CALL(*client.GetMockDriver(), IsOffTheRecord())
545       .WillRepeatedly(Return(false));
546   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
547   // We need add heap allocated objects to result.
548   result.push_back(CreateSavedMatch(false));
549   SimulateResponseFromPasswordStore(manager.get(), result);
550   Mock::VerifyAndClearExpectations(client.GetMockDriver());
551 
552   // Sign up attempt to previously visited sites; Login result is found from
553   // password store, but is blacklisted; We should not send the not blacklisted
554   // message.
555   manager.reset(new PasswordFormManager(
556       &password_manager, &client, client.GetDriver(), *observed_form(), false));
557   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
558       .Times(0);
559   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
560   result.clear();
561   result.push_back(CreateSavedMatch(true));
562   SimulateResponseFromPasswordStore(manager.get(), result);
563   Mock::VerifyAndClearExpectations(client.GetMockDriver());
564 }
565 
TEST_F(PasswordFormManagerTest,TestForceInclusionOfGeneratedPasswords)566 TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) {
567   base::MessageLoop message_loop;
568 
569   TestPasswordManagerClient client(NULL);
570   TestPasswordManager password_manager(&client);
571   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
572       &password_manager, &client, client.GetDriver(), *observed_form(), false));
573   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
574       .Times(1);
575   EXPECT_CALL(*client.GetMockDriver(), IsOffTheRecord())
576       .WillRepeatedly(Return(false));
577 
578   // Simulate having two matches for this origin, one of which was from a form
579   // with different HTML tags for elements. Because of scoring differences,
580   // only the first form will be sent to Autofill().
581   std::vector<PasswordForm*> results;
582   results.push_back(CreateSavedMatch(false));
583   results.push_back(CreateSavedMatch(false));
584   results[1]->username_value = ASCIIToUTF16("other@gmail.com");
585   results[1]->password_element = ASCIIToUTF16("signup_password");
586   results[1]->username_element = ASCIIToUTF16("signup_username");
587   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
588   SimulateResponseFromPasswordStore(manager.get(), results);
589   EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
590   results.clear();
591 
592   // Same thing, except this time the credentials that don't match quite as
593   // well are generated. They should now be sent to Autofill().
594   manager.reset(new PasswordFormManager(
595       &password_manager, &client, client.GetDriver(), *observed_form(), false));
596   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
597       .Times(1);
598 
599   results.push_back(CreateSavedMatch(false));
600   results.push_back(CreateSavedMatch(false));
601   results[1]->username_value = ASCIIToUTF16("other@gmail.com");
602   results[1]->password_element = ASCIIToUTF16("signup_password");
603   results[1]->username_element = ASCIIToUTF16("signup_username");
604   results[1]->type = PasswordForm::TYPE_GENERATED;
605   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
606   SimulateResponseFromPasswordStore(manager.get(), results);
607   EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size());
608 }
609 
TEST_F(PasswordFormManagerTest,TestSanitizePossibleUsernames)610 TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
611   scoped_ptr<TestPasswordManagerClient> client(
612       new TestPasswordManagerClient(NULL));
613   scoped_ptr<StubPasswordManagerDriver> driver;
614   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
615       NULL, client.get(), driver.get(), *observed_form(), false));
616   PasswordForm credentials(*observed_form());
617   credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
618   credentials.other_possible_usernames.push_back(
619       ASCIIToUTF16("378282246310005"));
620   credentials.other_possible_usernames.push_back(
621       ASCIIToUTF16("other username"));
622   credentials.username_value = ASCIIToUTF16("test@gmail.com");
623 
624   SanitizePossibleUsernames(manager.get(), &credentials);
625 
626   // Possible credit card number and SSN are stripped.
627   std::vector<base::string16> expected;
628   expected.push_back(ASCIIToUTF16("other username"));
629   EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
630 
631   credentials.other_possible_usernames.clear();
632   credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
633   credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
634   credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
635   credentials.other_possible_usernames.push_back(ASCIIToUTF16("random"));
636   credentials.other_possible_usernames.push_back(
637       ASCIIToUTF16("test@gmail.com"));
638 
639   SanitizePossibleUsernames(manager.get(), &credentials);
640 
641   // SSN, duplicate in |other_possible_usernames| and duplicate of
642   // |username_value| all removed.
643   expected.clear();
644   expected.push_back(ASCIIToUTF16("duplicate"));
645   expected.push_back(ASCIIToUTF16("random"));
646   EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
647 }
648 
TEST_F(PasswordFormManagerTest,TestUpdateIncompleteCredentials)649 TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
650   InitializeMockStore();
651 
652   // We've found this form on a website:
653   PasswordForm encountered_form;
654   encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
655   encountered_form.signon_realm = "http://accounts.google.com/";
656   encountered_form.action = GURL("http://accounts.google.com/Login");
657   encountered_form.username_element = ASCIIToUTF16("Email");
658   encountered_form.password_element = ASCIIToUTF16("Passwd");
659   encountered_form.submit_element = ASCIIToUTF16("signIn");
660 
661   TestPasswordManagerClient client(mock_store());
662   MockPasswordManagerDriver driver;
663   EXPECT_CALL(driver, IsOffTheRecord()).WillRepeatedly(Return(false));
664   EXPECT_CALL(driver, AllowPasswordGenerationForForm(_));
665 
666   TestPasswordManager manager(&client);
667   PasswordFormManager form_manager(
668       &manager, &client, &driver, encountered_form, false);
669 
670   const PasswordStore::AuthorizationPromptPolicy auth_policy =
671       PasswordStore::DISALLOW_PROMPT;
672   EXPECT_CALL(*mock_store(),
673               GetLogins(encountered_form, auth_policy, &form_manager));
674   form_manager.FetchMatchingLoginsFromPasswordStore(auth_policy);
675 
676   // Password store only has these incomplete credentials.
677   PasswordForm* incomplete_form = new PasswordForm();
678   incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth");
679   incomplete_form->signon_realm = "http://accounts.google.com/";
680   incomplete_form->password_value = ASCIIToUTF16("my_password");
681   incomplete_form->username_value = ASCIIToUTF16("my_username");
682   incomplete_form->preferred = true;
683   incomplete_form->ssl_valid = false;
684   incomplete_form->scheme = PasswordForm::SCHEME_HTML;
685 
686   // We expect to see this form eventually sent to the Password store. It
687   // has password/username values from the store and 'username_element',
688   // 'password_element', 'submit_element' and 'action' fields copied from
689   // the encountered form.
690   PasswordForm complete_form(*incomplete_form);
691   complete_form.action = encountered_form.action;
692   complete_form.password_element = encountered_form.password_element;
693   complete_form.username_element = encountered_form.username_element;
694   complete_form.submit_element = encountered_form.submit_element;
695 
696   PasswordForm obsolete_form(*incomplete_form);
697   obsolete_form.action = encountered_form.action;
698 
699   // Feed the incomplete credentials to the manager.
700   std::vector<PasswordForm*> results;
701   results.push_back(incomplete_form);  // Takes ownership.
702   form_manager.OnRequestDone(results);
703 
704   form_manager.ProvisionallySave(
705       complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
706   // By now that form has been used once.
707   complete_form.times_used = 1;
708   obsolete_form.times_used = 1;
709 
710   // Check that PasswordStore receives an update request with the complete form.
711   EXPECT_CALL(*mock_store(), RemoveLogin(obsolete_form));
712   EXPECT_CALL(*mock_store(), AddLogin(complete_form));
713   form_manager.Save();
714 }
715 
TEST_F(PasswordFormManagerTest,TestScoringPublicSuffixMatch)716 TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) {
717   base::MessageLoop message_loop;
718 
719   TestPasswordManagerClient client(NULL);
720   MockPasswordManagerDriver driver;
721   EXPECT_CALL(driver, IsOffTheRecord()).WillRepeatedly(Return(false));
722   EXPECT_CALL(driver, AllowPasswordGenerationForForm(_));
723 
724   TestPasswordManager password_manager(&client);
725   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
726     &password_manager, &client, &driver, *observed_form(), false));
727 
728   // Simulate having two matches for this form, first comes from different
729   // signon realm, but reports the same origin and action as matched form.
730   // Second candidate has the same signon realm as the form, but has a different
731   // origin and action. Public suffix match is the most important criterion so
732   // the second candidate should be selected.
733   std::vector<PasswordForm*> results;
734   results.push_back(CreateSavedMatch(false));
735   results.push_back(CreateSavedMatch(false));
736   results[0]->original_signon_realm = "http://accounts2.google.com";
737   results[1]->origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2");
738   results[1]->action = GURL("http://accounts.google.com/a/ServiceLogin2");
739   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
740   SimulateResponseFromPasswordStore(manager.get(), results);
741   EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
742   EXPECT_EQ("", password_manager.GetLatestBestMatches().begin()
743       ->second->original_signon_realm);
744 }
745 
746 }  // namespace password_manager
747