Home | History | Annotate | Download | only in password_manager
      1 // Copyright (c) 2012 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 
      8 #include <vector>
      9 
     10 #include "base/callback.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "base/observer_list.h"
     13 #include "base/threading/thread.h"
     14 #include "base/time/time.h"
     15 #include "chrome/browser/common/cancelable_request.h"
     16 #include "chrome/common/cancelable_task_tracker.h"
     17 #include "components/browser_context_keyed_service/refcounted_browser_context_keyed_service.h"
     18 
     19 class PasswordStore;
     20 class PasswordStoreConsumer;
     21 class PasswordSyncableService;
     22 class Task;
     23 
     24 namespace autofill {
     25 struct PasswordForm;
     26 }
     27 
     28 namespace browser_sync {
     29 class PasswordChangeProcessor;
     30 class PasswordDataTypeController;
     31 class PasswordModelAssociator;
     32 class PasswordModelWorker;
     33 }
     34 
     35 namespace passwords_helper {
     36 void AddLogin(PasswordStore* store, const autofill::PasswordForm& form);
     37 void RemoveLogin(PasswordStore* store, const autofill::PasswordForm& form);
     38 void UpdateLogin(PasswordStore* store, const autofill::PasswordForm& form);
     39 }
     40 
     41 // Interface for storing form passwords in a platform-specific secure way.
     42 // The login request/manipulation API is not threadsafe and must be used
     43 // from the UI thread.
     44 class PasswordStore
     45     : public RefcountedBrowserContextKeyedService,
     46       public CancelableRequestProvider {
     47  public:
     48   typedef base::Callback<
     49       void(Handle, const std::vector<autofill::PasswordForm*>&)>
     50       GetLoginsCallback;
     51 
     52   // Whether or not it's acceptable for Chrome to request access to locked
     53   // passwords, which requires prompting the user for permission.
     54   enum AuthorizationPromptPolicy {
     55     ALLOW_PROMPT,
     56     DISALLOW_PROMPT
     57   };
     58 
     59   // PasswordForm vector elements are meant to be owned by the
     60   // PasswordStoreConsumer. However, if the request is canceled after the
     61   // allocation, then the request must take care of the deletion.
     62   class GetLoginsRequest
     63       : public CancelableRequest1<GetLoginsCallback,
     64                                   std::vector<autofill::PasswordForm*> > {
     65    public:
     66     explicit GetLoginsRequest(const GetLoginsCallback& callback);
     67 
     68     void set_ignore_logins_cutoff(const base::Time& cutoff) {
     69       ignore_logins_cutoff_ = cutoff;
     70     }
     71 
     72     // Removes any logins in the result list that were saved before the cutoff.
     73     void ApplyIgnoreLoginsCutoff();
     74 
     75    protected:
     76     virtual ~GetLoginsRequest();
     77 
     78    private:
     79     // See GetLogins(). Logins older than this will be removed from the reply.
     80     base::Time ignore_logins_cutoff_;
     81 
     82     DISALLOW_COPY_AND_ASSIGN(GetLoginsRequest);
     83   };
     84 
     85   // An interface used to notify clients (observers) of this object that data in
     86   // the password store has changed. Register the observer via
     87   // PasswordStore::SetObserver.
     88   class Observer {
     89    public:
     90     // Notifies the observer that password data changed in some way.
     91     virtual void OnLoginsChanged() = 0;
     92 
     93    protected:
     94     virtual ~Observer() {}
     95   };
     96 
     97   PasswordStore();
     98 
     99   // Reimplement this to add custom initialization. Always call this too.
    100   virtual bool Init();
    101 
    102   // Adds the given PasswordForm to the secure password store asynchronously.
    103   virtual void AddLogin(const autofill::PasswordForm& form);
    104 
    105   // Updates the matching PasswordForm in the secure password store (async).
    106   void UpdateLogin(const autofill::PasswordForm& form);
    107 
    108   // Removes the matching PasswordForm from the secure password store (async).
    109   void RemoveLogin(const autofill::PasswordForm& form);
    110 
    111   // Removes all logins created in the given date range.
    112   void RemoveLoginsCreatedBetween(const base::Time& delete_begin,
    113                                   const base::Time& delete_end);
    114 
    115   // Searches for a matching PasswordForm and returns a ID so the async request
    116   // can be tracked. Implement the PasswordStoreConsumer interface to be
    117   // notified on completion. |prompt_policy| indicates whether it's permissible
    118   // to prompt the user to authorize access to locked passwords. This argument
    119   // is only used on platforms that support prompting the user for access (such
    120   // as Mac OS). NOTE: This means that this method can return different results
    121   // depending on the value of |prompt_policy|.
    122   virtual CancelableTaskTracker::TaskId GetLogins(
    123       const autofill::PasswordForm& form,
    124       AuthorizationPromptPolicy prompt_policy,
    125       PasswordStoreConsumer* consumer);
    126 
    127   // Gets the complete list of PasswordForms that are not blacklist entries--and
    128   // are thus auto-fillable--and returns a handle so the async request can be
    129   // tracked. Implement the PasswordStoreConsumer interface to be notified on
    130   // completion.
    131   Handle GetAutofillableLogins(PasswordStoreConsumer* consumer);
    132 
    133   // Gets the complete list of PasswordForms that are blacklist entries, and
    134   // returns a handle so the async request can be tracked. Implement the
    135   // PasswordStoreConsumer interface to be notified on completion.
    136   Handle GetBlacklistLogins(PasswordStoreConsumer* consumer);
    137 
    138   // Reports usage metrics for the database.
    139   void ReportMetrics();
    140 
    141   // Adds an observer to be notified when the password store data changes.
    142   void AddObserver(Observer* observer);
    143 
    144   // Removes |observer| from the observer list.
    145   void RemoveObserver(Observer* observer);
    146 
    147  protected:
    148   friend class base::RefCountedThreadSafe<PasswordStore>;
    149   // Sync's interaction with password store needs to be syncrhonous.
    150   // Since the synchronous methods are private these classes are made
    151   // as friends. This can be fixed by moving the private impl to a new
    152   // class. See http://crbug.com/307750
    153   friend class browser_sync::PasswordChangeProcessor;
    154   friend class browser_sync::PasswordDataTypeController;
    155   friend class browser_sync::PasswordModelAssociator;
    156   friend class browser_sync::PasswordModelWorker;
    157   friend class PasswordSyncableService;
    158   friend void passwords_helper::AddLogin(PasswordStore*,
    159                                          const autofill::PasswordForm&);
    160   friend void passwords_helper::RemoveLogin(PasswordStore*,
    161                                             const autofill::PasswordForm&);
    162   friend void passwords_helper::UpdateLogin(PasswordStore*,
    163                                             const autofill::PasswordForm&);
    164 
    165   virtual ~PasswordStore();
    166 
    167   // Provided to allow subclasses to extend GetLoginsRequest if additional info
    168   // is needed between a call and its Impl.
    169   virtual GetLoginsRequest* NewGetLoginsRequest(
    170       const GetLoginsCallback& callback);
    171 
    172   // Schedule the given |task| to be run in the PasswordStore's task thread. By
    173   // default it uses DB thread, but sub classes can override to use other
    174   // threads.
    175   virtual bool ScheduleTask(const base::Closure& task);
    176 
    177   // These will be run in PasswordStore's own thread.
    178   // Synchronous implementation that reports usage metrics.
    179   virtual void ReportMetricsImpl() = 0;
    180   // Synchronous implementation to add the given login.
    181   virtual void AddLoginImpl(const autofill::PasswordForm& form) = 0;
    182   // Synchronous implementation to update the given login.
    183   virtual void UpdateLoginImpl(const autofill::PasswordForm& form) = 0;
    184   // Synchronous implementation to remove the given login.
    185   virtual void RemoveLoginImpl(const autofill::PasswordForm& form) = 0;
    186   // Synchronous implementation to remove the given logins.
    187   virtual void RemoveLoginsCreatedBetweenImpl(const base::Time& delete_begin,
    188                                               const base::Time& delete_end) = 0;
    189 
    190   typedef base::Callback<void(const std::vector<autofill::PasswordForm*>&)>
    191       ConsumerCallbackRunner;  // Owns all PasswordForms in the vector.
    192 
    193   // Should find all PasswordForms with the same signon_realm. The results
    194   // will then be scored by the PasswordFormManager. Once they are found
    195   // (or not), the consumer should be notified.
    196   virtual void GetLoginsImpl(
    197       const autofill::PasswordForm& form,
    198       AuthorizationPromptPolicy prompt_policy,
    199       const ConsumerCallbackRunner& callback_runner) = 0;
    200 
    201   // Finds all non-blacklist PasswordForms, and notifies the consumer.
    202   virtual void GetAutofillableLoginsImpl(GetLoginsRequest* request) = 0;
    203   // Finds all blacklist PasswordForms, and notifies the consumer.
    204   virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0;
    205 
    206   // Finds all non-blacklist PasswordForms, and fills the vector.
    207   virtual bool FillAutofillableLogins(
    208       std::vector<autofill::PasswordForm*>* forms) = 0;
    209   // Finds all blacklist PasswordForms, and fills the vector.
    210   virtual bool FillBlacklistLogins(
    211       std::vector<autofill::PasswordForm*>* forms) = 0;
    212 
    213   // Dispatches the result to the PasswordStoreConsumer on the original caller's
    214   // thread so the callback can be executed there. This should be the UI thread.
    215   virtual void ForwardLoginsResult(GetLoginsRequest* request);
    216 
    217   // Log UMA stats for number of bulk deletions.
    218   void LogStatsForBulkDeletion(int num_deletions);
    219 
    220  private:
    221   // Schedule the given |func| to be run in the PasswordStore's own thread with
    222   // responses delivered to |consumer| on the current thread.
    223   template<typename BackendFunc>
    224   Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer);
    225 
    226   // Schedule the given |func| to be run in the PasswordStore's own thread with
    227   // form |form| and responses delivered to |consumer| on the current thread.
    228   // See GetLogins() for more information on |ignore_logins_cutoff|.
    229   template<typename BackendFunc>
    230   Handle Schedule(BackendFunc func,
    231                   PasswordStoreConsumer* consumer,
    232                   const autofill::PasswordForm& form,
    233                   const base::Time& ignore_logins_cutoff);
    234 
    235   // Wrapper method called on the destination thread (DB for non-mac) that
    236   // invokes |task| and then calls back into the source thread to notify
    237   // observers that the password store may have been modified via
    238   // NotifyLoginsChanged(). Note that there is no guarantee that the called
    239   // method will actually modify the password store data.
    240   virtual void WrapModificationTask(base::Closure task);
    241 
    242   // Post a message to the UI thread to run NotifyLoginsChanged(). Called by
    243   // WrapModificationTask() above, and split out as a separate method so that
    244   // password sync can call it as well after synchronously updating the password
    245   // store.
    246   void PostNotifyLoginsChanged();
    247 
    248   // Called by WrapModificationTask() once the underlying data-modifying
    249   // operation has been performed. Notifies observers that password store data
    250   // may have been changed.
    251   void NotifyLoginsChanged();
    252 
    253   // The observers.
    254   ObserverList<Observer> observers_;
    255 
    256   DISALLOW_COPY_AND_ASSIGN(PasswordStore);
    257 };
    258 
    259 #endif  // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_H_
    260