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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
|
// Copyright (c) 2012 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_
#include <vector>
#include "base/callback.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/observer_list_threadsafe.h"
#include "base/threading/thread.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "chrome/browser/common/cancelable_request.h"
#include "chrome/browser/password_manager/password_store_change.h"
class PasswordStore;
class PasswordStoreConsumer;
class PasswordSyncableService;
class Task;
namespace autofill {
struct PasswordForm;
}
namespace browser_sync {
class PasswordChangeProcessor;
class PasswordDataTypeController;
class PasswordModelAssociator;
class PasswordModelWorker;
}
namespace passwords_helper {
void AddLogin(PasswordStore* store, const autofill::PasswordForm& form);
void RemoveLogin(PasswordStore* store, const autofill::PasswordForm& form);
void UpdateLogin(PasswordStore* store, const autofill::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:
// Whether or not it's acceptable for Chrome to request access to locked
// passwords, which requires prompting the user for permission.
enum AuthorizationPromptPolicy {
ALLOW_PROMPT,
DISALLOW_PROMPT
};
// 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.
class GetLoginsRequest {
public:
explicit GetLoginsRequest(PasswordStoreConsumer* consumer);
virtual ~GetLoginsRequest();
void set_ignore_logins_cutoff(const base::Time& cutoff) {
ignore_logins_cutoff_ = cutoff;
}
// Removes any logins in the result list that were saved before the cutoff.
void ApplyIgnoreLoginsCutoff();
// Forward the result to the consumer on the original message loop.
void ForwardResult();
std::vector<autofill::PasswordForm*>* result() const {
return result_.get();
}
private:
// See GetLogins(). Logins older than this will be removed from the reply.
base::Time ignore_logins_cutoff_;
base::WeakPtr<PasswordStoreConsumer> consumer_weak_;
// The result of the request. It is filled in on the PasswordStore's task
// thread and consumed on the UI thread.
// TODO(dubroy): Remove this, and instead pass the vector directly to the
// backend methods.
scoped_ptr< std::vector<autofill::PasswordForm*> > result_;
base::ThreadChecker thread_checker_;
scoped_refptr<base::MessageLoopProxy> origin_loop_;
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::AddObserver.
class Observer {
public:
// Notifies the observer that password data changed. Will be called from
// the UI thread.
virtual void OnLoginsChanged(const PasswordStoreChangeList& changes) = 0;
protected:
virtual ~Observer() {}
};
PasswordStore(
scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner);
// Reimplement this to add custom initialization. Always call this too.
virtual bool Init();
// Adds the given PasswordForm to the secure password store asynchronously.
virtual void AddLogin(const autofill::PasswordForm& form);
// Updates the matching PasswordForm in the secure password store (async).
void UpdateLogin(const autofill::PasswordForm& form);
// Removes the matching PasswordForm from the secure password store (async).
void RemoveLogin(const autofill::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 notifies |consumer| on
// completion. The request will be cancelled if the consumer is destroyed.
// |prompt_policy| indicates whether it's permissible to prompt the user to
// authorize access to locked passwords. This argument is only used on
// platforms that support prompting the user for access (such as Mac OS).
// NOTE: This means that this method can return different results depending
// on the value of |prompt_policy|.
virtual void GetLogins(
const autofill::PasswordForm& form,
AuthorizationPromptPolicy prompt_policy,
PasswordStoreConsumer* consumer);
// Gets the complete list of PasswordForms that are not blacklist entries--and
// are thus auto-fillable. |consumer| will be notified on completion.
// The request will be cancelled if the consumer is destroyed.
void GetAutofillableLogins(PasswordStoreConsumer* consumer);
// Gets the complete list of PasswordForms that are blacklist entries,
// and notify |consumer| on completion. The request will be cancelled if the
// consumer is destroyed.
void 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);
// Before you destruct the store, call Shutdown to indicate that the store
// needs to shut itself down.
virtual void Shutdown();
protected:
friend class base::RefCountedThreadSafe<PasswordStore>;
// Sync's interaction with password store needs to be synchronous.
// Since the synchronous methods are private these classes are made
// as friends. This can be fixed by moving the private impl to a new
// class. See http://crbug.com/307750
friend class browser_sync::PasswordChangeProcessor;
friend class browser_sync::PasswordDataTypeController;
friend class browser_sync::PasswordModelAssociator;
friend class browser_sync::PasswordModelWorker;
friend class PasswordSyncableService;
friend void passwords_helper::AddLogin(PasswordStore*,
const autofill::PasswordForm&);
friend void passwords_helper::RemoveLogin(PasswordStore*,
const autofill::PasswordForm&);
friend void passwords_helper::UpdateLogin(PasswordStore*,
const autofill::PasswordForm&);
FRIEND_TEST_ALL_PREFIXES(PasswordStoreTest, IgnoreOldWwwGoogleLogins);
typedef base::Callback<PasswordStoreChangeList(void)> ModificationTask;
virtual ~PasswordStore();
// Schedules the given |task| to be run on the PasswordStore's TaskRunner.
bool ScheduleTask(const base::Closure& task);
// Get the TaskRunner to use for PasswordStore background tasks.
// By default, a SingleThreadTaskRunner on the DB thread is used, but
// subclasses can override.
virtual scoped_refptr<base::SingleThreadTaskRunner> GetBackgroundTaskRunner();
// 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 PasswordStoreChangeList AddLoginImpl(
const autofill::PasswordForm& form) = 0;
// Synchronous implementation to update the given login.
virtual PasswordStoreChangeList UpdateLoginImpl(
const autofill::PasswordForm& form) = 0;
// Synchronous implementation to remove the given login.
virtual PasswordStoreChangeList RemoveLoginImpl(
const autofill::PasswordForm& form) = 0;
// Synchronous implementation to remove the given logins.
virtual PasswordStoreChangeList RemoveLoginsCreatedBetweenImpl(
const base::Time& delete_begin, const base::Time& delete_end) = 0;
typedef base::Callback<void(const std::vector<autofill::PasswordForm*>&)>
ConsumerCallbackRunner; // Owns all PasswordForms in the vector.
// 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(
const autofill::PasswordForm& form,
AuthorizationPromptPolicy prompt_policy,
const ConsumerCallbackRunner& callback_runner) = 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<autofill::PasswordForm*>* forms) = 0;
// Finds all blacklist PasswordForms, and fills the vector.
virtual bool FillBlacklistLogins(
std::vector<autofill::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);
// Log UMA stats for number of bulk deletions.
void LogStatsForBulkDeletion(int num_deletions);
// TaskRunner for tasks that run on the main thread (usually the UI thread).
scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner_;
// TaskRunner for the DB thread. By default, this is the task runner used for
// background tasks -- see |GetBackgroundTaskRunner|.
scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner_;
private:
// 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>
void Schedule(BackendFunc func, PasswordStoreConsumer* consumer);
// 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.
virtual void WrapModificationTask(ModificationTask task);
// Called by WrapModificationTask() once the underlying data-modifying
// operation has been performed. Notifies observers that password store data
// may have been changed.
void NotifyLoginsChanged(const PasswordStoreChangeList& changes);
// Copies |matched_forms| into the request's result vector, then calls
// |ForwardLoginsResult|. Temporarily used as an adapter between the API of
// |GetLoginsImpl| and |PasswordStoreConsumer|.
// TODO(dubroy): Get rid of this.
void CopyAndForwardLoginsResult(
PasswordStore::GetLoginsRequest* request,
const std::vector<autofill::PasswordForm*>& matched_forms);
// The observers.
scoped_refptr<ObserverListThreadSafe<Observer> > observers_;
bool shutdown_called_;
DISALLOW_COPY_AND_ASSIGN(PasswordStore);
};
#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_
|