| // 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/memory/ref_counted.h" |
| #include "base/observer_list.h" |
| #include "base/threading/thread.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/common/cancelable_request.h" |
| #include "chrome/common/cancelable_task_tracker.h" |
| #include "components/browser_context_keyed_service/refcounted_browser_context_keyed_service.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 RefcountedBrowserContextKeyedService, |
| public CancelableRequestProvider { |
| public: |
| typedef base::Callback< |
| void(Handle, const std::vector<autofill::PasswordForm*>&)> |
| GetLoginsCallback; |
| |
| // 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 CancelableRequest1<GetLoginsCallback, |
| std::vector<autofill::PasswordForm*> > { |
| public: |
| explicit GetLoginsRequest(const GetLoginsCallback& callback); |
| |
| 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(); |
| |
| protected: |
| virtual ~GetLoginsRequest(); |
| |
| private: |
| // See GetLogins(). Logins older than this will be removed from the reply. |
| base::Time ignore_logins_cutoff_; |
| |
| 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(); |
| |
| // 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 returns a ID so the async request |
| // can be tracked. Implement the PasswordStoreConsumer interface to be |
| // notified on completion. |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 CancelableTaskTracker::TaskId 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--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>; |
| // Sync's interaction with password store needs to be syncrhonous. |
| // 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&); |
| |
| virtual ~PasswordStore(); |
| |
| // Provided to allow subclasses to extend GetLoginsRequest if additional info |
| // is needed between a call and its Impl. |
| virtual GetLoginsRequest* NewGetLoginsRequest( |
| const GetLoginsCallback& callback); |
| |
| // Schedule the given |task| to be run in the PasswordStore's task thread. By |
| // default it uses DB thread, but sub classes can override to use other |
| // threads. |
| virtual bool 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 autofill::PasswordForm& form) = 0; |
| // Synchronous implementation to update the given login. |
| virtual void UpdateLoginImpl(const autofill::PasswordForm& form) = 0; |
| // Synchronous implementation to remove the given login. |
| virtual void RemoveLoginImpl(const autofill::PasswordForm& form) = 0; |
| // Synchronous implementation to remove the given logins. |
| virtual void 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); |
| |
| 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> |
| Handle Schedule(BackendFunc func, PasswordStoreConsumer* consumer); |
| |
| // Schedule the given |func| to be run in the PasswordStore's own thread with |
| // form |form| and responses delivered to |consumer| on the current thread. |
| // See GetLogins() for more information on |ignore_logins_cutoff|. |
| template<typename BackendFunc> |
| Handle Schedule(BackendFunc func, |
| PasswordStoreConsumer* consumer, |
| const autofill::PasswordForm& form, |
| const base::Time& ignore_logins_cutoff); |
| |
| // 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(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_ |