passwords_helper.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
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 "chrome/browser/sync/test/integration/passwords_helper.h"
6
7#include "base/compiler_specific.h"
8#include "base/strings/stringprintf.h"
9#include "base/strings/utf_string_conversions.h"
10#include "base/synchronization/waitable_event.h"
11#include "base/time/time.h"
12#include "chrome/browser/password_manager/password_store_factory.h"
13#include "chrome/browser/sync/profile_sync_service.h"
14#include "chrome/browser/sync/profile_sync_service_factory.h"
15#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
16#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
17#include "chrome/test/base/ui_test_utils.h"
18#include "components/password_manager/core/browser/password_form_data.h"
19#include "components/password_manager/core/browser/password_store.h"
20#include "components/password_manager/core/browser/password_store_consumer.h"
21
22using autofill::PasswordForm;
23using password_manager::PasswordStore;
24using sync_datatype_helper::test;
25
26const std::string kFakeSignonRealm = "http://fake-signon-realm.google.com/";
27const char* kIndexedFakeOrigin = "http://fake-signon-realm.google.com/%d";
28
29namespace {
30
31// We use a WaitableEvent to wait when logins are added, removed, or updated
32// instead of running the UI message loop because of a restriction that
33// prevents a DB thread from initiating a quit of the UI message loop.
34void PasswordStoreCallback(base::WaitableEvent* wait_event) {
35  // Wake up passwords_helper::AddLogin.
36  wait_event->Signal();
37}
38
39class PasswordStoreConsumerHelper
40    : public password_manager::PasswordStoreConsumer {
41 public:
42  explicit PasswordStoreConsumerHelper(std::vector<PasswordForm>* result)
43      : password_manager::PasswordStoreConsumer(), result_(result) {}
44
45  virtual void OnGetPasswordStoreResults(
46      const std::vector<PasswordForm*>& result) OVERRIDE {
47    result_->clear();
48    for (std::vector<PasswordForm*>::const_iterator it = result.begin();
49         it != result.end();
50         ++it) {
51      result_->push_back(**it);
52      delete *it;
53    }
54
55    // Quit the message loop to wake up passwords_helper::GetLogins.
56    base::MessageLoopForUI::current()->Quit();
57  }
58
59 private:
60  std::vector<PasswordForm>* result_;
61
62  DISALLOW_COPY_AND_ASSIGN(PasswordStoreConsumerHelper);
63};
64
65}  // namespace
66
67namespace passwords_helper {
68
69void AddLogin(PasswordStore* store, const PasswordForm& form) {
70  ASSERT_TRUE(store);
71  base::WaitableEvent wait_event(true, false);
72  store->AddLogin(form);
73  store->ScheduleTask(base::Bind(&PasswordStoreCallback, &wait_event));
74  wait_event.Wait();
75}
76
77void UpdateLogin(PasswordStore* store, const PasswordForm& form) {
78  ASSERT_TRUE(store);
79  base::WaitableEvent wait_event(true, false);
80  store->UpdateLogin(form);
81  store->ScheduleTask(base::Bind(&PasswordStoreCallback, &wait_event));
82  wait_event.Wait();
83}
84
85void GetLogins(PasswordStore* store, std::vector<PasswordForm>& matches) {
86  ASSERT_TRUE(store);
87  PasswordForm matcher_form;
88  matcher_form.signon_realm = kFakeSignonRealm;
89  PasswordStoreConsumerHelper consumer(&matches);
90  store->GetLogins(matcher_form, PasswordStore::DISALLOW_PROMPT, &consumer);
91  content::RunMessageLoop();
92}
93
94void RemoveLogin(PasswordStore* store, const PasswordForm& form) {
95  ASSERT_TRUE(store);
96  base::WaitableEvent wait_event(true, false);
97  store->RemoveLogin(form);
98  store->ScheduleTask(base::Bind(&PasswordStoreCallback, &wait_event));
99  wait_event.Wait();
100}
101
102void RemoveLogins(PasswordStore* store) {
103  std::vector<PasswordForm> forms;
104  GetLogins(store, forms);
105  for (std::vector<PasswordForm>::iterator it = forms.begin();
106       it != forms.end(); ++it) {
107    RemoveLogin(store, *it);
108  }
109}
110
111void SetEncryptionPassphrase(int index,
112                             const std::string& passphrase,
113                             ProfileSyncService::PassphraseType type) {
114  ProfileSyncServiceFactory::GetForProfile(
115      test()->GetProfile(index))->SetEncryptionPassphrase(passphrase, type);
116}
117
118bool SetDecryptionPassphrase(int index, const std::string& passphrase) {
119  return ProfileSyncServiceFactory::GetForProfile(
120      test()->GetProfile(index))->SetDecryptionPassphrase(passphrase);
121}
122
123PasswordStore* GetPasswordStore(int index) {
124  return PasswordStoreFactory::GetForProfile(test()->GetProfile(index),
125                                             Profile::IMPLICIT_ACCESS).get();
126}
127
128PasswordStore* GetVerifierPasswordStore() {
129  return PasswordStoreFactory::GetForProfile(test()->verifier(),
130                                             Profile::IMPLICIT_ACCESS).get();
131}
132
133bool ProfileContainsSamePasswordFormsAsVerifier(int index) {
134  std::vector<PasswordForm> verifier_forms;
135  std::vector<PasswordForm> forms;
136  GetLogins(GetVerifierPasswordStore(), verifier_forms);
137  GetLogins(GetPasswordStore(index), forms);
138  bool result =
139      password_manager::ContainsSamePasswordForms(verifier_forms, forms);
140  if (!result) {
141    LOG(ERROR) << "Password forms in Verifier Profile:";
142    for (std::vector<PasswordForm>::iterator it = verifier_forms.begin();
143         it != verifier_forms.end(); ++it) {
144      LOG(ERROR) << *it << std::endl;
145    }
146    LOG(ERROR) << "Password forms in Profile" << index << ":";
147    for (std::vector<PasswordForm>::iterator it = forms.begin();
148         it != forms.end(); ++it) {
149      LOG(ERROR) << *it << std::endl;
150    }
151  }
152  return result;
153}
154
155bool ProfilesContainSamePasswordForms(int index_a, int index_b) {
156  std::vector<PasswordForm> forms_a;
157  std::vector<PasswordForm> forms_b;
158  GetLogins(GetPasswordStore(index_a), forms_a);
159  GetLogins(GetPasswordStore(index_b), forms_b);
160  bool result = password_manager::ContainsSamePasswordForms(forms_a, forms_b);
161  if (!result) {
162    LOG(ERROR) << "Password forms in Profile" << index_a << ":";
163    for (std::vector<PasswordForm>::iterator it = forms_a.begin();
164         it != forms_a.end(); ++it) {
165      LOG(ERROR) << *it << std::endl;
166    }
167    LOG(ERROR) << "Password forms in Profile" << index_b << ":";
168    for (std::vector<PasswordForm>::iterator it = forms_b.begin();
169         it != forms_b.end(); ++it) {
170      LOG(ERROR) << *it << std::endl;
171    }
172  }
173  return result;
174}
175
176bool AllProfilesContainSamePasswordFormsAsVerifier() {
177  for (int i = 0; i < test()->num_clients(); ++i) {
178    if (!ProfileContainsSamePasswordFormsAsVerifier(i)) {
179      LOG(ERROR) << "Profile " << i << " does not contain the same password"
180                                       " forms as the verifier.";
181      return false;
182    }
183  }
184  return true;
185}
186
187bool AllProfilesContainSamePasswordForms() {
188  for (int i = 1; i < test()->num_clients(); ++i) {
189    if (!ProfilesContainSamePasswordForms(0, i)) {
190      LOG(ERROR) << "Profile " << i << " does not contain the same password"
191                                       " forms as Profile 0.";
192      return false;
193    }
194  }
195  return true;
196}
197
198int GetPasswordCount(int index) {
199  std::vector<PasswordForm> forms;
200  GetLogins(GetPasswordStore(index), forms);
201  return forms.size();
202}
203
204int GetVerifierPasswordCount() {
205  std::vector<PasswordForm> verifier_forms;
206  GetLogins(GetVerifierPasswordStore(), verifier_forms);
207  return verifier_forms.size();
208}
209
210PasswordForm CreateTestPasswordForm(int index) {
211  PasswordForm form;
212  form.signon_realm = kFakeSignonRealm;
213  form.origin = GURL(base::StringPrintf(kIndexedFakeOrigin, index));
214  form.username_value =
215      base::ASCIIToUTF16(base::StringPrintf("username%d", index));
216  form.password_value =
217      base::ASCIIToUTF16(base::StringPrintf("password%d", index));
218  form.date_created = base::Time::Now();
219  return form;
220}
221
222}  // namespace passwords_helper
223