1// Copyright (c) 2011 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 CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_ 6#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_ 7#pragma once 8 9#include <vector> 10 11#include "base/callback.h" 12#include "base/memory/ref_counted.h" 13#include "base/observer_list.h" 14#include "base/threading/thread.h" 15#include "base/time.h" 16#include "content/browser/cancelable_request.h" 17 18class PasswordStoreConsumer; 19class Task; 20 21namespace browser_sync { 22class PasswordDataTypeController; 23class PasswordModelAssociator; 24class PasswordModelWorker; 25}; 26 27namespace webkit_glue { 28struct PasswordForm; 29}; 30 31// Interface for storing form passwords in a platform-specific secure way. 32// The login request/manipulation API is not threadsafe and must be used 33// from the UI thread. 34class PasswordStore 35 : public base::RefCountedThreadSafe<PasswordStore>, 36 public CancelableRequestProvider { 37 public: 38 typedef Callback2<Handle, 39 const std::vector<webkit_glue::PasswordForm*>&>::Type 40 GetLoginsCallback; 41 42 // PasswordForm vector elements are meant to be owned by the 43 // PasswordStoreConsumer. However, if the request is canceled after the 44 // allocation, then the request must take care of the deletion. 45 // TODO(scr) If we can convert vector<PasswordForm*> to 46 // ScopedVector<PasswordForm>, then we can move the following class to merely 47 // a typedef. At the moment, a subclass of CancelableRequest1 is required to 48 // provide a destructor, which cleans up after canceled requests by deleting 49 // vector elements. 50 class GetLoginsRequest : public CancelableRequest1< 51 GetLoginsCallback, std::vector<webkit_glue::PasswordForm*> > { 52 public: 53 explicit GetLoginsRequest(GetLoginsCallback* callback); 54 virtual ~GetLoginsRequest(); 55 56 private: 57 DISALLOW_COPY_AND_ASSIGN(GetLoginsRequest); 58 }; 59 60 // An interface used to notify clients (observers) of this object that data in 61 // the password store has changed. Register the observer via 62 // PasswordStore::SetObserver. 63 class Observer { 64 public: 65 // Notifies the observer that password data changed in some way. 66 virtual void OnLoginsChanged() = 0; 67 68 protected: 69 virtual ~Observer() {} 70 }; 71 72 PasswordStore(); 73 74 // Reimplement this to add custom initialization. Always call this too. 75 virtual bool Init(); 76 77 // Invoked from the profiles destructor to shutdown the PasswordStore. 78 virtual void Shutdown(); 79 80 // Adds the given PasswordForm to the secure password store asynchronously. 81 virtual void AddLogin(const webkit_glue::PasswordForm& form); 82 83 // Updates the matching PasswordForm in the secure password store (async). 84 void UpdateLogin(const webkit_glue::PasswordForm& form); 85 86 // Removes the matching PasswordForm from the secure password store (async). 87 void RemoveLogin(const webkit_glue::PasswordForm& form); 88 89 // Removes all logins created in the given date range. 90 void RemoveLoginsCreatedBetween(const base::Time& delete_begin, 91 const base::Time& delete_end); 92 93 // Searches for a matching PasswordForm and returns a handle so the async 94 // request can be tracked. Implement the PasswordStoreConsumer interface to be 95 // notified on completion. 96 virtual Handle GetLogins(const webkit_glue::PasswordForm& form, 97 PasswordStoreConsumer* consumer); 98 99 // Gets the complete list of PasswordForms that are not blacklist entries--and 100 // are thus auto-fillable--and returns a handle so the async request can be 101 // tracked. Implement the PasswordStoreConsumer interface to be notified on 102 // completion. 103 Handle GetAutofillableLogins(PasswordStoreConsumer* consumer); 104 105 // Gets the complete list of PasswordForms that are blacklist entries, and 106 // returns a handle so the async request can be tracked. Implement the 107 // PasswordStoreConsumer interface to be notified on completion. 108 Handle GetBlacklistLogins(PasswordStoreConsumer* consumer); 109 110 // Reports usage metrics for the database. 111 void ReportMetrics(); 112 113 // Adds an observer to be notified when the password store data changes. 114 void AddObserver(Observer* observer); 115 116 // Removes |observer| from the observer list. 117 void RemoveObserver(Observer* observer); 118 119 protected: 120 friend class base::RefCountedThreadSafe<PasswordStore>; 121 friend class browser_sync::PasswordDataTypeController; 122 friend class browser_sync::PasswordModelAssociator; 123 friend class browser_sync::PasswordModelWorker; 124 friend class LivePasswordsSyncTest; 125 126 virtual ~PasswordStore(); 127 128 // Provided to allow subclasses to extend GetLoginsRequest if additional info 129 // is needed between a call and its Impl. 130 virtual GetLoginsRequest* NewGetLoginsRequest(GetLoginsCallback* callback); 131 132 // Schedule the given |task| to be run in the PasswordStore's own thread. 133 virtual void ScheduleTask(Task* task); 134 135 // These will be run in PasswordStore's own thread. 136 // Synchronous implementation that reports usage metrics. 137 virtual void ReportMetricsImpl() = 0; 138 // Synchronous implementation to add the given login. 139 virtual void AddLoginImpl(const webkit_glue::PasswordForm& form) = 0; 140 // Synchronous implementation to update the given login. 141 virtual void UpdateLoginImpl(const webkit_glue::PasswordForm& form) = 0; 142 // Synchronous implementation to remove the given login. 143 virtual void RemoveLoginImpl(const webkit_glue::PasswordForm& form) = 0; 144 // Synchronous implementation to remove the given logins. 145 virtual void RemoveLoginsCreatedBetweenImpl(const base::Time& delete_begin, 146 const base::Time& delete_end) = 0; 147 // Should find all PasswordForms with the same signon_realm. The results 148 // will then be scored by the PasswordFormManager. Once they are found 149 // (or not), the consumer should be notified. 150 virtual void GetLoginsImpl(GetLoginsRequest* request, 151 const webkit_glue::PasswordForm& form) = 0; 152 // Finds all non-blacklist PasswordForms, and notifies the consumer. 153 virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) = 0; 154 // Finds all blacklist PasswordForms, and notifies the consumer. 155 virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0; 156 157 // Finds all non-blacklist PasswordForms, and fills the vector. 158 virtual bool FillAutofillableLogins( 159 std::vector<webkit_glue::PasswordForm*>* forms) = 0; 160 // Finds all blacklist PasswordForms, and fills the vector. 161 virtual bool FillBlacklistLogins( 162 std::vector<webkit_glue::PasswordForm*>* forms) = 0; 163 164 // Dispatches the result to the PasswordStoreConsumer on the original caller's 165 // thread so the callback can be executed there. This should be the UI 166 // thread. 167 virtual void ForwardLoginsResult(GetLoginsRequest* request); 168 169 // Schedule the given |func| to be run in the PasswordStore's own thread with 170 // responses delivered to |consumer| on the current thread. 171 template<typename BackendFunc> 172 Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer); 173 174 // Schedule the given |func| to be run in the PasswordStore's own thread with 175 // argument |a| and responses delivered to |consumer| on the current thread. 176 template<typename BackendFunc, typename ArgA> 177 Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer, 178 const ArgA& a); 179 180 private: 181 // Wrapper method called on the destination thread (DB for non-mac) that calls 182 // the method specified in |task| and then calls back into the source thread 183 // to notify observers that the password store may have been modified via 184 // NotifyLoginsChanged(). Note that there is no guarantee that the called 185 // method will actually modify the password store data. |task| may not be 186 // NULL. This method owns and will delete |task|. 187 void WrapModificationTask(Task* task); 188 189 // Post a message to the UI thread to run NotifyLoginsChanged(). Called by 190 // WrapModificationTask() above, and split out as a separate method so that 191 // password sync can call it as well after synchronously updating the password 192 // store. 193 void PostNotifyLoginsChanged(); 194 195 // Called by WrapModificationTask() once the underlying data-modifying 196 // operation has been performed. Notifies observers that password store data 197 // may have been changed. 198 void NotifyLoginsChanged(); 199 200 // The observers. 201 ObserverList<Observer> observers_; 202 203 DISALLOW_COPY_AND_ASSIGN(PasswordStore); 204}; 205 206#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_ 207