1// Copyright 2014 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#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_H_ 6#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_H_ 7 8#include <vector> 9 10#include "base/callback.h" 11#include "base/gtest_prod_util.h" 12#include "base/memory/ref_counted.h" 13#include "base/memory/scoped_ptr.h" 14#include "base/observer_list_threadsafe.h" 15#include "base/threading/thread.h" 16#include "base/threading/thread_checker.h" 17#include "base/time/time.h" 18#include "components/password_manager/core/browser/password_store_change.h" 19#include "components/password_manager/core/browser/password_store_sync.h" 20#include "sync/api/syncable_service.h" 21 22class Task; 23 24namespace autofill { 25struct PasswordForm; 26} 27 28namespace browser_sync { 29class PasswordChangeProcessor; 30class PasswordDataTypeController; 31class PasswordModelAssociator; 32class PasswordModelWorker; 33} 34 35namespace password_manager { 36class PasswordStore; 37} // namespace password_manager 38 39namespace passwords_helper { 40void AddLogin(password_manager::PasswordStore* store, 41 const autofill::PasswordForm& form); 42void RemoveLogin(password_manager::PasswordStore* store, 43 const autofill::PasswordForm& form); 44void UpdateLogin(password_manager::PasswordStore* store, 45 const autofill::PasswordForm& form); 46} 47 48namespace syncer { 49class SyncableService; 50} 51 52namespace password_manager { 53 54class PasswordStoreConsumer; 55class PasswordSyncableService; 56 57// Interface for storing form passwords in a platform-specific secure way. 58// The login request/manipulation API is not threadsafe and must be used 59// from the UI thread. 60// PasswordStoreSync is a hidden base class because only PasswordSyncableService 61// needs to access these methods. 62class PasswordStore : protected PasswordStoreSync, 63 public base::RefCountedThreadSafe<PasswordStore> { 64 public: 65 // Whether or not it's acceptable for Chrome to request access to locked 66 // passwords, which requires prompting the user for permission. 67 enum AuthorizationPromptPolicy { 68 ALLOW_PROMPT, 69 DISALLOW_PROMPT 70 }; 71 72 // PasswordForm vector elements are meant to be owned by the 73 // PasswordStoreConsumer. However, if the request is canceled after the 74 // allocation, then the request must take care of the deletion. 75 class GetLoginsRequest { 76 public: 77 explicit GetLoginsRequest(PasswordStoreConsumer* consumer); 78 virtual ~GetLoginsRequest(); 79 80 void set_ignore_logins_cutoff(base::Time cutoff) { 81 ignore_logins_cutoff_ = cutoff; 82 } 83 84 // Removes any logins in the result list that were saved before the cutoff. 85 void ApplyIgnoreLoginsCutoff(); 86 87 // Forward the result to the consumer on the original message loop. 88 void ForwardResult(); 89 90 std::vector<autofill::PasswordForm*>* result() const { 91 return result_.get(); 92 } 93 94 private: 95 // See GetLogins(). Logins older than this will be removed from the reply. 96 base::Time ignore_logins_cutoff_; 97 98 base::WeakPtr<PasswordStoreConsumer> consumer_weak_; 99 100 // The result of the request. It is filled in on the PasswordStore's task 101 // thread and consumed on the UI thread. 102 // TODO(dubroy): Remove this, and instead pass the vector directly to the 103 // backend methods. 104 scoped_ptr< std::vector<autofill::PasswordForm*> > result_; 105 106 base::ThreadChecker thread_checker_; 107 scoped_refptr<base::MessageLoopProxy> origin_loop_; 108 109 DISALLOW_COPY_AND_ASSIGN(GetLoginsRequest); 110 }; 111 112 // An interface used to notify clients (observers) of this object that data in 113 // the password store has changed. Register the observer via 114 // PasswordStore::AddObserver. 115 class Observer { 116 public: 117 // Notifies the observer that password data changed. Will be called from 118 // the UI thread. 119 virtual void OnLoginsChanged(const PasswordStoreChangeList& changes) = 0; 120 121 protected: 122 virtual ~Observer() {} 123 }; 124 125 PasswordStore( 126 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, 127 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner); 128 129 // Reimplement this to add custom initialization. Always call this too. 130 virtual bool Init(const syncer::SyncableService::StartSyncFlare& flare); 131 132 // Adds the given PasswordForm to the secure password store asynchronously. 133 virtual void AddLogin(const autofill::PasswordForm& form); 134 135 // Updates the matching PasswordForm in the secure password store (async). 136 virtual void UpdateLogin(const autofill::PasswordForm& form); 137 138 // Removes the matching PasswordForm from the secure password store (async). 139 virtual void RemoveLogin(const autofill::PasswordForm& form); 140 141 // Removes all logins created in the given date range. 142 virtual void RemoveLoginsCreatedBetween(base::Time delete_begin, 143 base::Time delete_end); 144 145 // Removes all logins synced in the given date range. 146 virtual void RemoveLoginsSyncedBetween(base::Time delete_begin, 147 base::Time delete_end); 148 149 // Searches for a matching PasswordForm, and notifies |consumer| on 150 // completion. The request will be cancelled if the consumer is destroyed. 151 // |prompt_policy| indicates whether it's permissible to prompt the user to 152 // authorize access to locked passwords. This argument is only used on 153 // platforms that support prompting the user for access (such as Mac OS). 154 // NOTE: This means that this method can return different results depending 155 // on the value of |prompt_policy|. 156 virtual void GetLogins( 157 const autofill::PasswordForm& form, 158 AuthorizationPromptPolicy prompt_policy, 159 PasswordStoreConsumer* consumer); 160 161 // Gets the complete list of PasswordForms that are not blacklist entries--and 162 // are thus auto-fillable. |consumer| will be notified on completion. 163 // The request will be cancelled if the consumer is destroyed. 164 virtual void GetAutofillableLogins(PasswordStoreConsumer* consumer); 165 166 // Gets the complete list of PasswordForms that are blacklist entries, 167 // and notify |consumer| on completion. The request will be cancelled if the 168 // consumer is destroyed. 169 virtual void GetBlacklistLogins(PasswordStoreConsumer* consumer); 170 171 // Reports usage metrics for the database. 172 virtual void ReportMetrics(); 173 174 // Adds an observer to be notified when the password store data changes. 175 void AddObserver(Observer* observer); 176 177 // Removes |observer| from the observer list. 178 void RemoveObserver(Observer* observer); 179 180 // Schedules the given |task| to be run on the PasswordStore's TaskRunner. 181 bool ScheduleTask(const base::Closure& task); 182 183 // Before you destruct the store, call Shutdown to indicate that the store 184 // needs to shut itself down. 185 virtual void Shutdown(); 186 187#if defined(PASSWORD_MANAGER_ENABLE_SYNC) 188 base::WeakPtr<syncer::SyncableService> GetPasswordSyncableService(); 189#endif 190 191 protected: 192 friend class base::RefCountedThreadSafe<PasswordStore>; 193 FRIEND_TEST_ALL_PREFIXES(PasswordStoreTest, IgnoreOldWwwGoogleLogins); 194 195 typedef base::Callback<PasswordStoreChangeList(void)> ModificationTask; 196 197 virtual ~PasswordStore(); 198 199 // Get the TaskRunner to use for PasswordStore background tasks. 200 // By default, a SingleThreadTaskRunner on the DB thread is used, but 201 // subclasses can override. 202 virtual scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner(); 203 204 // Methods below will be run in PasswordStore's own thread. 205 // Synchronous implementation that reports usage metrics. 206 virtual void ReportMetricsImpl() = 0; 207 208 // Bring PasswordStoreSync methods to the scope of PasswordStore. Otherwise, 209 // base::Bind can't be used with them because it fails to cast PasswordStore 210 // to PasswordStoreSync. 211 virtual PasswordStoreChangeList AddLoginImpl( 212 const autofill::PasswordForm& form) = 0; 213 virtual PasswordStoreChangeList UpdateLoginImpl( 214 const autofill::PasswordForm& form) = 0; 215 virtual PasswordStoreChangeList RemoveLoginImpl( 216 const autofill::PasswordForm& form) = 0; 217 218 // Synchronous implementation to remove the given logins. 219 virtual PasswordStoreChangeList RemoveLoginsCreatedBetweenImpl( 220 base::Time delete_begin, 221 base::Time delete_end) = 0; 222 223 // Synchronous implementation to remove the given logins. 224 virtual PasswordStoreChangeList RemoveLoginsSyncedBetweenImpl( 225 base::Time delete_begin, 226 base::Time delete_end) = 0; 227 228 typedef base::Callback<void(const std::vector<autofill::PasswordForm*>&)> 229 ConsumerCallbackRunner; // Owns all PasswordForms in the vector. 230 231 // Should find all PasswordForms with the same signon_realm. The results 232 // will then be scored by the PasswordFormManager. Once they are found 233 // (or not), the consumer should be notified. 234 virtual void GetLoginsImpl( 235 const autofill::PasswordForm& form, 236 AuthorizationPromptPolicy prompt_policy, 237 const ConsumerCallbackRunner& callback_runner) = 0; 238 239 // Finds all non-blacklist PasswordForms, and notifies the consumer. 240 virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) = 0; 241 242 // Finds all blacklist PasswordForms, and notifies the consumer. 243 virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0; 244 245 // Dispatches the result to the PasswordStoreConsumer on the original caller's 246 // thread so the callback can be executed there. This should be the UI thread. 247 virtual void ForwardLoginsResult(GetLoginsRequest* request); 248 249 // Log UMA stats for number of bulk deletions. 250 void LogStatsForBulkDeletion(int num_deletions); 251 252 // TaskRunner for tasks that run on the main thread (usually the UI thread). 253 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner_; 254 255 // TaskRunner for the DB thread. By default, this is the task runner used for 256 // background tasks -- see |GetBackgroundTaskRunner|. 257 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner_; 258 259 scoped_ptr<PasswordSyncableService> syncable_service_; 260 261 private: 262 // Schedule the given |func| to be run in the PasswordStore's own thread with 263 // responses delivered to |consumer| on the current thread. 264 template<typename BackendFunc> 265 void Schedule(BackendFunc func, PasswordStoreConsumer* consumer); 266 267 // Wrapper method called on the destination thread (DB for non-mac) that 268 // invokes |task| and then calls back into the source thread to notify 269 // observers that the password store may have been modified via 270 // NotifyLoginsChanged(). Note that there is no guarantee that the called 271 // method will actually modify the password store data. 272 virtual void WrapModificationTask(ModificationTask task); 273 274 // PasswordStoreSync: 275 // Called by WrapModificationTask() once the underlying data-modifying 276 // operation has been performed. Notifies observers that password store data 277 // may have been changed. 278 virtual void NotifyLoginsChanged( 279 const PasswordStoreChangeList& changes) OVERRIDE; 280 281 // Copies |matched_forms| into the request's result vector, then calls 282 // |ForwardLoginsResult|. Temporarily used as an adapter between the API of 283 // |GetLoginsImpl| and |PasswordStoreConsumer|. 284 // TODO(dubroy): Get rid of this. 285 void CopyAndForwardLoginsResult( 286 PasswordStore::GetLoginsRequest* request, 287 const std::vector<autofill::PasswordForm*>& matched_forms); 288 289#if defined(PASSWORD_MANAGER_ENABLE_SYNC) 290 // Creates PasswordSyncableService instance on the background thread. 291 void InitSyncableService( 292 const syncer::SyncableService::StartSyncFlare& flare); 293 294 // Deletes PasswordSyncableService instance on the background thread. 295 void DestroySyncableService(); 296#endif 297 298 // The observers. 299 scoped_refptr<ObserverListThreadSafe<Observer> > observers_; 300 301 bool shutdown_called_; 302 303 DISALLOW_COPY_AND_ASSIGN(PasswordStore); 304}; 305 306} // namespace password_manager 307 308#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_H_ 309