| // Copyright 2014 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 COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_H_ |
| #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_H_ |
| |
| #include <memory> |
| #include <ostream> |
| #include <string> |
| #include <vector> |
| |
| #include "base/callback.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/macros.h" |
| #include "base/observer_list_threadsafe.h" |
| #include "base/sequenced_task_runner.h" |
| #include "base/time/time.h" |
| #include "build/build_config.h" |
| #include "components/keyed_service/core/refcounted_keyed_service.h" |
| #include "components/password_manager/core/browser/password_store_change.h" |
| #include "components/password_manager/core/browser/password_store_sync.h" |
| #include "components/sync/model/syncable_service.h" |
| |
| // TODO(crbug.com/706392): Fix password reuse detection for Android. |
| #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) |
| #include "components/password_manager/core/browser/hash_password_manager.h" |
| #include "components/password_manager/core/browser/password_manager_metrics_util.h" |
| #include "components/password_manager/core/browser/password_reuse_detector.h" |
| #include "components/password_manager/core/browser/password_reuse_detector_consumer.h" |
| #endif |
| |
| class PrefService; |
| |
| namespace autofill { |
| struct FormData; |
| struct PasswordForm; |
| } |
| |
| namespace syncer { |
| class ModelTypeControllerDelegate; |
| class ProxyModelTypeControllerDelegate; |
| class SyncableService; |
| } |
| |
| namespace password_manager { |
| |
| class AffiliatedMatchHelper; |
| class PasswordStoreConsumer; |
| class PasswordStoreSigninNotifier; |
| class PasswordSyncableService; |
| class PasswordSyncBridge; |
| struct InteractionsStats; |
| |
| #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) |
| using PasswordHashDataList = base::Optional<std::vector<PasswordHashData>>; |
| #endif |
| |
| // 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. |
| // Implementations, however, should carry out most tasks asynchronously on a |
| // background sequence: the base class provides functionality to facilitate |
| // this. I/O heavy initialization should also be performed asynchronously in |
| // this manner. If this deferred initialization fails, all subsequent method |
| // calls should fail without side effects, return no data, and send no |
| // notifications. PasswordStoreSync is a hidden base class because only |
| // PasswordSyncableService needs to access these methods. |
| class PasswordStore : protected PasswordStoreSync, |
| public RefcountedKeyedService { |
| public: |
| // 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() {} |
| }; |
| |
| // Represents a subset of autofill::PasswordForm needed for credential |
| // retrievals. |
| struct FormDigest { |
| FormDigest(autofill::PasswordForm::Scheme scheme, |
| const std::string& signon_realm, |
| const GURL& origin); |
| explicit FormDigest(const autofill::PasswordForm& form); |
| explicit FormDigest(const autofill::FormData& form); |
| FormDigest(const FormDigest& other); |
| FormDigest(FormDigest&& other); |
| FormDigest& operator=(const FormDigest& other); |
| FormDigest& operator=(FormDigest&& other); |
| bool operator==(const FormDigest& other) const; |
| |
| autofill::PasswordForm::Scheme scheme; |
| std::string signon_realm; |
| GURL origin; |
| }; |
| |
| PasswordStore(); |
| |
| // Reimplement this to add custom initialization. Always call this too on the |
| // UI thread. |
| virtual bool Init(const syncer::SyncableService::StartSyncFlare& flare, |
| PrefService* prefs); |
| |
| // RefcountedKeyedService: |
| void ShutdownOnUIThread() override; |
| |
| // Sets the affiliation-based match |helper| that will be used by subsequent |
| // GetLogins() calls to return credentials stored not only for the requested |
| // sign-on realm, but also for affiliated Android applications. If |helper| is |
| // null, clears the the currently set helper if any. Unless a helper is set, |
| // affiliation-based matching is disabled. The passed |helper| must already be |
| // initialized if it is non-null. |
| void SetAffiliatedMatchHelper(std::unique_ptr<AffiliatedMatchHelper> helper); |
| AffiliatedMatchHelper* affiliated_match_helper() const { |
| return affiliated_match_helper_.get(); |
| } |
| |
| // Toggles whether or not to propagate password changes in Android credentials |
| // to the affiliated Web credentials. |
| void enable_propagating_password_changes_to_web_credentials(bool enabled) { |
| is_propagating_password_changes_to_web_credentials_enabled_ = enabled; |
| } |
| |
| // 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). |
| // If any of the primary key fields (signon_realm, origin, username_element, |
| // username_value, password_element) are updated, then the second version of |
| // the method must be used that takes |old_primary_key|, i.e., the old values |
| // for the primary key fields (the rest of the fields are ignored). |
| virtual void UpdateLogin(const autofill::PasswordForm& form); |
| virtual void UpdateLoginWithPrimaryKey( |
| const autofill::PasswordForm& new_form, |
| const autofill::PasswordForm& old_primary_key); |
| |
| // Removes the matching PasswordForm from the secure password store (async). |
| virtual void RemoveLogin(const autofill::PasswordForm& form); |
| |
| // Remove all logins whose origins match the given filter and that were |
| // created |
| // in the given date range. |completion| will be posted to the |
| // |main_task_runner_| after deletions have been completed and notification |
| // have been sent out. |
| void RemoveLoginsByURLAndTime( |
| const base::Callback<bool(const GURL&)>& url_filter, |
| base::Time delete_begin, |
| base::Time delete_end, |
| const base::Closure& completion); |
| |
| // Removes all logins created in the given date range. If |completion| is not |
| // null, it will be posted to the |main_task_runner_| after deletions have |
| // been completed and notification have been sent out. |
| void RemoveLoginsCreatedBetween(base::Time delete_begin, |
| base::Time delete_end, |
| const base::Closure& completion); |
| |
| // Removes all logins synced in the given date range. |
| void RemoveLoginsSyncedBetween(base::Time delete_begin, |
| base::Time delete_end); |
| |
| // Removes all the stats created in the given date range. |
| // If |origin_filter| is not null, only statistics for matching origins are |
| // removed. If |completion| is not null, it will be posted to the |
| // |main_task_runner_| after deletions have been completed. |
| // Should be called on the UI thread. |
| void RemoveStatisticsByOriginAndTime( |
| const base::Callback<bool(const GURL&)>& origin_filter, |
| base::Time delete_begin, |
| base::Time delete_end, |
| const base::Closure& completion); |
| |
| // Sets the 'skip_zero_click' flag for all logins in the database that match |
| // |origin_filter| to 'true'. |completion| will be posted to the |
| // |main_task_runner_| after these modifications are completed and |
| // notifications are sent out. |
| void DisableAutoSignInForOrigins( |
| const base::Callback<bool(const GURL&)>& origin_filter, |
| const base::Closure& completion); |
| |
| // Searches for a matching PasswordForm, and notifies |consumer| on |
| // completion. The request will be cancelled if the consumer is destroyed. |
| virtual void GetLogins(const FormDigest& form, |
| PasswordStoreConsumer* consumer); |
| |
| // Returns all stored credentials with SCHEME_HTTP that have a realm whose |
| // organization-identifying name -- that is, the first domain name label below |
| // the effective TLD -- matches that of |signon_realm|. Notifies |consumer| on |
| // completion. The request will be cancelled if the consumer is destroyed. |
| // |
| // WARNING: This is *NOT* PSL (Public Suffix List) matching. The logins |
| // returned by this method are not safe to be filled into the observed form. |
| // |
| // For example, the organization-identifying name of "https://foo.example.org" |
| // is `example`, and logins will be returned for "http://bar.example.co.uk", |
| // but not for "http://notexample.com" or "https://example.foo.com". |
| virtual void GetLoginsForSameOrganizationName( |
| const std::string& signon_realm, |
| 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. |
| virtual void GetAutofillableLogins(PasswordStoreConsumer* consumer); |
| |
| // Same as above, but also fills in affiliation and branding information for |
| // Android credentials. |
| virtual void GetAutofillableLoginsWithAffiliationAndBrandingInformation( |
| 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. |
| virtual void GetBlacklistLogins(PasswordStoreConsumer* consumer); |
| |
| // Same as above, but also fills in affiliation and branding information for |
| // Android credentials. |
| virtual void GetBlacklistLoginsWithAffiliationAndBrandingInformation( |
| PasswordStoreConsumer* consumer); |
| |
| // Gets the complete list of PasswordForms, regardless of their blacklist |
| // status. Also fills in affiliation and branding information for Android |
| // credentials. |
| virtual void GetAllLoginsWithAffiliationAndBrandingInformation( |
| PasswordStoreConsumer* consumer); |
| |
| // Reports usage metrics for the database. |sync_username|, and |
| // |custom_passphrase_sync_enabled|, and |is_under_advanced_protection| |
| // determine some of the UMA stats that may be reported. |
| virtual void ReportMetrics(const std::string& sync_username, |
| bool custom_passphrase_sync_enabled, |
| bool is_under_advanced_protection); |
| |
| // Adds or replaces the statistics for the domain |stats.origin_domain|. |
| void AddSiteStats(const InteractionsStats& stats); |
| |
| // Removes the statistics for |origin_domain|. |
| void RemoveSiteStats(const GURL& origin_domain); |
| |
| // Retrieves the statistics for all sites and notifies |consumer| on |
| // completion. The request will be cancelled if the consumer is destroyed. |
| void GetAllSiteStats(PasswordStoreConsumer* consumer); |
| |
| // Retrieves the statistics for |origin_domain| and notifies |consumer| on |
| // completion. The request will be cancelled if the consumer is destroyed. |
| void GetSiteStats(const GURL& origin_domain, PasswordStoreConsumer* consumer); |
| |
| // 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); |
| |
| // Schedules the given |task| to be run on the PasswordStore's TaskRunner. |
| bool ScheduleTask(base::OnceClosure task); |
| |
| scoped_refptr<base::SequencedTaskRunner> GetBackgroundTaskRunner(); |
| |
| // Returns true iff initialization was successful. |
| virtual bool IsAbleToSavePasswords() const; |
| |
| base::WeakPtr<syncer::SyncableService> GetPasswordSyncableService(); |
| |
| // For sync codebase only: instantiates a proxy controller delegate to |
| // interact with PasswordSyncBridge. Must be called from the UI thread. |
| std::unique_ptr<syncer::ProxyModelTypeControllerDelegate> |
| CreateSyncControllerDelegate(); |
| |
| // TODO(crbug.com/706392): Fix password reuse detection for Android. |
| #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) |
| // Immediately called after |Init()| to retrieve password hash data for |
| // reuse detection. |
| void PreparePasswordHashData(const std::string& sync_username); |
| |
| // Checks that some suffix of |input| equals to a password saved on another |
| // registry controlled domain than |domain|. |
| // If such suffix is found, |consumer|->OnReuseFound() is called on the same |
| // sequence on which this method is called. |
| // |consumer| must not be null. |
| virtual void CheckReuse(const base::string16& input, |
| const std::string& domain, |
| PasswordReuseDetectorConsumer* consumer); |
| |
| // Saves |username| and a hash of |password| for Gaia password reuse checking. |
| // |event| is used for metric logging and for distinguishing sync password |
| // hash change event and other non-sync Gaia password change event. |
| virtual void SaveGaiaPasswordHash(const std::string& username, |
| const base::string16& password, |
| metrics_util::SyncPasswordHashChange event); |
| |
| // Saves |username| and a hash of |password| for enterprise password reuse |
| // checking. |
| virtual void SaveEnterprisePasswordHash(const std::string& username, |
| const base::string16& password); |
| |
| // Saves |sync_password_data| for sync password reuse checking. |
| // |event| is used for metric logging. |
| virtual void SaveSyncPasswordHash(const PasswordHashData& sync_password_data, |
| metrics_util::SyncPasswordHashChange event); |
| |
| // Clears the saved Gaia password hash for |username|. |
| virtual void ClearGaiaPasswordHash(const std::string& username); |
| |
| // Clears all the Gaia password hash. |
| virtual void ClearAllGaiaPasswordHash(); |
| |
| // Clears all (non-Gaia) enterprise password hash. |
| virtual void ClearAllEnterprisePasswordHash(); |
| |
| // Shouldn't be called more than once, |notifier| must be not nullptr. |
| void SetPasswordStoreSigninNotifier( |
| std::unique_ptr<PasswordStoreSigninNotifier> notifier); |
| |
| // Schedules the update of password hashes used by reuse detector. |
| void SchedulePasswordHashUpdate(bool should_log_metrics); |
| |
| // Schedules the update of enterprise login and change password URLs. |
| // These URLs are used in enterprise password reuse detection. |
| void ScheduleEnterprisePasswordURLUpdate(); |
| |
| #endif |
| |
| protected: |
| friend class base::RefCountedThreadSafe<PasswordStore>; |
| |
| typedef base::Callback<PasswordStoreChangeList(void)> ModificationTask; |
| |
| // Represents a single GetLogins() request. Implements functionality to filter |
| // results and send them to the consumer on the consumer's message loop. |
| class GetLoginsRequest { |
| public: |
| explicit GetLoginsRequest(PasswordStoreConsumer* consumer); |
| ~GetLoginsRequest(); |
| |
| // Removes any credentials in |results| that were saved before the cutoff, |
| // then notifies the consumer with the remaining results. |
| // Note that if this method is not called before destruction, the consumer |
| // will not be notified. |
| void NotifyConsumerWithResults( |
| std::vector<std::unique_ptr<autofill::PasswordForm>> results); |
| |
| void NotifyWithSiteStatistics(std::vector<InteractionsStats> stats); |
| |
| void set_ignore_logins_cutoff(base::Time cutoff) { |
| ignore_logins_cutoff_ = cutoff; |
| } |
| |
| private: |
| // See GetLogins(). Logins older than this will be removed from the reply. |
| base::Time ignore_logins_cutoff_; |
| |
| scoped_refptr<base::SequencedTaskRunner> origin_task_runner_; |
| base::WeakPtr<PasswordStoreConsumer> consumer_weak_; |
| |
| DISALLOW_COPY_AND_ASSIGN(GetLoginsRequest); |
| }; |
| |
| // TODO(crbug.com/706392): Fix password reuse detection for Android. |
| #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) |
| // Represents a single CheckReuse() request. Implements functionality to |
| // listen to reuse events and propagate them to |consumer| on the sequence on |
| // which CheckReuseRequest is created. |
| class CheckReuseRequest : public PasswordReuseDetectorConsumer { |
| public: |
| // |consumer| must not be null. |
| explicit CheckReuseRequest(PasswordReuseDetectorConsumer* consumer); |
| ~CheckReuseRequest() override; |
| |
| // PasswordReuseDetectorConsumer |
| void OnReuseFound( |
| size_t password_length, |
| base::Optional<PasswordHashData> reused_protected_password_hash, |
| const std::vector<std::string>& matching_domains, |
| int saved_passwords) override; |
| |
| private: |
| const scoped_refptr<base::SequencedTaskRunner> origin_task_runner_; |
| const base::WeakPtr<PasswordReuseDetectorConsumer> consumer_weak_; |
| |
| DISALLOW_COPY_AND_ASSIGN(CheckReuseRequest); |
| }; |
| #endif |
| |
| // Status of PasswordStore::Init(). |
| enum class InitStatus { |
| // Initialization status is still not determined (init hasn't started or |
| // finished yet). |
| kUnknown, |
| // Initialization is successfully finished. |
| kSuccess, |
| // There was an error during initialization and PasswordStore is not ready |
| // to save or get passwords. |
| // Removing passwords may still work. |
| kFailure, |
| }; |
| |
| ~PasswordStore() override; |
| |
| // Create a TaskRunner to be saved in |background_task_runner_|. |
| virtual scoped_refptr<base::SequencedTaskRunner> CreateBackgroundTaskRunner() |
| const; |
| |
| // Creates PasswordSyncableService and PasswordReuseDetector instances on the |
| // background sequence. Subclasses can add more logic. Returns true on |
| // success. |
| virtual bool InitOnBackgroundSequence( |
| const syncer::SyncableService::StartSyncFlare& flare); |
| |
| // Methods below will be run in PasswordStore's own sequence. |
| // Synchronous implementation that reports usage metrics. |
| virtual void ReportMetricsImpl(const std::string& sync_username, |
| bool custom_passphrase_sync_enabled) = 0; |
| |
| // Synchronous implementation to remove the given logins. |
| virtual PasswordStoreChangeList RemoveLoginsByURLAndTimeImpl( |
| const base::Callback<bool(const GURL&)>& url_filter, |
| base::Time delete_begin, |
| base::Time delete_end) = 0; |
| |
| // Synchronous implementation to remove the given logins. |
| virtual PasswordStoreChangeList RemoveLoginsCreatedBetweenImpl( |
| base::Time delete_begin, |
| base::Time delete_end) = 0; |
| |
| // Synchronous implementation to remove the given logins. |
| virtual PasswordStoreChangeList RemoveLoginsSyncedBetweenImpl( |
| base::Time delete_begin, |
| base::Time delete_end) = 0; |
| |
| // Synchronous implementation to remove the statistics. |
| virtual bool RemoveStatisticsByOriginAndTimeImpl( |
| const base::Callback<bool(const GURL&)>& origin_filter, |
| base::Time delete_begin, |
| base::Time delete_end) = 0; |
| |
| // Synchronous implementation to disable auto sign-in. |
| virtual PasswordStoreChangeList DisableAutoSignInForOriginsImpl( |
| const base::Callback<bool(const GURL&)>& origin_filter) = 0; |
| |
| // Finds all PasswordForms with a signon_realm that is equal to, or is a |
| // PSL-match to that of |form|, and takes care of notifying the consumer with |
| // the results when done. |
| // Note: subclasses should implement FillMatchingLogins() instead. This needs |
| // to be virtual only because asynchronous behavior in PasswordStoreWin. |
| // TODO(engedy): Make this non-virtual once https://crbug.com/78830 is fixed. |
| virtual void GetLoginsImpl(const FormDigest& form, |
| std::unique_ptr<GetLoginsRequest> request); |
| |
| // Synchronous implementation provided by subclasses to add the given login. |
| virtual PasswordStoreChangeList AddLoginImpl( |
| const autofill::PasswordForm& form) = 0; |
| |
| // Synchronous implementation provided by subclasses to update the given |
| // login. |
| virtual PasswordStoreChangeList UpdateLoginImpl( |
| const autofill::PasswordForm& form) = 0; |
| |
| // Synchronous implementation provided by subclasses to remove the given |
| // login. |
| virtual PasswordStoreChangeList RemoveLoginImpl( |
| const autofill::PasswordForm& form) = 0; |
| |
| // Finds and returns all PasswordForms with the same signon_realm as |form|, |
| // or with a signon_realm that is a PSL-match to that of |form|. |
| virtual std::vector<std::unique_ptr<autofill::PasswordForm>> |
| FillMatchingLogins(const FormDigest& form) = 0; |
| |
| // Finds and returns all organization-name-matching logins, or returns an |
| // empty list on error. |
| virtual std::vector<std::unique_ptr<autofill::PasswordForm>> |
| FillLoginsForSameOrganizationName(const std::string& signon_realm) = 0; |
| |
| // Synchronous implementation for manipulating with statistics. |
| virtual void AddSiteStatsImpl(const InteractionsStats& stats) = 0; |
| virtual void RemoveSiteStatsImpl(const GURL& origin_domain) = 0; |
| virtual std::vector<InteractionsStats> GetAllSiteStatsImpl() = 0; |
| virtual std::vector<InteractionsStats> GetSiteStatsImpl( |
| const GURL& origin_domain) = 0; |
| |
| // Log UMA stats for number of bulk deletions. |
| void LogStatsForBulkDeletion(int num_deletions); |
| |
| // Log UMA stats for password deletions happening on clear browsing data |
| // since first sync during rollback. |
| void LogStatsForBulkDeletionDuringRollback(int num_deletions); |
| |
| // PasswordStoreSync: |
| PasswordStoreChangeList AddLoginSync( |
| const autofill::PasswordForm& form) override; |
| PasswordStoreChangeList UpdateLoginSync( |
| const autofill::PasswordForm& form) override; |
| PasswordStoreChangeList RemoveLoginSync( |
| const autofill::PasswordForm& form) override; |
| |
| // 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) override; |
| |
| // TODO(crbug.com/706392): Fix password reuse detection for Android. |
| #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) |
| // Saves |username| and a hash of |password| for password reuse checking. |
| // |is_gaia_password| indicates if it is a Gaia account. |event| is used for |
| // metric logging. |
| void SaveProtectedPasswordHash(const std::string& username, |
| const base::string16& password, |
| bool is_gaia_password, |
| metrics_util::SyncPasswordHashChange event); |
| |
| // Synchronous implementation of CheckReuse(). |
| void CheckReuseImpl(std::unique_ptr<CheckReuseRequest> request, |
| const base::string16& input, |
| const std::string& domain); |
| |
| // Synchronous implementation of SaveProtectedPasswordHash(). |
| // |should_log_metrics| indicates whether to log the counts of captured |
| // password hashes. |
| void SaveProtectedPasswordHashImpl( |
| PasswordHashDataList protected_password_data_list, |
| bool should_log_metrics); |
| |
| // Propagates enterprise login urls and change password url to |
| // |reuse_detector_|. |
| void SaveEnterprisePasswordURLs( |
| const std::vector<GURL>& enterprise_login_urls, |
| const GURL& enterprise_change_password_url); |
| |
| // Synchronous implementation of ClearGaiaPasswordHash(...). |
| void ClearGaiaPasswordHashImpl(const std::string& username); |
| |
| // Synchronous implementation of ClearAllGaiaPasswordHashImpl(). |
| void ClearAllGaiaPasswordHashImpl(); |
| |
| // Synchronous implementation of ClearAllEnterprisePasswordHashImpl(). |
| void ClearAllEnterprisePasswordHashImpl(); |
| #endif |
| |
| scoped_refptr<base::SequencedTaskRunner> main_task_runner() const { |
| return main_task_runner_; |
| } |
| |
| scoped_refptr<base::SequencedTaskRunner> background_task_runner() const { |
| return background_task_runner_; |
| } |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(PasswordStoreTest, |
| UpdatePasswordsStoredForAffiliatedWebsites); |
| |
| // Called on the main thread after initialization is completed. |
| // |success| is true if initialization was successful. Sets the |
| // |init_status_|. |
| void OnInitCompleted(bool success); |
| |
| // Schedule the given |func| to be run in the PasswordStore's own sequence |
| // with responses delivered to |consumer| on the current sequence. |
| void Schedule(void (PasswordStore::*func)(std::unique_ptr<GetLoginsRequest>), |
| PasswordStoreConsumer* consumer); |
| |
| // Wrapper method called on the destination sequence that invokes |task| and |
| // then calls back into the source sequence 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. |
| void WrapModificationTask(ModificationTask task); |
| |
| // Temporary specializations of WrapModificationTask for a better stack trace. |
| void AddLoginInternal(const autofill::PasswordForm& form); |
| void UpdateLoginInternal(const autofill::PasswordForm& form); |
| void RemoveLoginInternal(const autofill::PasswordForm& form); |
| void UpdateLoginWithPrimaryKeyInternal( |
| const autofill::PasswordForm& new_form, |
| const autofill::PasswordForm& old_primary_key); |
| void RemoveLoginsByURLAndTimeInternal( |
| const base::Callback<bool(const GURL&)>& url_filter, |
| base::Time delete_begin, |
| base::Time delete_end, |
| const base::Closure& completion); |
| void RemoveLoginsCreatedBetweenInternal(base::Time delete_begin, |
| base::Time delete_end, |
| const base::Closure& completion); |
| void RemoveLoginsSyncedBetweenInternal(base::Time delete_begin, |
| base::Time delete_end); |
| void RemoveStatisticsByOriginAndTimeInternal( |
| const base::Callback<bool(const GURL&)>& origin_filter, |
| base::Time delete_begin, |
| base::Time delete_end, |
| const base::Closure& completion); |
| void DisableAutoSignInForOriginsInternal( |
| const base::Callback<bool(const GURL&)>& origin_filter, |
| const base::Closure& completion); |
| |
| // Finds all logins organization-name-matching |signon_realm| and notifies the |
| // consumer. |
| void GetLoginsForSameOrganizationNameImpl( |
| const std::string& signon_realm, |
| std::unique_ptr<GetLoginsRequest> request); |
| |
| // Finds all non-blacklist PasswordForms, and notifies the consumer. |
| void GetAutofillableLoginsImpl(std::unique_ptr<GetLoginsRequest> request); |
| |
| // Same as above, but also fills in affiliation and branding information for |
| // Android credentials. |
| void GetAutofillableLoginsWithAffiliationAndBrandingInformationImpl( |
| std::unique_ptr<GetLoginsRequest> request); |
| |
| // Finds all blacklist PasswordForms, and notifies the consumer. |
| void GetBlacklistLoginsImpl(std::unique_ptr<GetLoginsRequest> request); |
| |
| // Same as above, but also fills in affiliation and branding information for |
| // Android credentials. |
| void GetBlacklistLoginsWithAffiliationAndBrandingInformationImpl( |
| std::unique_ptr<GetLoginsRequest> request); |
| |
| // Find all PasswordForms, fills in affiliation and branding information for |
| // Android credentials, and notifies the consumer. |
| void GetAllLoginsWithAffiliationAndBrandingInformationImpl( |
| std::unique_ptr<GetLoginsRequest> request); |
| |
| // Notifies |request| about the stats for all sites. |
| void NotifyAllSiteStats(std::unique_ptr<GetLoginsRequest> request); |
| |
| // Notifies |request| about the stats for |origin_domain|. |
| void NotifySiteStats(const GURL& origin_domain, |
| std::unique_ptr<GetLoginsRequest> request); |
| |
| // Extended version of GetLoginsImpl that also returns credentials stored for |
| // the specified affiliated Android applications. That is, it finds all |
| // PasswordForms with a signon_realm that is either: |
| // * equal to that of |form|, |
| // * is a PSL-match to the realm of |form|, |
| // * is one of those in |additional_android_realms|, |
| // and takes care of notifying the consumer with the results when done. |
| void GetLoginsWithAffiliationsImpl( |
| const FormDigest& form, |
| std::unique_ptr<GetLoginsRequest> request, |
| const std::vector<std::string>& additional_android_realms); |
| |
| // Retrieves and fills in affiliation and branding information for Android |
| // credentials in |forms|. Called on the main sequence. |
| void InjectAffiliationAndBrandingInformation( |
| std::vector<std::unique_ptr<autofill::PasswordForm>> forms, |
| std::unique_ptr<GetLoginsRequest> request); |
| |
| // Schedules GetLoginsWithAffiliationsImpl() to be run on the background |
| // sequence. |
| void ScheduleGetLoginsWithAffiliations( |
| const FormDigest& form, |
| std::unique_ptr<GetLoginsRequest> request, |
| const std::vector<std::string>& additional_android_realms); |
| |
| // Retrieves the currently stored form, if any, with the same primary key as |
| // |form|, that is, with the same signon_realm, origin, username_element, |
| // username_value and password_element attributes. To be called on the |
| // background sequence. |
| std::unique_ptr<autofill::PasswordForm> GetLoginImpl( |
| const autofill::PasswordForm& primary_key); |
| |
| // Called when a password is added or updated for an Android application, and |
| // triggers finding web sites affiliated with the Android application and |
| // propagating the new password to credentials for those web sites, if any. |
| // Called on the main sequence. |
| void FindAndUpdateAffiliatedWebLogins( |
| const autofill::PasswordForm& added_or_updated_android_form); |
| |
| // Posts FindAndUpdateAffiliatedWebLogins() to the main sequence. Should be |
| // called from the background sequence. |
| void ScheduleFindAndUpdateAffiliatedWebLogins( |
| const autofill::PasswordForm& added_or_updated_android_form); |
| |
| // Called when a password is added or updated for an Android application, and |
| // propagates these changes to credentials stored for |affiliated_web_realms| |
| // under the same username, if there are any. Called on the background |
| // sequence. |
| void UpdateAffiliatedWebLoginsImpl( |
| const autofill::PasswordForm& updated_android_form, |
| const std::vector<std::string>& affiliated_web_realms); |
| |
| // Returns the sync controller delegate for syncing passwords. It must be |
| // called on the background sequence. |
| base::WeakPtr<syncer::ModelTypeControllerDelegate> |
| GetSyncControllerDelegateOnBackgroundSequence(); |
| |
| // Schedules UpdateAffiliatedWebLoginsImpl() to run on the background |
| // sequence. Should be called from the main sequence. |
| void ScheduleUpdateAffiliatedWebLoginsImpl( |
| const autofill::PasswordForm& updated_android_form, |
| const std::vector<std::string>& affiliated_web_realms); |
| |
| // Deletes object that should be destroyed on the background sequence. |
| // WARNING: this method can be skipped on shutdown. |
| void DestroyOnBackgroundSequence(); |
| |
| // TaskRunner for tasks that run on the main sequence (usually the UI thread). |
| scoped_refptr<base::SequencedTaskRunner> main_task_runner_; |
| |
| // TaskRunner for all the background operations. |
| scoped_refptr<base::SequencedTaskRunner> background_task_runner_; |
| |
| // The observers. |
| scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_; |
| |
| // Either of two below would actually be set based on a feature flag. |
| std::unique_ptr<PasswordSyncableService> syncable_service_; |
| std::unique_ptr<PasswordSyncBridge> sync_bridge_; |
| |
| std::unique_ptr<AffiliatedMatchHelper> affiliated_match_helper_; |
| // TODO(crbug.com/706392): Fix password reuse detection for Android. |
| #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) |
| PrefService* prefs_ = nullptr; |
| // PasswordReuseDetector can be only destroyed on the background sequence. It |
| // can't be owned by PasswordStore because PasswordStore can be destroyed on |
| // the UI thread and DestroyOnBackgroundThread isn't guaranteed to be called. |
| PasswordReuseDetector* reuse_detector_ = nullptr; |
| std::unique_ptr<PasswordStoreSigninNotifier> notifier_; |
| HashPasswordManager hash_password_manager_; |
| #endif |
| |
| bool is_propagating_password_changes_to_web_credentials_enabled_; |
| |
| bool shutdown_called_; |
| |
| InitStatus init_status_; |
| |
| DISALLOW_COPY_AND_ASSIGN(PasswordStore); |
| }; |
| |
| // For logging only. |
| std::ostream& operator<<(std::ostream& os, |
| const PasswordStore::FormDigest& digest); |
| |
| } // namespace password_manager |
| |
| #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_STORE_H_ |