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
22class Task;
23
24namespace autofill {
25struct PasswordForm;
26}
27
28namespace browser_sync {
29class PasswordChangeProcessor;
30class PasswordDataTypeController;
31class PasswordModelAssociator;
32class PasswordModelWorker;
33}
34
35namespace password_manager {
36class PasswordStore;
37}  // namespace password_manager
38
39namespace passwords_helper {
40void AddLogin(password_manager::PasswordStore* store,
41              const autofill::PasswordForm& form);
42void RemoveLogin(password_manager::PasswordStore* store,
43                 const autofill::PasswordForm& form);
44void UpdateLogin(password_manager::PasswordStore* store,
45                 const autofill::PasswordForm& form);
46}
47
48namespace syncer {
49class SyncableService;
50}
51
52namespace password_manager {
53
54class PasswordStoreConsumer;
55class 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.
62class 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
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
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:
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