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