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