summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/test/integration/passwords_helper.cc
blob: e54d89d7695f517eb0ea5716f3cf3d1b3299a1c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync/test/integration/passwords_helper.h"

#include "base/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/password_manager/password_form_data.h"
#include "chrome/browser/password_manager/password_store.h"
#include "chrome/browser/password_manager/password_store_consumer.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/sync_datatype_helper.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"

using content::PasswordForm;
using sync_datatype_helper::test;

const std::string kFakeSignonRealm = "http://fake-signon-realm.google.com/";
const char* kIndexedFakeOrigin = "http://fake-signon-realm.google.com/%d";

namespace {

// We use a WaitableEvent to wait when logins are added, removed, or updated
// instead of running the UI message loop because of a restriction that
// prevents a DB thread from initiating a quit of the UI message loop.
void PasswordStoreCallback(base::WaitableEvent* wait_event) {
  // Wake up passwords_helper::AddLogin.
  wait_event->Signal();
}

class PasswordStoreConsumerHelper : public PasswordStoreConsumer {
 public:
  explicit PasswordStoreConsumerHelper(std::vector<PasswordForm>* result)
      : PasswordStoreConsumer(),
        result_(result) {}

  virtual void OnPasswordStoreRequestDone(
      CancelableRequestProvider::Handle handle,
      const std::vector<PasswordForm*>& result) {
    result_->clear();
    for (std::vector<PasswordForm*>::const_iterator it = result.begin();
         it != result.end(); ++it) {
      // Make a copy of the form since it gets deallocated after the caller of
      // this method returns.
      result_->push_back(**it);
    }

    // Quit the message loop to wake up passwords_helper::GetLogins.
    MessageLoopForUI::current()->Quit();
  }

 private:
  std::vector<PasswordForm>* result_;

  DISALLOW_COPY_AND_ASSIGN(PasswordStoreConsumerHelper);
};

}  // namespace

namespace passwords_helper {

void AddLogin(PasswordStore* store, const PasswordForm& form) {
  ASSERT_TRUE(store);
  base::WaitableEvent wait_event(true, false);
  store->AddLogin(form);
  store->ScheduleTask(base::Bind(&PasswordStoreCallback, &wait_event));
  wait_event.Wait();
}

void UpdateLogin(PasswordStore* store, const PasswordForm& form) {
  ASSERT_TRUE(store);
  base::WaitableEvent wait_event(true, false);
  store->UpdateLogin(form);
  store->ScheduleTask(base::Bind(&PasswordStoreCallback, &wait_event));
  wait_event.Wait();
}

void GetLogins(PasswordStore* store, std::vector<PasswordForm>& matches) {
  ASSERT_TRUE(store);
  PasswordForm matcher_form;
  matcher_form.signon_realm = kFakeSignonRealm;
  PasswordStoreConsumerHelper consumer(&matches);
  store->GetLogins(matcher_form, &consumer);
  content::RunMessageLoop();
}

void RemoveLogin(PasswordStore* store, const PasswordForm& form) {
  ASSERT_TRUE(store);
  base::WaitableEvent wait_event(true, false);
  store->RemoveLogin(form);
  store->ScheduleTask(base::Bind(&PasswordStoreCallback, &wait_event));
  wait_event.Wait();
}

void RemoveLogins(PasswordStore* store) {
  std::vector<PasswordForm> forms;
  GetLogins(store, forms);
  for (std::vector<PasswordForm>::iterator it = forms.begin();
       it != forms.end(); ++it) {
    RemoveLogin(store, *it);
  }
}

void SetEncryptionPassphrase(int index,
                             const std::string& passphrase,
                             ProfileSyncService::PassphraseType type) {
  ProfileSyncServiceFactory::GetForProfile(
      test()->GetProfile(index))->SetEncryptionPassphrase(passphrase, type);
}

bool SetDecryptionPassphrase(int index, const std::string& passphrase) {
  return ProfileSyncServiceFactory::GetForProfile(
      test()->GetProfile(index))->SetDecryptionPassphrase(passphrase);
}

PasswordStore* GetPasswordStore(int index) {
  return PasswordStoreFactory::GetForProfile(test()->GetProfile(index),
                                             Profile::IMPLICIT_ACCESS);
}

PasswordStore* GetVerifierPasswordStore() {
  return PasswordStoreFactory::GetForProfile(test()->verifier(),
                                             Profile::IMPLICIT_ACCESS);
}

bool ProfileContainsSamePasswordFormsAsVerifier(int index) {
  std::vector<PasswordForm> verifier_forms;
  std::vector<PasswordForm> forms;
  GetLogins(GetVerifierPasswordStore(), verifier_forms);
  GetLogins(GetPasswordStore(index), forms);
  bool result = ContainsSamePasswordForms(verifier_forms, forms);
  if (!result) {
    LOG(ERROR) << "Password forms in Verifier Profile:";
    for (std::vector<PasswordForm>::iterator it = verifier_forms.begin();
         it != verifier_forms.end(); ++it) {
      LOG(ERROR) << *it << std::endl;
    }
    LOG(ERROR) << "Password forms in Profile" << index << ":";
    for (std::vector<PasswordForm>::iterator it = forms.begin();
         it != forms.end(); ++it) {
      LOG(ERROR) << *it << std::endl;
    }
  }
  return result;
}

bool ProfilesContainSamePasswordForms(int index_a, int index_b) {
  std::vector<PasswordForm> forms_a;
  std::vector<PasswordForm> forms_b;
  GetLogins(GetPasswordStore(index_a), forms_a);
  GetLogins(GetPasswordStore(index_b), forms_b);
  bool result = ContainsSamePasswordForms(forms_a, forms_b);
  if (!result) {
    LOG(ERROR) << "Password forms in Profile" << index_a << ":";
    for (std::vector<PasswordForm>::iterator it = forms_a.begin();
         it != forms_a.end(); ++it) {
      LOG(ERROR) << *it << std::endl;
    }
    LOG(ERROR) << "Password forms in Profile" << index_b << ":";
    for (std::vector<PasswordForm>::iterator it = forms_b.begin();
         it != forms_b.end(); ++it) {
      LOG(ERROR) << *it << std::endl;
    }
  }
  return result;
}

bool AllProfilesContainSamePasswordFormsAsVerifier() {
  for (int i = 0; i < test()->num_clients(); ++i) {
    if (!ProfileContainsSamePasswordFormsAsVerifier(i)) {
      LOG(ERROR) << "Profile " << i << " does not contain the same password"
                                       " forms as the verifier.";
      return false;
    }
  }
  return true;
}

bool AllProfilesContainSamePasswordForms() {
  for (int i = 1; i < test()->num_clients(); ++i) {
    if (!ProfilesContainSamePasswordForms(0, i)) {
      LOG(ERROR) << "Profile " << i << " does not contain the same password"
                                       " forms as Profile 0.";
      return false;
    }
  }
  return true;
}

int GetPasswordCount(int index) {
  std::vector<PasswordForm> forms;
  GetLogins(GetPasswordStore(index), forms);
  return forms.size();
}

int GetVerifierPasswordCount() {
  std::vector<PasswordForm> verifier_forms;
  GetLogins(GetVerifierPasswordStore(), verifier_forms);
  return verifier_forms.size();
}

PasswordForm CreateTestPasswordForm(int index) {
  PasswordForm form;
  form.signon_realm = kFakeSignonRealm;
  form.origin = GURL(base::StringPrintf(kIndexedFakeOrigin, index));
  form.username_value = ASCIIToUTF16(base::StringPrintf("username%d", index));
  form.password_value = ASCIIToUTF16(base::StringPrintf("password%d", index));
  form.date_created = base::Time::Now();
  return form;
}

}  // namespace passwords_helper