password_store.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/password_manager/core/browser/password_store.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/dump_without_crashing.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/stl_util.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/autofill/core/common/password_form.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/password_manager/core/browser/password_store_consumer.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/password_manager/core/browser/password_syncable_service.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(PASSWORD_MANAGER_ENABLE_SYNC) 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "components/password_manager/core/browser/password_syncable_service.h" 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using autofill::PasswordForm; 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace password_manager { 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Calls |consumer| back with the request result, if |consumer| is still alive. 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Takes ownership of the elements in |result|, passing ownership to |consumer| 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// if it is still alive. 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MaybeCallConsumerCallback(base::WeakPtr<PasswordStoreConsumer> consumer, 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<std::vector<PasswordForm*> > result) { 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (consumer.get()) 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumer->OnGetPasswordStoreResults(*result); 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) STLDeleteElements(result.get()); 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// http://crbug.com/404012. Let's see where the empty fields come from. 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid CheckForEmptyUsernameAndPassword(const PasswordForm& form) { 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (form.username_value.empty() && 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci form.password_value.empty() && 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !form.blacklisted_by_user) 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::debug::DumpWithoutCrashing(); 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PasswordStore::GetLoginsRequest::GetLoginsRequest( 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordStoreConsumer* consumer) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : consumer_weak_(consumer->GetWeakPtr()), 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result_(new std::vector<PasswordForm*>()) { 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) origin_loop_ = base::MessageLoopProxy::current(); 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PasswordStore::GetLoginsRequest::~GetLoginsRequest() { 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::GetLoginsRequest::ApplyIgnoreLoginsCutoff() { 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ignore_logins_cutoff_.is_null()) { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Count down rather than up since we may be deleting elements. 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note that in principle it could be more efficient to copy the whole array 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // since that's worst-case linear time, but we expect that elements will be 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // deleted rarely and lists will be small, so this avoids the copies. 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = result_->size(); i > 0; --i) { 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((*result_)[i - 1]->date_created < ignore_logins_cutoff_) { 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete (*result_)[i - 1]; 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result_->erase(result_->begin() + (i - 1)); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::GetLoginsRequest::ForwardResult() { 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) origin_loop_->PostTask(FROM_HERE, 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&MaybeCallConsumerCallback, 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumer_weak_, 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Passed(result_.Pass()))); 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PasswordStore::PasswordStore( 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : main_thread_runner_(main_thread_runner), 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) db_thread_runner_(db_thread_runner), 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) observers_(new ObserverListThreadSafe<Observer>()), 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shutdown_called_(false) {} 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool PasswordStore::Init(const syncer::SyncableService::StartSyncFlare& flare, 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& sync_username) { 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReportMetrics(sync_username); 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(PASSWORD_MANAGER_ENABLE_SYNC) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScheduleTask(base::Bind(&PasswordStore::InitSyncableService, this, flare)); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::AddLogin(const PasswordForm& form) { 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CheckForEmptyUsernameAndPassword(form); 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScheduleTask( 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PasswordStore::WrapModificationTask, this, 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PasswordStore::AddLoginImpl, this, form))); 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::UpdateLogin(const PasswordForm& form) { 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CheckForEmptyUsernameAndPassword(form); 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScheduleTask( 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PasswordStore::WrapModificationTask, this, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PasswordStore::UpdateLoginImpl, this, form))); 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::RemoveLogin(const PasswordForm& form) { 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScheduleTask( 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PasswordStore::WrapModificationTask, this, 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PasswordStore::RemoveLoginImpl, this, form))); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void PasswordStore::RemoveLoginsCreatedBetween(base::Time delete_begin, 1206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) base::Time delete_end) { 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScheduleTask( 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PasswordStore::WrapModificationTask, this, 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PasswordStore::RemoveLoginsCreatedBetweenImpl, 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, delete_begin, delete_end))); 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void PasswordStore::RemoveLoginsSyncedBetween(base::Time delete_begin, 128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Time delete_end) { 129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ScheduleTask( 130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&PasswordStore::WrapModificationTask, 131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this, 132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Bind(&PasswordStore::RemoveLoginsSyncedBetweenImpl, 133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this, 134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) delete_begin, 135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) delete_end))); 136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::GetLogins( 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const PasswordForm& form, 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AuthorizationPromptPolicy prompt_policy, 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordStoreConsumer* consumer) { 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Per http://crbug.com/121738, we deliberately ignore saved logins for 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // http*://www.google.com/ that were stored prior to 2012. (Google now uses 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // https://accounts.google.com/ for all login forms, so these should be 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // unused.) We don't delete them just yet, and they'll still be visible in the 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // password manager, but we won't use them to autofill any forms. This is a 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // security feature to help minimize damage that can be done by XSS attacks. 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(mdm): actually delete them at some point, say M24 or so. 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time ignore_logins_cutoff; // the null time 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (form.scheme == PasswordForm::SCHEME_HTML && 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (form.signon_realm == "http://www.google.com" || 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) form.signon_realm == "http://www.google.com/" || 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) form.signon_realm == "https://www.google.com" || 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) form.signon_realm == "https://www.google.com/")) { 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const base::Time::Exploded exploded_cutoff = 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { 2012, 1, 0, 1, 0, 0, 0, 0 }; // 00:00 Jan 1 2012 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff); 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetLoginsRequest* request = new GetLoginsRequest(consumer); 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->set_ignore_logins_cutoff(ignore_logins_cutoff); 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ConsumerCallbackRunner callback_runner = 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&PasswordStore::CopyAndForwardLoginsResult, 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, base::Owned(request)); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScheduleTask(base::Bind(&PasswordStore::GetLoginsImpl, 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, form, prompt_policy, callback_runner)); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::GetAutofillableLogins(PasswordStoreConsumer* consumer) { 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::GetBlacklistLogins(PasswordStoreConsumer* consumer) { 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 177116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid PasswordStore::ReportMetrics(const std::string& sync_username) { 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScheduleTask(base::Bind(&PasswordStore::ReportMetricsImpl, this, 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch sync_username)); 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::AddObserver(Observer* observer) { 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) observers_->AddObserver(observer); 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::RemoveObserver(Observer* observer) { 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) observers_->RemoveObserver(observer); 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool PasswordStore::ScheduleTask(const base::Closure& task) { 191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> task_runner( 192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetBackgroundTaskRunner()); 193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (task_runner.get()) 194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return task_runner->PostTask(FROM_HERE, task); 195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return false; 196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PasswordStore::Shutdown() { 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(PASSWORD_MANAGER_ENABLE_SYNC) 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScheduleTask(base::Bind(&PasswordStore::DestroySyncableService, this)); 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) shutdown_called_ = true; 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(PASSWORD_MANAGER_ENABLE_SYNC) 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)base::WeakPtr<syncer::SyncableService> 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) PasswordStore::GetPasswordSyncableService() { 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(syncable_service_); 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return syncable_service_->AsWeakPtr(); 211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PasswordStore::~PasswordStore() { DCHECK(shutdown_called_); } 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_refptr<base::SingleThreadTaskRunner> 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PasswordStore::GetBackgroundTaskRunner() { 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return db_thread_runner_; 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) { 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->ApplyIgnoreLoginsCutoff(); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request->ForwardResult(); 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::CopyAndForwardLoginsResult( 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordStore::GetLoginsRequest* request, 228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::vector<PasswordForm*>& matched_forms) { 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Copy the contents of |matched_forms| into the request. The request takes 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // ownership of the PasswordForm elements. 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *(request->result()) = matched_forms; 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ForwardLoginsResult(request); 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::LogStatsForBulkDeletion(int num_deletions) { 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsDeletedByBulkDelete", 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_deletions); 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void PasswordStore::NotifyLoginsChanged( 2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const PasswordStoreChangeList& changes) { 2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); 2436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!changes.empty()) { 2446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) observers_->Notify(&Observer::OnLoginsChanged, changes); 2456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(PASSWORD_MANAGER_ENABLE_SYNC) 2466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (syncable_service_) 2476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) syncable_service_->ActOnPasswordStoreChanges(changes); 2486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif 2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template<typename BackendFunc> 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::Schedule( 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BackendFunc func, 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordStoreConsumer* consumer) { 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetLoginsRequest* request = new GetLoginsRequest(consumer); 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumer->cancelable_task_tracker()->PostTask( 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetBackgroundTaskRunner().get(), 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(func, this, base::Owned(request))); 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordStore::WrapModificationTask(ModificationTask task) { 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordStoreChangeList changes = task.Run(); 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NotifyLoginsChanged(changes); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(PASSWORD_MANAGER_ENABLE_SYNC) 269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PasswordStore::InitSyncableService( 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const syncer::SyncableService::StartSyncFlare& flare) { 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!syncable_service_); 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) syncable_service_.reset(new PasswordSyncableService(this)); 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) syncable_service_->InjectStartSyncFlare(flare); 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PasswordStore::DestroySyncableService() { 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(GetBackgroundTaskRunner()->BelongsToCurrentThread()); 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) syncable_service_.reset(); 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 282c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 283c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace password_manager 284