Home | History | Annotate | Download | only in password_manager
      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:
     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