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 22 class Task; 23 24 namespace autofill { 25 struct PasswordForm; 26 } 27 28 namespace browser_sync { 29 class PasswordChangeProcessor; 30 class PasswordDataTypeController; 31 class PasswordModelAssociator; 32 class PasswordModelWorker; 33 } 34 35 namespace password_manager { 36 class PasswordStore; 37 } // namespace password_manager 38 39 namespace passwords_helper { 40 void AddLogin(password_manager::PasswordStore* store, 41 const autofill::PasswordForm& form); 42 void RemoveLogin(password_manager::PasswordStore* store, 43 const autofill::PasswordForm& form); 44 void UpdateLogin(password_manager::PasswordStore* store, 45 const autofill::PasswordForm& form); 46 } 47 48 namespace syncer { 49 class SyncableService; 50 } 51 52 namespace password_manager { 53 54 class PasswordStoreConsumer; 55 class 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. 62 class 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 set_ignore_logins_cutoff(base::Time cutoff)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 result()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: ~Observer()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 // |sync_username| is specified to aid in metrics reporting. 131 virtual bool Init(const syncer::SyncableService::StartSyncFlare& flare, 132 const std::string& sync_username); 133 134 // Adds the given PasswordForm to the secure password store asynchronously. 135 virtual void AddLogin(const autofill::PasswordForm& form); 136 137 // Updates the matching PasswordForm in the secure password store (async). 138 virtual void UpdateLogin(const autofill::PasswordForm& form); 139 140 // Removes the matching PasswordForm from the secure password store (async). 141 virtual void RemoveLogin(const autofill::PasswordForm& form); 142 143 // Removes all logins created in the given date range. 144 virtual void RemoveLoginsCreatedBetween(base::Time delete_begin, 145 base::Time delete_end); 146 147 // Removes all logins synced in the given date range. 148 virtual void RemoveLoginsSyncedBetween(base::Time delete_begin, 149 base::Time delete_end); 150 151 // Searches for a matching PasswordForm, and notifies |consumer| on 152 // completion. The request will be cancelled if the consumer is destroyed. 153 // |prompt_policy| indicates whether it's permissible to prompt the user to 154 // authorize access to locked passwords. This argument is only used on 155 // platforms that support prompting the user for access (such as Mac OS). 156 // NOTE: This means that this method can return different results depending 157 // on the value of |prompt_policy|. 158 virtual void GetLogins( 159 const autofill::PasswordForm& form, 160 AuthorizationPromptPolicy prompt_policy, 161 PasswordStoreConsumer* consumer); 162 163 // Gets the complete list of PasswordForms that are not blacklist entries--and 164 // are thus auto-fillable. |consumer| will be notified on completion. 165 // The request will be cancelled if the consumer is destroyed. 166 virtual void GetAutofillableLogins(PasswordStoreConsumer* consumer); 167 168 // Gets the complete list of PasswordForms that are blacklist entries, 169 // and notify |consumer| on completion. The request will be cancelled if the 170 // consumer is destroyed. 171 virtual void GetBlacklistLogins(PasswordStoreConsumer* consumer); 172 173 // Reports usage metrics for the database. 174 virtual void ReportMetrics(const std::string& sync_username); 175 176 // Adds an observer to be notified when the password store data changes. 177 void AddObserver(Observer* observer); 178 179 // Removes |observer| from the observer list. 180 void RemoveObserver(Observer* observer); 181 182 // Schedules the given |task| to be run on the PasswordStore's TaskRunner. 183 bool ScheduleTask(const base::Closure& task); 184 185 // Before you destruct the store, call Shutdown to indicate that the store 186 // needs to shut itself down. 187 virtual void Shutdown(); 188 189 #if defined(PASSWORD_MANAGER_ENABLE_SYNC) 190 base::WeakPtr<syncer::SyncableService> GetPasswordSyncableService(); 191 #endif 192 193 protected: 194 friend class base::RefCountedThreadSafe<PasswordStore>; 195 FRIEND_TEST_ALL_PREFIXES(PasswordStoreTest, IgnoreOldWwwGoogleLogins); 196 197 typedef base::Callback<PasswordStoreChangeList(void)> ModificationTask; 198 199 virtual ~PasswordStore(); 200 201 // Get the TaskRunner to use for PasswordStore background tasks. 202 // By default, a SingleThreadTaskRunner on the DB thread is used, but 203 // subclasses can override. 204 virtual scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner(); 205 206 // Methods below will be run in PasswordStore's own thread. 207 // Synchronous implementation that reports usage metrics. 208 virtual void ReportMetricsImpl(const std::string& sync_username) = 0; 209 210 // Bring PasswordStoreSync methods to the scope of PasswordStore. Otherwise, 211 // base::Bind can't be used with them because it fails to cast PasswordStore 212 // to PasswordStoreSync. 213 virtual PasswordStoreChangeList AddLoginImpl( 214 const autofill::PasswordForm& form) = 0; 215 virtual PasswordStoreChangeList UpdateLoginImpl( 216 const autofill::PasswordForm& form) = 0; 217 virtual PasswordStoreChangeList RemoveLoginImpl( 218 const autofill::PasswordForm& form) = 0; 219 220 // Synchronous implementation to remove the given logins. 221 virtual PasswordStoreChangeList RemoveLoginsCreatedBetweenImpl( 222 base::Time delete_begin, 223 base::Time delete_end) = 0; 224 225 // Synchronous implementation to remove the given logins. 226 virtual PasswordStoreChangeList RemoveLoginsSyncedBetweenImpl( 227 base::Time delete_begin, 228 base::Time delete_end) = 0; 229 230 typedef base::Callback<void(const std::vector<autofill::PasswordForm*>&)> 231 ConsumerCallbackRunner; // Owns all PasswordForms in the vector. 232 233 // Should find all PasswordForms with the same signon_realm. The results 234 // will then be scored by the PasswordFormManager. Once they are found 235 // (or not), the consumer should be notified. 236 virtual void GetLoginsImpl( 237 const autofill::PasswordForm& form, 238 AuthorizationPromptPolicy prompt_policy, 239 const ConsumerCallbackRunner& callback_runner) = 0; 240 241 // Finds all non-blacklist PasswordForms, and notifies the consumer. 242 virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) = 0; 243 244 // Finds all blacklist PasswordForms, and notifies the consumer. 245 virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0; 246 247 // Dispatches the result to the PasswordStoreConsumer on the original caller's 248 // thread so the callback can be executed there. This should be the UI thread. 249 virtual void ForwardLoginsResult(GetLoginsRequest* request); 250 251 // Log UMA stats for number of bulk deletions. 252 void LogStatsForBulkDeletion(int num_deletions); 253 254 // PasswordStoreSync: 255 // Called by WrapModificationTask() once the underlying data-modifying 256 // operation has been performed. Notifies observers that password store data 257 // may have been changed. 258 virtual void NotifyLoginsChanged( 259 const PasswordStoreChangeList& changes) OVERRIDE; 260 261 // TaskRunner for tasks that run on the main thread (usually the UI thread). 262 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner_; 263 264 // TaskRunner for the DB thread. By default, this is the task runner used for 265 // background tasks -- see |GetBackgroundTaskRunner|. 266 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner_; 267 268 private: 269 // Schedule the given |func| to be run in the PasswordStore's own thread with 270 // responses delivered to |consumer| on the current thread. 271 template<typename BackendFunc> 272 void Schedule(BackendFunc func, PasswordStoreConsumer* consumer); 273 274 // Wrapper method called on the destination thread (DB for non-mac) that 275 // invokes |task| and then calls back into the source thread to notify 276 // observers that the password store may have been modified via 277 // NotifyLoginsChanged(). Note that there is no guarantee that the called 278 // method will actually modify the password store data. 279 virtual void WrapModificationTask(ModificationTask task); 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 scoped_ptr<PasswordSyncableService> syncable_service_; 302 303 bool shutdown_called_; 304 305 DISALLOW_COPY_AND_ASSIGN(PasswordStore); 306 }; 307 308 } // namespace password_manager 309 310 #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_H_ 311