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 PasswordSyncableService; 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 passwords_helper { 36 void AddLogin(PasswordStore* store, const autofill::PasswordForm& form); 37 void RemoveLogin(PasswordStore* store, const autofill::PasswordForm& form); 38 void UpdateLogin(PasswordStore* store, const autofill::PasswordForm& form); 39 } 40 41 // Interface for storing form passwords in a platform-specific secure way. 42 // The login request/manipulation API is not threadsafe and must be used 43 // from the UI thread. 44 class PasswordStore 45 : public RefcountedBrowserContextKeyedService, 46 public CancelableRequestProvider { 47 public: 48 typedef base::Callback< 49 void(Handle, const std::vector<autofill::PasswordForm*>&)> 50 GetLoginsCallback; 51 52 // Whether or not it's acceptable for Chrome to request access to locked 53 // passwords, which requires prompting the user for permission. 54 enum AuthorizationPromptPolicy { 55 ALLOW_PROMPT, 56 DISALLOW_PROMPT 57 }; 58 59 // PasswordForm vector elements are meant to be owned by the 60 // PasswordStoreConsumer. However, if the request is canceled after the 61 // allocation, then the request must take care of the deletion. 62 class GetLoginsRequest 63 : public CancelableRequest1<GetLoginsCallback, 64 std::vector<autofill::PasswordForm*> > { 65 public: 66 explicit GetLoginsRequest(const GetLoginsCallback& callback); 67 68 void set_ignore_logins_cutoff(const base::Time& cutoff) { 69 ignore_logins_cutoff_ = cutoff; 70 } 71 72 // Removes any logins in the result list that were saved before the cutoff. 73 void ApplyIgnoreLoginsCutoff(); 74 75 protected: 76 virtual ~GetLoginsRequest(); 77 78 private: 79 // See GetLogins(). Logins older than this will be removed from the reply. 80 base::Time ignore_logins_cutoff_; 81 82 DISALLOW_COPY_AND_ASSIGN(GetLoginsRequest); 83 }; 84 85 // An interface used to notify clients (observers) of this object that data in 86 // the password store has changed. Register the observer via 87 // PasswordStore::SetObserver. 88 class Observer { 89 public: 90 // Notifies the observer that password data changed in some way. 91 virtual void OnLoginsChanged() = 0; 92 93 protected: 94 virtual ~Observer() {} 95 }; 96 97 PasswordStore(); 98 99 // Reimplement this to add custom initialization. Always call this too. 100 virtual bool Init(); 101 102 // Adds the given PasswordForm to the secure password store asynchronously. 103 virtual void AddLogin(const autofill::PasswordForm& form); 104 105 // Updates the matching PasswordForm in the secure password store (async). 106 void UpdateLogin(const autofill::PasswordForm& form); 107 108 // Removes the matching PasswordForm from the secure password store (async). 109 void RemoveLogin(const autofill::PasswordForm& form); 110 111 // Removes all logins created in the given date range. 112 void RemoveLoginsCreatedBetween(const base::Time& delete_begin, 113 const base::Time& delete_end); 114 115 // Searches for a matching PasswordForm and returns a ID so the async request 116 // can be tracked. Implement the PasswordStoreConsumer interface to be 117 // notified on completion. |prompt_policy| indicates whether it's permissible 118 // to prompt the user to authorize access to locked passwords. This argument 119 // is only used on platforms that support prompting the user for access (such 120 // as Mac OS). NOTE: This means that this method can return different results 121 // depending on the value of |prompt_policy|. 122 virtual CancelableTaskTracker::TaskId GetLogins( 123 const autofill::PasswordForm& form, 124 AuthorizationPromptPolicy prompt_policy, 125 PasswordStoreConsumer* consumer); 126 127 // Gets the complete list of PasswordForms that are not blacklist entries--and 128 // are thus auto-fillable--and returns a handle so the async request can be 129 // tracked. Implement the PasswordStoreConsumer interface to be notified on 130 // completion. 131 Handle GetAutofillableLogins(PasswordStoreConsumer* consumer); 132 133 // Gets the complete list of PasswordForms that are blacklist entries, and 134 // returns a handle so the async request can be tracked. Implement the 135 // PasswordStoreConsumer interface to be notified on completion. 136 Handle GetBlacklistLogins(PasswordStoreConsumer* consumer); 137 138 // Reports usage metrics for the database. 139 void ReportMetrics(); 140 141 // Adds an observer to be notified when the password store data changes. 142 void AddObserver(Observer* observer); 143 144 // Removes |observer| from the observer list. 145 void RemoveObserver(Observer* observer); 146 147 protected: 148 friend class base::RefCountedThreadSafe<PasswordStore>; 149 // Sync's interaction with password store needs to be syncrhonous. 150 // Since the synchronous methods are private these classes are made 151 // as friends. This can be fixed by moving the private impl to a new 152 // class. See http://crbug.com/307750 153 friend class browser_sync::PasswordChangeProcessor; 154 friend class browser_sync::PasswordDataTypeController; 155 friend class browser_sync::PasswordModelAssociator; 156 friend class browser_sync::PasswordModelWorker; 157 friend class PasswordSyncableService; 158 friend void passwords_helper::AddLogin(PasswordStore*, 159 const autofill::PasswordForm&); 160 friend void passwords_helper::RemoveLogin(PasswordStore*, 161 const autofill::PasswordForm&); 162 friend void passwords_helper::UpdateLogin(PasswordStore*, 163 const autofill::PasswordForm&); 164 165 virtual ~PasswordStore(); 166 167 // Provided to allow subclasses to extend GetLoginsRequest if additional info 168 // is needed between a call and its Impl. 169 virtual GetLoginsRequest* NewGetLoginsRequest( 170 const GetLoginsCallback& callback); 171 172 // Schedule the given |task| to be run in the PasswordStore's task thread. By 173 // default it uses DB thread, but sub classes can override to use other 174 // threads. 175 virtual bool ScheduleTask(const base::Closure& task); 176 177 // These will be run in PasswordStore's own thread. 178 // Synchronous implementation that reports usage metrics. 179 virtual void ReportMetricsImpl() = 0; 180 // Synchronous implementation to add the given login. 181 virtual void AddLoginImpl(const autofill::PasswordForm& form) = 0; 182 // Synchronous implementation to update the given login. 183 virtual void UpdateLoginImpl(const autofill::PasswordForm& form) = 0; 184 // Synchronous implementation to remove the given login. 185 virtual void RemoveLoginImpl(const autofill::PasswordForm& form) = 0; 186 // Synchronous implementation to remove the given logins. 187 virtual void RemoveLoginsCreatedBetweenImpl(const base::Time& delete_begin, 188 const base::Time& delete_end) = 0; 189 190 typedef base::Callback<void(const std::vector<autofill::PasswordForm*>&)> 191 ConsumerCallbackRunner; // Owns all PasswordForms in the vector. 192 193 // Should find all PasswordForms with the same signon_realm. The results 194 // will then be scored by the PasswordFormManager. Once they are found 195 // (or not), the consumer should be notified. 196 virtual void GetLoginsImpl( 197 const autofill::PasswordForm& form, 198 AuthorizationPromptPolicy prompt_policy, 199 const ConsumerCallbackRunner& callback_runner) = 0; 200 201 // Finds all non-blacklist PasswordForms, and notifies the consumer. 202 virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) = 0; 203 // Finds all blacklist PasswordForms, and notifies the consumer. 204 virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0; 205 206 // Finds all non-blacklist PasswordForms, and fills the vector. 207 virtual bool FillAutofillableLogins( 208 std::vector<autofill::PasswordForm*>* forms) = 0; 209 // Finds all blacklist PasswordForms, and fills the vector. 210 virtual bool FillBlacklistLogins( 211 std::vector<autofill::PasswordForm*>* forms) = 0; 212 213 // Dispatches the result to the PasswordStoreConsumer on the original caller's 214 // thread so the callback can be executed there. This should be the UI thread. 215 virtual void ForwardLoginsResult(GetLoginsRequest* request); 216 217 // Log UMA stats for number of bulk deletions. 218 void LogStatsForBulkDeletion(int num_deletions); 219 220 private: 221 // Schedule the given |func| to be run in the PasswordStore's own thread with 222 // responses delivered to |consumer| on the current thread. 223 template<typename BackendFunc> 224 Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer); 225 226 // Schedule the given |func| to be run in the PasswordStore's own thread with 227 // form |form| and responses delivered to |consumer| on the current thread. 228 // See GetLogins() for more information on |ignore_logins_cutoff|. 229 template<typename BackendFunc> 230 Handle Schedule(BackendFunc func, 231 PasswordStoreConsumer* consumer, 232 const autofill::PasswordForm& form, 233 const base::Time& ignore_logins_cutoff); 234 235 // Wrapper method called on the destination thread (DB for non-mac) that 236 // invokes |task| and then calls back into the source thread to notify 237 // observers that the password store may have been modified via 238 // NotifyLoginsChanged(). Note that there is no guarantee that the called 239 // method will actually modify the password store data. 240 virtual void WrapModificationTask(base::Closure task); 241 242 // Post a message to the UI thread to run NotifyLoginsChanged(). Called by 243 // WrapModificationTask() above, and split out as a separate method so that 244 // password sync can call it as well after synchronously updating the password 245 // store. 246 void PostNotifyLoginsChanged(); 247 248 // Called by WrapModificationTask() once the underlying data-modifying 249 // operation has been performed. Notifies observers that password store data 250 // may have been changed. 251 void NotifyLoginsChanged(); 252 253 // The observers. 254 ObserverList<Observer> observers_; 255 256 DISALLOW_COPY_AND_ASSIGN(PasswordStore); 257 }; 258 259 #endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_ 260