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
26using autofill::PasswordForm;
27using base::ASCIIToUTF16;
28using ::testing::_;
29using ::testing::Eq;
30using ::testing::Mock;
31using ::testing::Return;
32
33namespace autofill {
34class AutofillManager;
35}
36
37namespace password_manager {
38
39namespace {
40
41void RunAllPendingTasks() {
42  base::RunLoop run_loop;
43  base::MessageLoop::current()->PostTask(
44      FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
45  run_loop.Run();
46}
47
48class MockPasswordManagerDriver : public StubPasswordManagerDriver {
49 public:
50  MOCK_METHOD0(IsOffTheRecord, bool());
51  MOCK_METHOD1(AllowPasswordGenerationForForm,
52               void(const autofill::PasswordForm&));
53};
54
55class TestPasswordManagerClient : public StubPasswordManagerClient {
56 public:
57  explicit TestPasswordManagerClient(PasswordStore* password_store)
58      : password_store_(password_store) {
59    prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerSavingEnabled,
60                                           true);
61  }
62
63  virtual bool ShouldFilterAutofillResult(
64      const autofill::PasswordForm& form) OVERRIDE {
65    if (form == form_to_filter_)
66      return true;
67    return false;
68  }
69
70  virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; }
71  virtual PasswordStore* GetPasswordStore() OVERRIDE { return password_store_; }
72  virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; }
73  virtual void AuthenticateAutofillAndFillForm(
74      scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {
75    driver_.FillPasswordForm(*fill_data.get());
76  }
77
78  void SetFormToFilter(const autofill::PasswordForm& form) {
79    form_to_filter_ = form;
80  }
81
82  MockPasswordManagerDriver* GetMockDriver() { return &driver_; }
83
84 private:
85  autofill::PasswordForm form_to_filter_;
86
87  TestingPrefServiceSimple prefs_;
88  PasswordStore* password_store_;
89  testing::NiceMock<MockPasswordManagerDriver> driver_;
90};
91
92class TestPasswordManager : public PasswordManager {
93 public:
94  explicit TestPasswordManager(PasswordManagerClient* client)
95      : PasswordManager(client) {}
96
97  virtual void Autofill(const autofill::PasswordForm& form_for_autofill,
98                        const autofill::PasswordFormMap& best_matches,
99                        const autofill::PasswordForm& preferred_match,
100                        bool wait_for_username) const OVERRIDE {
101    best_matches_ = best_matches;
102  }
103
104  const autofill::PasswordFormMap& GetLatestBestMatches() {
105    return best_matches_;
106  }
107
108 private:
109  // Marked mutable to get around constness of Autofill().
110  mutable autofill::PasswordFormMap best_matches_;
111};
112
113class MockPasswordFormManager : public PasswordFormManager {
114 public:
115  MockPasswordFormManager(PasswordManager* manager,
116                          PasswordManagerClient* client,
117                          PasswordManagerDriver* driver,
118                          const autofill::PasswordForm& observed_form,
119                          bool ssl_valid)
120      : PasswordFormManager(manager, client, driver, observed_form, ssl_valid)
121  {}
122
123  MOCK_METHOD2(UploadPasswordForm, void(const autofill::FormData&,
124                                        const autofill::ServerFieldType&));
125};
126
127}  // namespace
128
129class PasswordFormManagerTest : public testing::Test {
130 public:
131  PasswordFormManagerTest() : client_(NULL /*password_store*/) {}
132
133  // Types of possible outcomes of simulated matching, see
134  // SimulateMatchingPhase.
135  enum ResultOfSimulatedMatching { RESULT_MATCH_FOUND, RESULT_NO_MATCH };
136
137  virtual void SetUp() {
138    observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
139    observed_form_.action = GURL("http://accounts.google.com/a/Login");
140    observed_form_.username_element = ASCIIToUTF16("Email");
141    observed_form_.password_element = ASCIIToUTF16("Passwd");
142    observed_form_.submit_element = ASCIIToUTF16("signIn");
143    observed_form_.signon_realm = "http://accounts.google.com";
144
145    saved_match_ = observed_form_;
146    saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
147    saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin");
148    saved_match_.preferred = true;
149    saved_match_.username_value = ASCIIToUTF16("test@gmail.com");
150    saved_match_.password_value = ASCIIToUTF16("test1");
151    saved_match_.other_possible_usernames.push_back(
152        ASCIIToUTF16("test2@gmail.com"));
153  }
154
155  virtual void TearDown() {
156    if (mock_store_.get())
157      mock_store_->Shutdown();
158  }
159
160  void InitializeMockStore() {
161    if (!mock_store_.get()) {
162      mock_store_ = new testing::NiceMock<MockPasswordStore>();
163      ASSERT_TRUE(mock_store_.get());
164    }
165  }
166
167  MockPasswordStore* mock_store() const { return mock_store_.get(); }
168
169  PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
170    return &p->pending_credentials_;
171  }
172
173  void SimulateMatchingPhase(PasswordFormManager* p,
174                             ResultOfSimulatedMatching result) {
175    // Roll up the state to mock out the matching phase.
176    p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
177    if (result == RESULT_NO_MATCH)
178      return;
179
180    PasswordForm* match = new PasswordForm(saved_match_);
181    // Heap-allocated form is owned by p.
182    p->best_matches_[match->username_value] = match;
183    p->preferred_match_ = match;
184  }
185
186  void SimulateFetchMatchingLoginsFromPasswordStore(
187      PasswordFormManager* manager) {
188    // Just need to update the internal states.
189    manager->state_ = PasswordFormManager::MATCHING_PHASE;
190  }
191
192  void SimulateResponseFromPasswordStore(
193      PasswordFormManager* manager,
194      const std::vector<PasswordForm*>& result) {
195    // Simply call the callback method when request done. This will transfer
196    // the ownership of the objects in |result| to the |manager|.
197    manager->OnGetPasswordStoreResults(result);
198  }
199
200  void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) {
201    p->SanitizePossibleUsernames(form);
202  }
203
204  bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
205    return p->ShouldIgnoreResult(*form);
206  }
207
208  PasswordForm* observed_form() { return &observed_form_; }
209  PasswordForm* saved_match() { return &saved_match_; }
210  PasswordForm* CreateSavedMatch(bool blacklisted) {
211    // Owned by the caller of this method.
212    PasswordForm* match = new PasswordForm(saved_match_);
213    match->blacklisted_by_user = blacklisted;
214    return match;
215  }
216
217  TestPasswordManagerClient* client() { return &client_; }
218
219 private:
220  PasswordForm observed_form_;
221  PasswordForm saved_match_;
222  scoped_refptr<testing::NiceMock<MockPasswordStore> > mock_store_;
223  TestPasswordManagerClient client_;
224};
225
226TEST_F(PasswordFormManagerTest, TestNewLogin) {
227  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
228  SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
229
230  // User submits credentials for the observed form.
231  PasswordForm credentials = *observed_form();
232  credentials.username_value = saved_match()->username_value;
233  credentials.password_value = saved_match()->password_value;
234  credentials.preferred = true;
235  manager.ProvisionallySave(
236      credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
237
238  // Successful login. The PasswordManager would instruct PasswordFormManager
239  // to save, which should know this is a new login.
240  EXPECT_TRUE(manager.IsNewLogin());
241  // Make sure the credentials that would be submitted on successful login
242  // are going to match the stored entry in the db.
243  EXPECT_EQ(observed_form()->origin.spec(),
244            GetPendingCredentials(&manager)->origin.spec());
245  EXPECT_EQ(observed_form()->signon_realm,
246            GetPendingCredentials(&manager)->signon_realm);
247  EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
248  EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
249  EXPECT_EQ(saved_match()->password_value,
250            GetPendingCredentials(&manager)->password_value);
251  EXPECT_EQ(saved_match()->username_value,
252            GetPendingCredentials(&manager)->username_value);
253  EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
254  EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
255
256  // Now, suppose the user re-visits the site and wants to save an additional
257  // login for the site with a new username. In this case, the matching phase
258  // will yield the previously saved login.
259  SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
260  // Set up the new login.
261  base::string16 new_user = ASCIIToUTF16("newuser");
262  base::string16 new_pass = ASCIIToUTF16("newpass");
263  credentials.username_value = new_user;
264  credentials.password_value = new_pass;
265  manager.ProvisionallySave(
266      credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
267
268  // Again, the PasswordFormManager should know this is still a new login.
269  EXPECT_TRUE(manager.IsNewLogin());
270  // And make sure everything squares up again.
271  EXPECT_EQ(observed_form()->origin.spec(),
272            GetPendingCredentials(&manager)->origin.spec());
273  EXPECT_EQ(observed_form()->signon_realm,
274            GetPendingCredentials(&manager)->signon_realm);
275  EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
276  EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
277  EXPECT_EQ(new_user, GetPendingCredentials(&manager)->username_value);
278  EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
279  EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
280}
281
282// If PSL-matched credentials had been suggested, but the user has overwritten
283// the password, the provisionally saved credentials should no longer be
284// considered as PSL-matched, so that the exception for not prompting before
285// saving PSL-matched credentials should no longer apply.
286TEST_F(PasswordFormManagerTest,
287       OverriddenPSLMatchedCredentialsNotMarkedAsPSLMatched) {
288  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
289
290  // The suggestion needs to be PSL-matched.
291  saved_match()->original_signon_realm = "www.example.org";
292  SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
293
294  // User modifies the suggested password and submits the form.
295  PasswordForm credentials(*observed_form());
296  credentials.username_value = saved_match()->username_value;
297  credentials.password_value =
298      saved_match()->password_value + ASCIIToUTF16("modify");
299  manager.ProvisionallySave(
300      credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
301
302  EXPECT_TRUE(manager.IsNewLogin());
303  EXPECT_FALSE(manager.IsPendingCredentialsPublicSuffixMatch());
304}
305
306TEST_F(PasswordFormManagerTest, TestNewLoginFromNewPasswordElement) {
307  // Add a new password field to the test form. The PasswordFormManager should
308  // save the password from this field, instead of the current password field.
309  observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
310
311  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
312  SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
313
314  // User enters current and new credentials to the observed form.
315  PasswordForm credentials(*observed_form());
316  credentials.username_value = saved_match()->username_value;
317  credentials.password_value = saved_match()->password_value;
318  credentials.new_password_value = ASCIIToUTF16("newpassword");
319  credentials.preferred = true;
320  manager.ProvisionallySave(
321      credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
322
323  // Successful login. The PasswordManager would instruct PasswordFormManager
324  // to save, which should know this is a new login.
325  EXPECT_TRUE(manager.IsNewLogin());
326  EXPECT_EQ(credentials.origin, GetPendingCredentials(&manager)->origin);
327  EXPECT_EQ(credentials.signon_realm,
328            GetPendingCredentials(&manager)->signon_realm);
329  EXPECT_EQ(credentials.action, GetPendingCredentials(&manager)->action);
330  EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
331  EXPECT_EQ(credentials.username_value,
332            GetPendingCredentials(&manager)->username_value);
333
334  // By this point, the PasswordFormManager should have promoted the new
335  // password value to be the current password, and should have wiped the
336  // password element names: they are likely going to be different on a login
337  // form, so it is not worth remembering them.
338  EXPECT_EQ(credentials.new_password_value,
339            GetPendingCredentials(&manager)->password_value);
340  EXPECT_TRUE(GetPendingCredentials(&manager)->password_element.empty());
341  EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
342  EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
343}
344
345TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
346  // Create a PasswordFormManager with observed_form, as if we just
347  // saw this form and need to find matching logins.
348  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
349
350  SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
351
352  // User submits credentials for the observed form using a username previously
353  // stored, but a new password. Note that the observed form may have different
354  // origin URL (as it does in this case) than the saved_match, but we want to
355  // make sure the updated password is reflected in saved_match, because that is
356  // what we autofilled.
357  base::string16 new_pass = ASCIIToUTF16("test2");
358  PasswordForm credentials = *observed_form();
359  credentials.username_value = saved_match()->username_value;
360  credentials.password_value = new_pass;
361  credentials.preferred = true;
362  manager.ProvisionallySave(
363      credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
364
365  // Successful login. The PasswordManager would instruct PasswordFormManager
366  // to save, and since this is an update, it should know not to save as a new
367  // login.
368  EXPECT_FALSE(manager.IsNewLogin());
369
370  // Make sure the credentials that would be submitted on successful login
371  // are going to match the stored entry in the db. (This verifies correct
372  // behaviour for bug 1074420).
373  EXPECT_EQ(GetPendingCredentials(&manager)->origin.spec(),
374            saved_match()->origin.spec());
375  EXPECT_EQ(GetPendingCredentials(&manager)->signon_realm,
376            saved_match()->signon_realm);
377  EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
378  EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
379}
380
381TEST_F(PasswordFormManagerTest, TestUpdatePasswordFromNewPasswordElement) {
382  // Add a new password field to the test form. The PasswordFormManager should
383  // save the password from this field, instead of the current password field.
384  observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
385
386  // Given that |observed_form| was most likely a change password form, it
387  // should not serve as a source for updating meta-information stored with the
388  // old credentials, such as element names, as they are likely going to be
389  // different between change password and login forms. To test this in depth,
390  // forcibly wipe |submit_element|, which should normally trigger updating this
391  // field from |observed_form| in the UpdateLogin() step as a special case. We
392  // will verify in the end that this did not happen.
393  saved_match()->submit_element.clear();
394
395  InitializeMockStore();
396  TestPasswordManagerClient client_with_store(mock_store());
397  PasswordFormManager manager(NULL,
398                              &client_with_store,
399                              client_with_store.GetDriver(),
400                              *observed_form(),
401                              false);
402  EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
403      .WillRepeatedly(Return(false));
404  SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
405
406  // User submits current and new credentials to the observed form.
407  PasswordForm credentials(*observed_form());
408  credentials.username_value = saved_match()->username_value;
409  credentials.password_value = saved_match()->password_value;
410  credentials.new_password_value = ASCIIToUTF16("test2");
411  credentials.preferred = true;
412  manager.ProvisionallySave(
413      credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
414
415  // Successful login. The PasswordManager would instruct PasswordFormManager
416  // to save, and since this is an update, it should know not to save as a new
417  // login.
418  EXPECT_FALSE(manager.IsNewLogin());
419
420  // By now, the PasswordFormManager should have promoted the new password value
421  // already to be the current password, and should no longer maintain any info
422  // about the new password.
423  EXPECT_EQ(credentials.new_password_value,
424            GetPendingCredentials(&manager)->password_value);
425  EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
426  EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
427
428  // Trigger saving to exercise some special case handling in UpdateLogin().
429  PasswordForm new_credentials;
430  EXPECT_CALL(*mock_store(), UpdateLogin(_))
431      .WillOnce(testing::SaveArg<0>(&new_credentials));
432  manager.Save();
433  Mock::VerifyAndClearExpectations(mock_store());
434
435  // No meta-information should be updated, only the password.
436  EXPECT_EQ(credentials.new_password_value, new_credentials.password_value);
437  EXPECT_EQ(saved_match()->username_element, new_credentials.username_element);
438  EXPECT_EQ(saved_match()->password_element, new_credentials.password_element);
439  EXPECT_EQ(saved_match()->submit_element, new_credentials.submit_element);
440}
441
442TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
443  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
444
445  // Make sure we don't match a PasswordForm if it was originally saved on
446  // an SSL-valid page and we are now on a page with invalid certificate.
447  saved_match()->ssl_valid = true;
448  EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
449
450  saved_match()->ssl_valid = false;
451  // Different paths for action / origin are okay.
452  saved_match()->action = GURL("http://www.google.com/b/Login");
453  saved_match()->origin = GURL("http://www.google.com/foo");
454  EXPECT_FALSE(IgnoredResult(&manager, saved_match()));
455
456  // Results should be ignored if the client requests it.
457  client()->SetFormToFilter(*saved_match());
458  EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
459}
460
461TEST_F(PasswordFormManagerTest, TestEmptyAction) {
462  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
463
464  saved_match()->action = GURL();
465  SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
466  // User logs in with the autofilled username / password from saved_match.
467  PasswordForm login = *observed_form();
468  login.username_value = saved_match()->username_value;
469  login.password_value = saved_match()->password_value;
470  manager.ProvisionallySave(
471      login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
472  EXPECT_FALSE(manager.IsNewLogin());
473  // We bless our saved PasswordForm entry with the action URL of the
474  // observed form.
475  EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
476}
477
478TEST_F(PasswordFormManagerTest, TestUpdateAction) {
479  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
480
481  SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
482  // User logs in with the autofilled username / password from saved_match.
483  PasswordForm login = *observed_form();
484  login.username_value = saved_match()->username_value;
485  login.password_value = saved_match()->password_value;
486
487  manager.ProvisionallySave(
488      login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
489  EXPECT_FALSE(manager.IsNewLogin());
490  // The observed action URL is different from the previously saved one, and
491  // is the same as the one that would be submitted on successful login.
492  EXPECT_NE(observed_form()->action, saved_match()->action);
493  EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
494}
495
496TEST_F(PasswordFormManagerTest, TestDynamicAction) {
497  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
498
499  SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
500  PasswordForm login(*observed_form());
501  // The submitted action URL is different from the one observed on page load.
502  GURL new_action = GURL("http://www.google.com/new_action");
503  login.action = new_action;
504
505  manager.ProvisionallySave(
506      login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
507  EXPECT_TRUE(manager.IsNewLogin());
508  // Check that the provisionally saved action URL is the same as the submitted
509  // action URL, not the one observed on page load.
510  EXPECT_EQ(new_action, GetPendingCredentials(&manager)->action);
511}
512
513TEST_F(PasswordFormManagerTest, TestAlternateUsername) {
514  // Need a MessageLoop for callbacks.
515  base::MessageLoop message_loop;
516  scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
517  CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
518
519  TestPasswordManagerClient client_with_store(password_store.get());
520  TestPasswordManager password_manager(&client_with_store);
521  PasswordFormManager manager(&password_manager,
522                              &client_with_store,
523                              client_with_store.GetDriver(),
524                              *observed_form(),
525                              false);
526  EXPECT_CALL(*client_with_store.GetMockDriver(),
527              AllowPasswordGenerationForForm(_)).Times(1);
528  EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
529      .WillRepeatedly(Return(false));
530
531  password_store->AddLogin(*saved_match());
532  manager.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
533  RunAllPendingTasks();
534
535  // The saved match has the right username already.
536  PasswordForm login(*observed_form());
537  login.username_value = saved_match()->username_value;
538  login.password_value = saved_match()->password_value;
539  login.preferred = true;
540  manager.ProvisionallySave(
541      login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
542
543  EXPECT_FALSE(manager.IsNewLogin());
544  manager.Save();
545  RunAllPendingTasks();
546
547  // Should be only one password stored, and should not have
548  // |other_possible_usernames| set anymore.
549  TestPasswordStore::PasswordMap passwords = password_store->stored_passwords();
550  EXPECT_EQ(1U, passwords.size());
551  ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
552  EXPECT_EQ(saved_match()->username_value,
553            passwords[saved_match()->signon_realm][0].username_value);
554  EXPECT_EQ(0U,
555            passwords[saved_match()->signon_realm][0]
556                .other_possible_usernames.size());
557
558  // This time use an alternate username
559  PasswordFormManager manager_alt(&password_manager,
560                                  &client_with_store,
561                                  client_with_store.GetDriver(),
562                                  *observed_form(),
563                                  false);
564  EXPECT_CALL(*client_with_store.GetMockDriver(),
565              AllowPasswordGenerationForForm(_)).Times(1);
566  password_store->Clear();
567  password_store->AddLogin(*saved_match());
568  manager_alt.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
569  RunAllPendingTasks();
570
571  base::string16 new_username = saved_match()->other_possible_usernames[0];
572  login.username_value = new_username;
573  manager_alt.ProvisionallySave(
574      login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
575
576  EXPECT_FALSE(manager_alt.IsNewLogin());
577  manager_alt.Save();
578  RunAllPendingTasks();
579
580  // |other_possible_usernames| should also be empty, but username_value should
581  // be changed to match |new_username|
582  passwords = password_store->stored_passwords();
583  EXPECT_EQ(1U, passwords.size());
584  ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
585  EXPECT_EQ(new_username,
586            passwords[saved_match()->signon_realm][0].username_value);
587  EXPECT_EQ(0U,
588            passwords[saved_match()->signon_realm][0]
589                .other_possible_usernames.size());
590  password_store->Shutdown();
591}
592
593TEST_F(PasswordFormManagerTest, TestValidForms) {
594  // User submits credentials for the observed form.
595  PasswordForm credentials = *observed_form();
596  credentials.scheme = PasswordForm::SCHEME_HTML;
597  credentials.username_value = saved_match()->username_value;
598  credentials.password_value = saved_match()->password_value;
599
600  // An alternate version of the form that also has a new_password_element.
601  PasswordForm new_credentials(*observed_form());
602  new_credentials.new_password_element = ASCIIToUTF16("NewPasswd");
603  new_credentials.new_password_value = ASCIIToUTF16("test1new");
604
605  // Form with both username_element and password_element.
606  PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
607  SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
608  EXPECT_TRUE(manager1.HasValidPasswordForm());
609
610  // Form with username_element, password_element, and new_password_element.
611  PasswordFormManager manager2(NULL, NULL, NULL, new_credentials, false);
612  SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
613  EXPECT_TRUE(manager2.HasValidPasswordForm());
614
615  // Form with username_element and only new_password_element.
616  new_credentials.password_element.clear();
617  PasswordFormManager manager3(NULL, NULL, NULL, new_credentials, false);
618  SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
619  EXPECT_TRUE(manager3.HasValidPasswordForm());
620
621  // Form without a username_element but with a password_element.
622  credentials.username_element.clear();
623  PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
624  SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
625  EXPECT_TRUE(manager4.HasValidPasswordForm());
626
627  // Form without a username_element but with a new_password_element.
628  new_credentials.username_element.clear();
629  PasswordFormManager manager5(NULL, NULL, NULL, new_credentials, false);
630  SimulateMatchingPhase(&manager5, RESULT_NO_MATCH);
631  EXPECT_TRUE(manager5.HasValidPasswordForm());
632
633  // Form without a password_element but with a username_element.
634  credentials.username_element = saved_match()->username_element;
635  credentials.password_element.clear();
636  PasswordFormManager manager6(NULL, NULL, NULL, credentials, false);
637  SimulateMatchingPhase(&manager6, RESULT_NO_MATCH);
638  EXPECT_FALSE(manager6.HasValidPasswordForm());
639
640  // Form with neither a password_element nor a username_element.
641  credentials.username_element.clear();
642  credentials.password_element.clear();
643  PasswordFormManager manager7(NULL, NULL, NULL, credentials, false);
644  SimulateMatchingPhase(&manager7, RESULT_NO_MATCH);
645  EXPECT_FALSE(manager7.HasValidPasswordForm());
646}
647
648TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
649  // User submits credentials for the observed form.
650  PasswordForm credentials = *observed_form();
651  credentials.scheme = PasswordForm::SCHEME_BASIC;
652  credentials.username_value = saved_match()->username_value;
653  credentials.password_value = saved_match()->password_value;
654
655  // Form with both username_element and password_element.
656  PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
657  SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
658  EXPECT_TRUE(manager1.HasValidPasswordForm());
659
660  // Form without a username_element but with a password_element.
661  credentials.username_element.clear();
662  PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
663  SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
664  EXPECT_TRUE(manager2.HasValidPasswordForm());
665
666  // Form without a password_element but with a username_element.
667  credentials.username_element = saved_match()->username_element;
668  credentials.password_element.clear();
669  PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
670  SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
671  EXPECT_TRUE(manager3.HasValidPasswordForm());
672
673  // Form with neither a password_element nor a username_element.
674  credentials.username_element.clear();
675  credentials.password_element.clear();
676  PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
677  SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
678  EXPECT_TRUE(manager4.HasValidPasswordForm());
679}
680
681TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) {
682  base::MessageLoop message_loop;
683
684  TestPasswordManager password_manager(client());
685  PasswordFormManager manager_no_creds(&password_manager,
686                                       client(),
687                                       client()->GetDriver(),
688                                       *observed_form(),
689                                       false);
690
691  // First time sign-up attempt. Password store does not contain matching
692  // credentials. AllowPasswordGenerationForForm should be called to send the
693  // "not blacklisted" message.
694  EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
695      .Times(1);
696  SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_creds);
697  std::vector<PasswordForm*> result;
698  SimulateResponseFromPasswordStore(&manager_no_creds, result);
699  Mock::VerifyAndClearExpectations(client()->GetMockDriver());
700
701  // Signing up on a previously visited site. Credentials are found in the
702  // password store, and are not blacklisted. AllowPasswordGenerationForForm
703  // should be called to send the "not blacklisted" message.
704  PasswordFormManager manager_creds(&password_manager,
705                                    client(),
706                                    client()->GetDriver(),
707                                    *observed_form(),
708                                    false);
709  EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
710      .Times(1);
711  EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
712      .WillRepeatedly(Return(false));
713  SimulateFetchMatchingLoginsFromPasswordStore(&manager_creds);
714  // We need add heap allocated objects to result.
715  result.push_back(CreateSavedMatch(false));
716  SimulateResponseFromPasswordStore(&manager_creds, result);
717  Mock::VerifyAndClearExpectations(client()->GetMockDriver());
718
719  // There are cases, such as when a form is explicitly for creating a new
720  // password, where we may ignore saved credentials. Make sure that we still
721  // allow generation in that case.
722  PasswordForm signup_form(*observed_form());
723  signup_form.new_password_element = base::ASCIIToUTF16("new_password_field");
724
725  PasswordFormManager manager_dropped_creds(&password_manager,
726                                            client(),
727                                            client()->GetDriver(),
728                                            signup_form,
729                                            false);
730  EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
731      .Times(1);
732  EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
733      .WillRepeatedly(Return(false));
734  SimulateFetchMatchingLoginsFromPasswordStore(&manager_dropped_creds);
735  result.clear();
736  result.push_back(CreateSavedMatch(false));
737  SimulateResponseFromPasswordStore(&manager_dropped_creds, result);
738  Mock::VerifyAndClearExpectations(client()->GetMockDriver());
739
740  // Signing up on a previously visited site. Credentials are found in the
741  // password store, but they are blacklisted. AllowPasswordGenerationForForm
742  // should not be called and no "not blacklisted" message sent.
743  PasswordFormManager manager_blacklisted(&password_manager,
744                                          client(),
745                                          client()->GetDriver(),
746                                          *observed_form(),
747                                          false);
748  EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
749      .Times(0);
750  SimulateFetchMatchingLoginsFromPasswordStore(&manager_blacklisted);
751  result.clear();
752  result.push_back(CreateSavedMatch(true));
753  SimulateResponseFromPasswordStore(&manager_blacklisted, result);
754  Mock::VerifyAndClearExpectations(client()->GetMockDriver());
755}
756
757TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) {
758  base::MessageLoop message_loop;
759
760  // Simulate having two matches for this origin, one of which was from a form
761  // with different HTML tags for elements. Because of scoring differences,
762  // only the first form will be sent to Autofill().
763  TestPasswordManager password_manager(client());
764  PasswordFormManager manager_match(&password_manager,
765                                    client(),
766                                    client()->GetDriver(),
767                                    *observed_form(),
768                                    false);
769  EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
770      .Times(1);
771  EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
772      .WillRepeatedly(Return(false));
773
774  std::vector<PasswordForm*> results;
775  results.push_back(CreateSavedMatch(false));
776  results.push_back(CreateSavedMatch(false));
777  results[1]->username_value = ASCIIToUTF16("other@gmail.com");
778  results[1]->password_element = ASCIIToUTF16("signup_password");
779  results[1]->username_element = ASCIIToUTF16("signup_username");
780  SimulateFetchMatchingLoginsFromPasswordStore(&manager_match);
781  SimulateResponseFromPasswordStore(&manager_match, results);
782  EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
783  results.clear();
784
785  // Same thing, except this time the credentials that don't match quite as
786  // well are generated. They should now be sent to Autofill().
787  PasswordFormManager manager_no_match(&password_manager,
788                                       client(),
789                                       client()->GetDriver(),
790                                       *observed_form(),
791                                       false);
792  EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
793      .Times(1);
794
795  results.push_back(CreateSavedMatch(false));
796  results.push_back(CreateSavedMatch(false));
797  results[1]->username_value = ASCIIToUTF16("other@gmail.com");
798  results[1]->password_element = ASCIIToUTF16("signup_password");
799  results[1]->username_element = ASCIIToUTF16("signup_username");
800  results[1]->type = PasswordForm::TYPE_GENERATED;
801  SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_match);
802  SimulateResponseFromPasswordStore(&manager_no_match, results);
803  EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size());
804}
805
806TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
807  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
808  PasswordForm credentials(*observed_form());
809  credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
810  credentials.other_possible_usernames.push_back(
811      ASCIIToUTF16("378282246310005"));
812  credentials.other_possible_usernames.push_back(
813      ASCIIToUTF16("other username"));
814  credentials.username_value = ASCIIToUTF16("test@gmail.com");
815
816  SanitizePossibleUsernames(&manager, &credentials);
817
818  // Possible credit card number and SSN are stripped.
819  std::vector<base::string16> expected;
820  expected.push_back(ASCIIToUTF16("other username"));
821  EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
822
823  credentials.other_possible_usernames.clear();
824  credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
825  credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
826  credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
827  credentials.other_possible_usernames.push_back(ASCIIToUTF16("random"));
828  credentials.other_possible_usernames.push_back(
829      ASCIIToUTF16("test@gmail.com"));
830
831  SanitizePossibleUsernames(&manager, &credentials);
832
833  // SSN, duplicate in |other_possible_usernames| and duplicate of
834  // |username_value| all removed.
835  expected.clear();
836  expected.push_back(ASCIIToUTF16("duplicate"));
837  expected.push_back(ASCIIToUTF16("random"));
838  EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
839}
840
841TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
842  InitializeMockStore();
843
844  // We've found this form on a website:
845  PasswordForm encountered_form;
846  encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
847  encountered_form.signon_realm = "http://accounts.google.com/";
848  encountered_form.action = GURL("http://accounts.google.com/Login");
849  encountered_form.username_element = ASCIIToUTF16("Email");
850  encountered_form.password_element = ASCIIToUTF16("Passwd");
851  encountered_form.submit_element = ASCIIToUTF16("signIn");
852
853  TestPasswordManagerClient client_with_store(mock_store());
854  EXPECT_CALL(*(client_with_store.GetMockDriver()), IsOffTheRecord())
855      .WillRepeatedly(Return(false));
856  EXPECT_CALL(*(client_with_store.GetMockDriver()),
857              AllowPasswordGenerationForForm(_));
858
859  TestPasswordManager manager(&client_with_store);
860  PasswordFormManager form_manager(&manager,
861                                   &client_with_store,
862                                   client_with_store.GetMockDriver(),
863                                   encountered_form,
864                                   false);
865
866  const PasswordStore::AuthorizationPromptPolicy auth_policy =
867      PasswordStore::DISALLOW_PROMPT;
868  EXPECT_CALL(*mock_store(),
869              GetLogins(encountered_form, auth_policy, &form_manager));
870  form_manager.FetchMatchingLoginsFromPasswordStore(auth_policy);
871
872  // Password store only has these incomplete credentials.
873  PasswordForm* incomplete_form = new PasswordForm();
874  incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth");
875  incomplete_form->signon_realm = "http://accounts.google.com/";
876  incomplete_form->password_value = ASCIIToUTF16("my_password");
877  incomplete_form->username_value = ASCIIToUTF16("my_username");
878  incomplete_form->preferred = true;
879  incomplete_form->ssl_valid = false;
880  incomplete_form->scheme = PasswordForm::SCHEME_HTML;
881
882  // We expect to see this form eventually sent to the Password store. It
883  // has password/username values from the store and 'username_element',
884  // 'password_element', 'submit_element' and 'action' fields copied from
885  // the encountered form.
886  PasswordForm complete_form(*incomplete_form);
887  complete_form.action = encountered_form.action;
888  complete_form.password_element = encountered_form.password_element;
889  complete_form.username_element = encountered_form.username_element;
890  complete_form.submit_element = encountered_form.submit_element;
891
892  PasswordForm obsolete_form(*incomplete_form);
893  obsolete_form.action = encountered_form.action;
894
895  // Feed the incomplete credentials to the manager.
896  std::vector<PasswordForm*> results;
897  results.push_back(incomplete_form);  // Takes ownership.
898  form_manager.OnRequestDone(results);
899
900  form_manager.ProvisionallySave(
901      complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
902  // By now that form has been used once.
903  complete_form.times_used = 1;
904  obsolete_form.times_used = 1;
905
906  // Check that PasswordStore receives an update request with the complete form.
907  EXPECT_CALL(*mock_store(), RemoveLogin(obsolete_form));
908  EXPECT_CALL(*mock_store(), AddLogin(complete_form));
909  form_manager.Save();
910}
911
912TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) {
913  base::MessageLoop message_loop;
914
915  EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
916      .WillRepeatedly(Return(false));
917  EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_));
918
919  TestPasswordManager password_manager(client());
920  PasswordFormManager manager(&password_manager,
921                              client(),
922                              client()->GetMockDriver(),
923                              *observed_form(),
924                              false);
925
926  // Simulate having two matches for this form, first comes from different
927  // signon realm, but reports the same origin and action as matched form.
928  // Second candidate has the same signon realm as the form, but has a different
929  // origin and action. Public suffix match is the most important criterion so
930  // the second candidate should be selected.
931  std::vector<PasswordForm*> results;
932  results.push_back(CreateSavedMatch(false));
933  results.push_back(CreateSavedMatch(false));
934  results[0]->original_signon_realm = "http://accounts2.google.com";
935  results[1]->origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2");
936  results[1]->action = GURL("http://accounts.google.com/a/ServiceLogin2");
937  SimulateFetchMatchingLoginsFromPasswordStore(&manager);
938  SimulateResponseFromPasswordStore(&manager, results);
939  EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
940  EXPECT_EQ("", password_manager.GetLatestBestMatches().begin()
941      ->second->original_signon_realm);
942}
943
944TEST_F(PasswordFormManagerTest, InvalidActionURLsDoNotMatch) {
945  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
946
947  PasswordForm invalid_action_form(*observed_form());
948  invalid_action_form.action = GURL("http://");
949  ASSERT_FALSE(invalid_action_form.action.is_valid());
950  ASSERT_FALSE(invalid_action_form.action.is_empty());
951  // Non-empty invalid action URLs should not match other actions.
952  // First when the compared form has an invalid URL:
953  EXPECT_EQ(0,
954            manager.DoesManage(invalid_action_form) &
955                PasswordFormManager::RESULT_ACTION_MATCH);
956  // Then when the observed form has an invalid URL:
957  PasswordForm valid_action_form(*observed_form());
958  PasswordFormManager invalid_manager(
959      NULL, client(), NULL, invalid_action_form, false);
960  EXPECT_EQ(0,
961            invalid_manager.DoesManage(valid_action_form) &
962                PasswordFormManager::RESULT_ACTION_MATCH);
963}
964
965TEST_F(PasswordFormManagerTest, EmptyActionURLsDoNotMatchNonEmpty) {
966  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
967
968  PasswordForm empty_action_form(*observed_form());
969  empty_action_form.action = GURL();
970  ASSERT_FALSE(empty_action_form.action.is_valid());
971  ASSERT_TRUE(empty_action_form.action.is_empty());
972  // First when the compared form has an empty URL:
973  EXPECT_EQ(0,
974            manager.DoesManage(empty_action_form) &
975                PasswordFormManager::RESULT_ACTION_MATCH);
976  // Then when the observed form has an empty URL:
977  PasswordForm valid_action_form(*observed_form());
978  PasswordFormManager empty_action_manager(
979      NULL, client(), NULL, empty_action_form, false);
980  EXPECT_EQ(0,
981            empty_action_manager.DoesManage(valid_action_form) &
982                PasswordFormManager::RESULT_ACTION_MATCH);
983}
984
985TEST_F(PasswordFormManagerTest, NonHTMLFormsDoNotMatchHTMLForms) {
986  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
987
988  ASSERT_EQ(PasswordForm::SCHEME_HTML, observed_form()->scheme);
989  PasswordForm non_html_form(*observed_form());
990  non_html_form.scheme = PasswordForm::SCHEME_DIGEST;
991  EXPECT_EQ(0,
992            manager.DoesManage(non_html_form) &
993                PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
994
995  // The other way round: observing a non-HTML form, don't match a HTML form.
996  PasswordForm html_form(*observed_form());
997  PasswordFormManager non_html_manager(
998      NULL, client(), NULL, non_html_form, false);
999  EXPECT_EQ(0,
1000            non_html_manager.DoesManage(html_form) &
1001                PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1002}
1003
1004TEST_F(PasswordFormManagerTest, OriginCheck_HostsMatchExactly) {
1005  // Host part of origins must match exactly, not just by prefix.
1006  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1007
1008  PasswordForm form_longer_host(*observed_form());
1009  form_longer_host.origin = GURL("http://accounts.google.com.au/a/LoginAuth");
1010  // Check that accounts.google.com does not match accounts.google.com.au.
1011  EXPECT_EQ(0,
1012            manager.DoesManage(form_longer_host) &
1013                PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1014}
1015
1016TEST_F(PasswordFormManagerTest, OriginCheck_MoreSecureSchemePathsMatchPrefix) {
1017  // If the URL scheme of the observed form is HTTP, and the compared form is
1018  // HTTPS, then the compared form can extend the path.
1019  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1020
1021  PasswordForm form_longer_path(*observed_form());
1022  form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
1023  EXPECT_NE(0,
1024            manager.DoesManage(form_longer_path) &
1025                PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1026}
1027
1028TEST_F(PasswordFormManagerTest,
1029       OriginCheck_NotMoreSecureSchemePathsMatchExactly) {
1030  // If the origin URL scheme of the compared form is not more secure than that
1031  // of the observed form, then the paths must match exactly.
1032  PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1033
1034  PasswordForm form_longer_path(*observed_form());
1035  form_longer_path.origin = GURL("http://accounts.google.com/a/LoginAuth/sec");
1036  // Check that /a/LoginAuth does not match /a/LoginAuth/more.
1037  EXPECT_EQ(0,
1038            manager.DoesManage(form_longer_path) &
1039                PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1040
1041  PasswordForm secure_observed_form(*observed_form());
1042  secure_observed_form.origin = GURL("https://accounts.google.com/a/LoginAuth");
1043  PasswordFormManager secure_manager(
1044      NULL, client(), NULL, secure_observed_form, true);
1045  // Also for HTTPS in the observed form, and HTTP in the compared form, an
1046  // exact path match is expected.
1047  EXPECT_EQ(0,
1048            secure_manager.DoesManage(form_longer_path) &
1049                PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1050  // Not even upgrade to HTTPS in the compared form should help.
1051  form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
1052  EXPECT_EQ(0,
1053            secure_manager.DoesManage(form_longer_path) &
1054                PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1055}
1056
1057TEST_F(PasswordFormManagerTest, CorrectlyUpdatePasswordsWithSameUsername) {
1058  // Need a MessageLoop for callbacks.
1059  base::MessageLoop message_loop;
1060  scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
1061  CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
1062
1063  TestPasswordManagerClient client_with_store(password_store.get());
1064  TestPasswordManager password_manager(&client_with_store);
1065  EXPECT_CALL(*client_with_store.GetMockDriver(),
1066              AllowPasswordGenerationForForm(_)).Times(2);
1067  EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1068      .WillRepeatedly(Return(false));
1069
1070  // Add two credentials with the same username. Both should score the same
1071  // and be seen as candidates to autofill.
1072  PasswordForm first(*saved_match());
1073  first.action = observed_form()->action;
1074  first.password_value = ASCIIToUTF16("first");
1075  password_store->AddLogin(first);
1076
1077  PasswordForm second(first);
1078  second.origin = GURL("http://accounts.google.com/a/AddLogin");
1079  second.password_value = ASCIIToUTF16("second");
1080  second.preferred = false;
1081  password_store->AddLogin(second);
1082
1083  PasswordFormManager storing_manager(&password_manager,
1084                                      &client_with_store,
1085                                      client_with_store.GetDriver(),
1086                                      *observed_form(),
1087                                      false);
1088  storing_manager.FetchMatchingLoginsFromPasswordStore(
1089      PasswordStore::ALLOW_PROMPT);
1090  RunAllPendingTasks();
1091
1092  // We always take the last credential with a particular username, regardless
1093  // of which ones are labeled preferred.
1094  EXPECT_EQ(ASCIIToUTF16("second"),
1095            storing_manager.preferred_match()->password_value);
1096
1097  PasswordForm login(*observed_form());
1098  login.username_value = saved_match()->username_value;
1099  login.password_value = ASCIIToUTF16("third");
1100  login.preferred = true;
1101  storing_manager.ProvisionallySave(
1102      login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1103
1104  EXPECT_FALSE(storing_manager.IsNewLogin());
1105  storing_manager.Save();
1106  RunAllPendingTasks();
1107
1108  PasswordFormManager retrieving_manager(&password_manager,
1109                                         &client_with_store,
1110                                         client_with_store.GetDriver(),
1111                                         *observed_form(),
1112                                         false);
1113
1114  retrieving_manager.FetchMatchingLoginsFromPasswordStore(
1115      PasswordStore::ALLOW_PROMPT);
1116  RunAllPendingTasks();
1117
1118  // Make sure that the preferred match is updated appropriately.
1119  EXPECT_EQ(ASCIIToUTF16("third"),
1120            retrieving_manager.preferred_match()->password_value);
1121  password_store->Shutdown();
1122}
1123
1124TEST_F(PasswordFormManagerTest, UploadFormData_NewPassword) {
1125  InitializeMockStore();
1126  TestPasswordManagerClient client_with_store(mock_store());
1127  TestPasswordManager password_manager(&client_with_store);
1128  EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1129      .WillRepeatedly(Return(false));
1130
1131  PasswordForm form(*observed_form());
1132
1133  autofill::FormFieldData field;
1134  field.label = ASCIIToUTF16("full_name");
1135  field.name = ASCIIToUTF16("full_name");
1136  field.form_control_type = "text";
1137  form.form_data.fields.push_back(field);
1138
1139  field.label = ASCIIToUTF16("Email");
1140  field.name = ASCIIToUTF16("Email");
1141  field.form_control_type = "text";
1142  form.form_data.fields.push_back(field);
1143
1144  field.label = ASCIIToUTF16("password");
1145  field.name = ASCIIToUTF16("password");
1146  field.form_control_type = "password";
1147  form.form_data.fields.push_back(field);
1148
1149  // For newly saved passwords, upload a vote for autofill::PASSWORD.
1150  MockPasswordFormManager form_manager(&password_manager,
1151                                       &client_with_store,
1152                                       client_with_store.GetDriver(),
1153                                       form,
1154                                       false);
1155  SimulateMatchingPhase(&form_manager, RESULT_NO_MATCH);
1156
1157  PasswordForm form_to_save(form);
1158  form_to_save.preferred = true;
1159  form_to_save.username_value = ASCIIToUTF16("username");
1160  form_to_save.password_value = ASCIIToUTF16("1234");
1161
1162  EXPECT_CALL(form_manager, UploadPasswordForm(_, autofill::PASSWORD)).Times(1);
1163  form_manager.ProvisionallySave(
1164      form_to_save,
1165      PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1166  form_manager.Save();
1167  Mock::VerifyAndClearExpectations(&form_manager);
1168
1169  // Do not upload a vote if the user is blacklisting the form.
1170  MockPasswordFormManager blacklist_form_manager(&password_manager,
1171                                                 &client_with_store,
1172                                                 client_with_store.GetDriver(),
1173                                                 form,
1174                                                 false);
1175  SimulateMatchingPhase(&blacklist_form_manager, RESULT_NO_MATCH);
1176
1177  EXPECT_CALL(blacklist_form_manager,
1178              UploadPasswordForm(_, autofill::PASSWORD)).Times(0);
1179  blacklist_form_manager.PermanentlyBlacklist();
1180  Mock::VerifyAndClearExpectations(&blacklist_form_manager);
1181}
1182
1183TEST_F(PasswordFormManagerTest, UploadFormData_AccountCreationPassword) {
1184  InitializeMockStore();
1185  TestPasswordManagerClient client_with_store(mock_store());
1186  TestPasswordManager password_manager(&client_with_store);
1187  EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1188      .WillRepeatedly(Return(false));
1189
1190  PasswordForm form(*observed_form());
1191
1192  autofill::FormFieldData field;
1193  field.label = ASCIIToUTF16("Email");
1194  field.name = ASCIIToUTF16("Email");
1195  field.form_control_type = "text";
1196  form.form_data.fields.push_back(field);
1197
1198  field.label = ASCIIToUTF16("password");
1199  field.name = ASCIIToUTF16("password");
1200  field.form_control_type = "password";
1201  form.form_data.fields.push_back(field);
1202
1203  MockPasswordFormManager form_manager(&password_manager,
1204                                       &client_with_store,
1205                                       client_with_store.GetDriver(),
1206                                       form,
1207                                       false);
1208  std::vector<PasswordForm*> result;
1209  result.push_back(CreateSavedMatch(false));
1210
1211  field.label = ASCIIToUTF16("full_name");
1212  field.name = ASCIIToUTF16("full_name");
1213  field.form_control_type = "text";
1214  result[0]->form_data.fields.push_back(field);
1215
1216  field.label = ASCIIToUTF16("Email");
1217  field.name = ASCIIToUTF16("Email");
1218  field.form_control_type = "text";
1219  result[0]->form_data.fields.push_back(field);
1220
1221  field.label = ASCIIToUTF16("password");
1222  field.name = ASCIIToUTF16("password");
1223  field.form_control_type = "password";
1224  result[0]->form_data.fields.push_back(field);
1225
1226  PasswordForm form_to_save(form);
1227  form_to_save.preferred = true;
1228  form_to_save.username_value = result[0]->username_value;
1229  form_to_save.password_value = result[0]->password_value;
1230
1231  SimulateFetchMatchingLoginsFromPasswordStore(&form_manager);
1232  SimulateResponseFromPasswordStore(&form_manager, result);
1233
1234  EXPECT_CALL(form_manager,
1235              UploadPasswordForm(_,
1236                                 autofill::ACCOUNT_CREATION_PASSWORD)).Times(1);
1237  form_manager.ProvisionallySave(
1238      form_to_save,
1239      PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1240  form_manager.Save();
1241}
1242
1243TEST_F(PasswordFormManagerTest, CorrectlySavePasswordWithoutUsernameFields) {
1244  // Need a MessageLoop for callbacks.
1245  base::MessageLoop message_loop;
1246  scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
1247  CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
1248
1249  TestPasswordManagerClient client_with_store(password_store.get());
1250  TestPasswordManager password_manager(&client_with_store);
1251  EXPECT_CALL(*client_with_store.GetMockDriver(),
1252              AllowPasswordGenerationForForm(_)).Times(2);
1253  EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1254      .WillRepeatedly(Return(false));
1255
1256  PasswordForm form(*observed_form());
1257  form.username_element.clear();
1258  form.password_value = ASCIIToUTF16("password");
1259  form.preferred = true;
1260
1261  PasswordFormManager storing_manager(&password_manager,
1262                                      &client_with_store,
1263                                      client_with_store.GetDriver(),
1264                                      *observed_form(),
1265                                      false);
1266  storing_manager.FetchMatchingLoginsFromPasswordStore(
1267      PasswordStore::ALLOW_PROMPT);
1268  RunAllPendingTasks();
1269
1270  storing_manager.ProvisionallySave(
1271      form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1272
1273  EXPECT_TRUE(storing_manager.IsNewLogin());
1274  storing_manager.Save();
1275  RunAllPendingTasks();
1276
1277  PasswordFormManager retrieving_manager(&password_manager,
1278                                         &client_with_store,
1279                                         client_with_store.GetDriver(),
1280                                         *observed_form(),
1281                                         false);
1282
1283  retrieving_manager.FetchMatchingLoginsFromPasswordStore(
1284      PasswordStore::ALLOW_PROMPT);
1285  RunAllPendingTasks();
1286
1287  // Make sure that the preferred match is updated appropriately.
1288  EXPECT_EQ(ASCIIToUTF16("password"),
1289            retrieving_manager.preferred_match()->password_value);
1290  password_store->Shutdown();
1291}
1292
1293}  // namespace password_manager
1294