summaryrefslogtreecommitdiffstats
path: root/chrome/browser/password_manager/password_store.h
blob: eb656bfb6804f504dcf09c751a6e0b8c85e5c5e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_
#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_
#pragma once

#include <vector>

#include "base/callback.h"
#include "base/callback_old.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list.h"
#include "base/threading/thread.h"
#include "base/time.h"
#include "content/browser/cancelable_request.h"

class PasswordStore;
class PasswordStoreConsumer;
class Task;

namespace browser_sync {
class PasswordDataTypeController;
class PasswordModelAssociator;
class PasswordModelWorker;
};

namespace webkit_glue {
struct PasswordForm;
};

namespace passwords_helper {
void AddLogin(PasswordStore* store, const webkit_glue::PasswordForm& form);
void RemoveLogin(PasswordStore* store, const webkit_glue::PasswordForm& form);
void UpdateLogin(PasswordStore* store, const webkit_glue::PasswordForm& form);
};

// Interface for storing form passwords in a platform-specific secure way.
// The login request/manipulation API is not threadsafe and must be used
// from the UI thread.
class PasswordStore
    : public base::RefCountedThreadSafe<PasswordStore>,
      public CancelableRequestProvider {
 public:
  typedef Callback2<Handle,
                    const std::vector<webkit_glue::PasswordForm*>&>::Type
      GetLoginsCallback;

  // PasswordForm vector elements are meant to be owned by the
  // PasswordStoreConsumer. However, if the request is canceled after the
  // allocation, then the request must take care of the deletion.
  // TODO(scr) If we can convert vector<PasswordForm*> to
  // ScopedVector<PasswordForm>, then we can move the following class to merely
  // a typedef. At the moment, a subclass of CancelableRequest1 is required to
  // provide a destructor, which cleans up after canceled requests by deleting
  // vector elements.
  class GetLoginsRequest : public CancelableRequest1<
    GetLoginsCallback, std::vector<webkit_glue::PasswordForm*> > {
   public:
    explicit GetLoginsRequest(GetLoginsCallback* callback);
    virtual ~GetLoginsRequest();

   private:
    DISALLOW_COPY_AND_ASSIGN(GetLoginsRequest);
  };

  // An interface used to notify clients (observers) of this object that data in
  // the password store has changed. Register the observer via
  // PasswordStore::SetObserver.
  class Observer {
   public:
    // Notifies the observer that password data changed in some way.
    virtual void OnLoginsChanged() = 0;

   protected:
    virtual ~Observer() {}
  };

  PasswordStore();

  // Reimplement this to add custom initialization. Always call this too.
  virtual bool Init();

  // Invoked from the profiles destructor to shutdown the PasswordStore.
  virtual void Shutdown();

  // Adds the given PasswordForm to the secure password store asynchronously.
  virtual void AddLogin(const webkit_glue::PasswordForm& form);

  // Updates the matching PasswordForm in the secure password store (async).
  void UpdateLogin(const webkit_glue::PasswordForm& form);

  // Removes the matching PasswordForm from the secure password store (async).
  void RemoveLogin(const webkit_glue::PasswordForm& form);

  // Removes all logins created in the given date range.
  void RemoveLoginsCreatedBetween(const base::Time& delete_begin,
                                  const base::Time& delete_end);

  // Searches for a matching PasswordForm and returns a handle so the async
  // request can be tracked. Implement the PasswordStoreConsumer interface to be
  // notified on completion.
  virtual Handle GetLogins(const webkit_glue::PasswordForm& form,
                           PasswordStoreConsumer* consumer);

  // Gets the complete list of PasswordForms that are not blacklist entries--and
  // are thus auto-fillable--and returns a handle so the async request can be
  // tracked. Implement the PasswordStoreConsumer interface to be notified on
  // completion.
  Handle GetAutofillableLogins(PasswordStoreConsumer* consumer);

  // Gets the complete list of PasswordForms that are blacklist entries, and
  // returns a handle so the async request can be tracked. Implement the
  // PasswordStoreConsumer interface to be notified on completion.
  Handle GetBlacklistLogins(PasswordStoreConsumer* consumer);

  // Reports usage metrics for the database.
  void ReportMetrics();

  // Adds an observer to be notified when the password store data changes.
  void AddObserver(Observer* observer);

  // Removes |observer| from the observer list.
  void RemoveObserver(Observer* observer);

 protected:
  friend class base::RefCountedThreadSafe<PasswordStore>;
  friend class browser_sync::PasswordDataTypeController;
  friend class browser_sync::PasswordModelAssociator;
  friend class browser_sync::PasswordModelWorker;
  friend void passwords_helper::AddLogin(PasswordStore*,
                                         const webkit_glue::PasswordForm&);
  friend void passwords_helper::RemoveLogin(PasswordStore*,
                                            const webkit_glue::PasswordForm&);
  friend void passwords_helper::UpdateLogin(PasswordStore*,
                                            const webkit_glue::PasswordForm&);

  virtual ~PasswordStore();

  // Provided to allow subclasses to extend GetLoginsRequest if additional info
  // is needed between a call and its Impl.
  virtual GetLoginsRequest* NewGetLoginsRequest(GetLoginsCallback* callback);

  // Schedule the given |task| to be run in the PasswordStore's own thread.
  // TODO(mdm): Remove the Task* version of this when it is no longer needed.
  virtual void ScheduleTask(Task* task);
  virtual void ScheduleTask(const base::Closure& task);

  // These will be run in PasswordStore's own thread.
  // Synchronous implementation that reports usage metrics.
  virtual void ReportMetricsImpl() = 0;
  // Synchronous implementation to add the given login.
  virtual void AddLoginImpl(const webkit_glue::PasswordForm& form) = 0;
  // Synchronous implementation to update the given login.
  virtual void UpdateLoginImpl(const webkit_glue::PasswordForm& form) = 0;
  // Synchronous implementation to remove the given login.
  virtual void RemoveLoginImpl(const webkit_glue::PasswordForm& form) = 0;
  // Synchronous implementation to remove the given logins.
  virtual void RemoveLoginsCreatedBetweenImpl(const base::Time& delete_begin,
                                              const base::Time& delete_end) = 0;
  // Should find all PasswordForms with the same signon_realm. The results
  // will then be scored by the PasswordFormManager. Once they are found
  // (or not), the consumer should be notified.
  virtual void GetLoginsImpl(GetLoginsRequest* request,
                             const webkit_glue::PasswordForm& form) = 0;
  // Finds all non-blacklist PasswordForms, and notifies the consumer.
  virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) = 0;
  // Finds all blacklist PasswordForms, and notifies the consumer.
  virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0;

  // Finds all non-blacklist PasswordForms, and fills the vector.
  virtual bool FillAutofillableLogins(
      std::vector<webkit_glue::PasswordForm*>* forms) = 0;
  // Finds all blacklist PasswordForms, and fills the vector.
  virtual bool FillBlacklistLogins(
      std::vector<webkit_glue::PasswordForm*>* forms) = 0;

  // Dispatches the result to the PasswordStoreConsumer on the original caller's
  // thread so the callback can be executed there.  This should be the UI
  // thread.
  virtual void ForwardLoginsResult(GetLoginsRequest* request);

  // Schedule the given |func| to be run in the PasswordStore's own thread with
  // responses delivered to |consumer| on the current thread.
  template<typename BackendFunc>
  Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer);

  // Schedule the given |func| to be run in the PasswordStore's own thread with
  // argument |a| and responses delivered to |consumer| on the current thread.
  template<typename BackendFunc, typename ArgA>
  Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer,
                  const ArgA& a);

 private:
  // Wrapper method called on the destination thread (DB for non-mac) that
  // invokes |task| and then calls back into the source thread to notify
  // observers that the password store may have been modified via
  // NotifyLoginsChanged(). Note that there is no guarantee that the called
  // method will actually modify the password store data.
  void WrapModificationTask(base::Closure task);

  // Post a message to the UI thread to run NotifyLoginsChanged(). Called by
  // WrapModificationTask() above, and split out as a separate method so that
  // password sync can call it as well after synchronously updating the password
  // store.
  void PostNotifyLoginsChanged();

  // Called by WrapModificationTask() once the underlying data-modifying
  // operation has been performed. Notifies observers that password store data
  // may have been changed.
  void NotifyLoginsChanged();

  // The observers.
  ObserverList<Observer> observers_;

  DISALLOW_COPY_AND_ASSIGN(PasswordStore);
};

#endif  // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_