passwords_helper.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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.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 base::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).get(); 132} 133 134PasswordStore* GetVerifierPasswordStore() { 135 return PasswordStoreFactory::GetForProfile(test()->verifier(), 136 Profile::IMPLICIT_ACCESS).get(); 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