• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #pragma once
8 
9 #include <vector>
10 
11 #include "base/callback.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/observer_list.h"
14 #include "base/threading/thread.h"
15 #include "base/time.h"
16 #include "content/browser/cancelable_request.h"
17 
18 class PasswordStoreConsumer;
19 class Task;
20 
21 namespace browser_sync {
22 class PasswordDataTypeController;
23 class PasswordModelAssociator;
24 class PasswordModelWorker;
25 };
26 
27 namespace webkit_glue {
28 struct PasswordForm;
29 };
30 
31 // Interface for storing form passwords in a platform-specific secure way.
32 // The login request/manipulation API is not threadsafe and must be used
33 // from the UI thread.
34 class PasswordStore
35     : public base::RefCountedThreadSafe<PasswordStore>,
36       public CancelableRequestProvider {
37  public:
38   typedef Callback2<Handle,
39                     const std::vector<webkit_glue::PasswordForm*>&>::Type
40       GetLoginsCallback;
41 
42   // PasswordForm vector elements are meant to be owned by the
43   // PasswordStoreConsumer. However, if the request is canceled after the
44   // allocation, then the request must take care of the deletion.
45   // TODO(scr) If we can convert vector<PasswordForm*> to
46   // ScopedVector<PasswordForm>, then we can move the following class to merely
47   // a typedef. At the moment, a subclass of CancelableRequest1 is required to
48   // provide a destructor, which cleans up after canceled requests by deleting
49   // vector elements.
50   class GetLoginsRequest : public CancelableRequest1<
51     GetLoginsCallback, std::vector<webkit_glue::PasswordForm*> > {
52    public:
53     explicit GetLoginsRequest(GetLoginsCallback* callback);
54     virtual ~GetLoginsRequest();
55 
56    private:
57     DISALLOW_COPY_AND_ASSIGN(GetLoginsRequest);
58   };
59 
60   // An interface used to notify clients (observers) of this object that data in
61   // the password store has changed. Register the observer via
62   // PasswordStore::SetObserver.
63   class Observer {
64    public:
65     // Notifies the observer that password data changed in some way.
66     virtual void OnLoginsChanged() = 0;
67 
68    protected:
~Observer()69     virtual ~Observer() {}
70   };
71 
72   PasswordStore();
73 
74   // Reimplement this to add custom initialization. Always call this too.
75   virtual bool Init();
76 
77   // Invoked from the profiles destructor to shutdown the PasswordStore.
78   virtual void Shutdown();
79 
80   // Adds the given PasswordForm to the secure password store asynchronously.
81   virtual void AddLogin(const webkit_glue::PasswordForm& form);
82 
83   // Updates the matching PasswordForm in the secure password store (async).
84   void UpdateLogin(const webkit_glue::PasswordForm& form);
85 
86   // Removes the matching PasswordForm from the secure password store (async).
87   void RemoveLogin(const webkit_glue::PasswordForm& form);
88 
89   // Removes all logins created in the given date range.
90   void RemoveLoginsCreatedBetween(const base::Time& delete_begin,
91                                   const base::Time& delete_end);
92 
93   // Searches for a matching PasswordForm and returns a handle so the async
94   // request can be tracked. Implement the PasswordStoreConsumer interface to be
95   // notified on completion.
96   virtual Handle GetLogins(const webkit_glue::PasswordForm& form,
97                            PasswordStoreConsumer* consumer);
98 
99   // Gets the complete list of PasswordForms that are not blacklist entries--and
100   // are thus auto-fillable--and returns a handle so the async request can be
101   // tracked. Implement the PasswordStoreConsumer interface to be notified on
102   // completion.
103   Handle GetAutofillableLogins(PasswordStoreConsumer* consumer);
104 
105   // Gets the complete list of PasswordForms that are blacklist entries, and
106   // returns a handle so the async request can be tracked. Implement the
107   // PasswordStoreConsumer interface to be notified on completion.
108   Handle GetBlacklistLogins(PasswordStoreConsumer* consumer);
109 
110   // Reports usage metrics for the database.
111   void ReportMetrics();
112 
113   // Adds an observer to be notified when the password store data changes.
114   void AddObserver(Observer* observer);
115 
116   // Removes |observer| from the observer list.
117   void RemoveObserver(Observer* observer);
118 
119  protected:
120   friend class base::RefCountedThreadSafe<PasswordStore>;
121   friend class browser_sync::PasswordDataTypeController;
122   friend class browser_sync::PasswordModelAssociator;
123   friend class browser_sync::PasswordModelWorker;
124   friend class LivePasswordsSyncTest;
125 
126   virtual ~PasswordStore();
127 
128   // Provided to allow subclasses to extend GetLoginsRequest if additional info
129   // is needed between a call and its Impl.
130   virtual GetLoginsRequest* NewGetLoginsRequest(GetLoginsCallback* callback);
131 
132   // Schedule the given |task| to be run in the PasswordStore's own thread.
133   virtual void ScheduleTask(Task* task);
134 
135   // These will be run in PasswordStore's own thread.
136   // Synchronous implementation that reports usage metrics.
137   virtual void ReportMetricsImpl() = 0;
138   // Synchronous implementation to add the given login.
139   virtual void AddLoginImpl(const webkit_glue::PasswordForm& form) = 0;
140   // Synchronous implementation to update the given login.
141   virtual void UpdateLoginImpl(const webkit_glue::PasswordForm& form) = 0;
142   // Synchronous implementation to remove the given login.
143   virtual void RemoveLoginImpl(const webkit_glue::PasswordForm& form) = 0;
144   // Synchronous implementation to remove the given logins.
145   virtual void RemoveLoginsCreatedBetweenImpl(const base::Time& delete_begin,
146                                               const base::Time& delete_end) = 0;
147   // Should find all PasswordForms with the same signon_realm. The results
148   // will then be scored by the PasswordFormManager. Once they are found
149   // (or not), the consumer should be notified.
150   virtual void GetLoginsImpl(GetLoginsRequest* request,
151                              const webkit_glue::PasswordForm& form) = 0;
152   // Finds all non-blacklist PasswordForms, and notifies the consumer.
153   virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) = 0;
154   // Finds all blacklist PasswordForms, and notifies the consumer.
155   virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0;
156 
157   // Finds all non-blacklist PasswordForms, and fills the vector.
158   virtual bool FillAutofillableLogins(
159       std::vector<webkit_glue::PasswordForm*>* forms) = 0;
160   // Finds all blacklist PasswordForms, and fills the vector.
161   virtual bool FillBlacklistLogins(
162       std::vector<webkit_glue::PasswordForm*>* forms) = 0;
163 
164   // Dispatches the result to the PasswordStoreConsumer on the original caller's
165   // thread so the callback can be executed there.  This should be the UI
166   // thread.
167   virtual void ForwardLoginsResult(GetLoginsRequest* request);
168 
169   // Schedule the given |func| to be run in the PasswordStore's own thread with
170   // responses delivered to |consumer| on the current thread.
171   template<typename BackendFunc>
172   Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer);
173 
174   // Schedule the given |func| to be run in the PasswordStore's own thread with
175   // argument |a| and responses delivered to |consumer| on the current thread.
176   template<typename BackendFunc, typename ArgA>
177   Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer,
178                   const ArgA& a);
179 
180  private:
181   // Wrapper method called on the destination thread (DB for non-mac) that calls
182   // the method specified in |task| and then calls back into the source thread
183   // to notify observers that the password store may have been modified via
184   // NotifyLoginsChanged(). Note that there is no guarantee that the called
185   // method will actually modify the password store data. |task| may not be
186   // NULL. This method owns and will delete |task|.
187   void WrapModificationTask(Task* task);
188 
189   // Post a message to the UI thread to run NotifyLoginsChanged(). Called by
190   // WrapModificationTask() above, and split out as a separate method so that
191   // password sync can call it as well after synchronously updating the password
192   // store.
193   void PostNotifyLoginsChanged();
194 
195   // Called by WrapModificationTask() once the underlying data-modifying
196   // operation has been performed. Notifies observers that password store data
197   // may have been changed.
198   void NotifyLoginsChanged();
199 
200   // The observers.
201   ObserverList<Observer> observers_;
202 
203   DISALLOW_COPY_AND_ASSIGN(PasswordStore);
204 };
205 
206 #endif  // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_
207