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