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