Commit 3f719ea2 authored by Jan Wilken Dörrie's avatar Jan Wilken Dörrie Committed by Commit Bot

[Passwords] Add CompromisedPasswordsObserver

This change adds a CompromisedPasswordsObserver interface to the
password store allowing subscribers to be notified about changes to the
stored compromised credentials.

Bug: 1047726
Change-Id: I10e8938bad7ad7503791f8c109df23384b4392c1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2037574
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738639}
parent 9f3f4689
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "components/password_manager/core/browser/compromised_credentials_table.h" #include "components/password_manager/core/browser/compromised_credentials_table.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "components/password_manager/core/browser/sql_table_builder.h" #include "components/password_manager/core/browser/sql_table_builder.h"
#include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_features.h"
...@@ -104,11 +106,20 @@ bool CompromisedCredentialsTable::AddRow( ...@@ -104,11 +106,20 @@ bool CompromisedCredentialsTable::AddRow(
UMA_HISTOGRAM_ENUMERATION("PasswordManager.CompromisedCredentials.Add", UMA_HISTOGRAM_ENUMERATION("PasswordManager.CompromisedCredentials.Add",
compromised_credentials.compromise_type); compromised_credentials.compromise_type);
sql::Statement s( // In case there is an error, expect it to be a constraint violation.
db_->GetCachedStatement(SQL_FROM_HERE, db_->set_error_callback(base::BindRepeating([](int error, sql::Statement*) {
"INSERT OR IGNORE INTO compromised_credentials " constexpr int kSqliteErrorMask = 0xFF;
"(url, username, create_time, compromise_type) " constexpr int kSqliteConstraint = 19;
"VALUES (?, ?, ?, ?)")); if ((error & kSqliteErrorMask) != kSqliteConstraint) {
DLOG(ERROR) << "Got unexpected SQL error code: " << error;
}
}));
sql::Statement s(db_->GetCachedStatement(
SQL_FROM_HERE,
"INSERT INTO compromised_credentials (url, username, create_time, "
"compromise_type) VALUES (?, ?, ?, ?)"));
s.BindString(GetColumnNumber(CompromisedCredentialsTableColumn::kSignonRealm), s.BindString(GetColumnNumber(CompromisedCredentialsTableColumn::kSignonRealm),
compromised_credentials.signon_realm); compromised_credentials.signon_realm);
s.BindString16(GetColumnNumber(CompromisedCredentialsTableColumn::kUsername), s.BindString16(GetColumnNumber(CompromisedCredentialsTableColumn::kUsername),
...@@ -119,7 +130,10 @@ bool CompromisedCredentialsTable::AddRow( ...@@ -119,7 +130,10 @@ bool CompromisedCredentialsTable::AddRow(
s.BindInt64( s.BindInt64(
GetColumnNumber(CompromisedCredentialsTableColumn::kCompromiseType), GetColumnNumber(CompromisedCredentialsTableColumn::kCompromiseType),
static_cast<int>(compromised_credentials.compromise_type)); static_cast<int>(compromised_credentials.compromise_type));
return s.Run();
bool result = s.Run();
db_->reset_error_callback();
return result;
} }
std::vector<CompromisedCredentials> CompromisedCredentialsTable::GetRows( std::vector<CompromisedCredentials> CompromisedCredentialsTable::GetRows(
...@@ -266,4 +280,4 @@ std::vector<CompromisedCredentials> CompromisedCredentialsTable::GetAllRows() { ...@@ -266,4 +280,4 @@ std::vector<CompromisedCredentials> CompromisedCredentialsTable::GetAllRows() {
return StatementToCompromisedCredentials(&s); return StatementToCompromisedCredentials(&s);
} }
} // namespace password_manager } // namespace password_manager
\ No newline at end of file
...@@ -140,10 +140,8 @@ TEST_F(CompromisedCredentialsTableTest, ...@@ -140,10 +140,8 @@ TEST_F(CompromisedCredentialsTableTest,
compromised_credentials2.create_time = base::Time::FromTimeT(2); compromised_credentials2.create_time = base::Time::FromTimeT(2);
EXPECT_TRUE(db()->AddRow(compromised_credentials1)); EXPECT_TRUE(db()->AddRow(compromised_credentials1));
// It should return true as the sql statement ran correctly. It ignored // It should return false because of unique constraints.
// new row though because of unique constraints, hence there is only one EXPECT_FALSE(db()->AddRow(compromised_credentials2));
// record in the database.
EXPECT_TRUE(db()->AddRow(compromised_credentials2));
EXPECT_THAT(db()->GetAllRows(), ElementsAre(compromised_credentials1)); EXPECT_THAT(db()->GetAllRows(), ElementsAre(compromised_credentials1));
} }
......
...@@ -74,15 +74,15 @@ class MockPasswordStore : public PasswordStore { ...@@ -74,15 +74,15 @@ class MockPasswordStore : public PasswordStore {
MOCK_METHOD1(AddSiteStatsImpl, void(const InteractionsStats&)); MOCK_METHOD1(AddSiteStatsImpl, void(const InteractionsStats&));
MOCK_METHOD1(RemoveSiteStatsImpl, void(const GURL&)); MOCK_METHOD1(RemoveSiteStatsImpl, void(const GURL&));
MOCK_METHOD1(AddCompromisedCredentialsImpl, MOCK_METHOD1(AddCompromisedCredentialsImpl,
void(const CompromisedCredentials&)); bool(const CompromisedCredentials&));
MOCK_METHOD3(RemoveCompromisedCredentialsImpl, MOCK_METHOD3(RemoveCompromisedCredentialsImpl,
void(const std::string&, bool(const std::string&,
const base::string16&, const base::string16&,
RemoveCompromisedCredentialsReason)); RemoveCompromisedCredentialsReason));
MOCK_METHOD0(GetAllCompromisedCredentialsImpl, MOCK_METHOD0(GetAllCompromisedCredentialsImpl,
std::vector<CompromisedCredentials>()); std::vector<CompromisedCredentials>());
MOCK_METHOD3(RemoveCompromisedCredentialsByUrlAndTimeImpl, MOCK_METHOD3(RemoveCompromisedCredentialsByUrlAndTimeImpl,
void(const base::RepeatingCallback<bool(const GURL&)>&, bool(const base::RepeatingCallback<bool(const GURL&)>&,
base::Time, base::Time,
base::Time)); base::Time));
MOCK_METHOD1(AddFieldInfoImpl, void(const FieldInfo&)); MOCK_METHOD1(AddFieldInfoImpl, void(const FieldInfo&));
......
...@@ -373,8 +373,11 @@ void PasswordStore::GetSiteStats(const GURL& origin_domain, ...@@ -373,8 +373,11 @@ void PasswordStore::GetSiteStats(const GURL& origin_domain,
void PasswordStore::AddCompromisedCredentials( void PasswordStore::AddCompromisedCredentials(
const CompromisedCredentials& compromised_credentials) { const CompromisedCredentials& compromised_credentials) {
DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
ScheduleTask(base::BindOnce(&PasswordStore::AddCompromisedCredentialsImpl, auto callback = base::BindOnce(&PasswordStore::AddCompromisedCredentialsImpl,
this, compromised_credentials)); this, compromised_credentials);
ScheduleTask(base::BindOnce(
&PasswordStore::InvokeAndNotifyAboutCompromisedPasswordsChange, this,
std::move(callback)));
} }
void PasswordStore::RemoveCompromisedCredentials( void PasswordStore::RemoveCompromisedCredentials(
...@@ -382,8 +385,12 @@ void PasswordStore::RemoveCompromisedCredentials( ...@@ -382,8 +385,12 @@ void PasswordStore::RemoveCompromisedCredentials(
const base::string16& username, const base::string16& username,
RemoveCompromisedCredentialsReason reason) { RemoveCompromisedCredentialsReason reason) {
DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
ScheduleTask(base::BindOnce(&PasswordStore::RemoveCompromisedCredentialsImpl, auto callback =
this, signon_realm, username, reason)); base::BindOnce(&PasswordStore::RemoveCompromisedCredentialsImpl, this,
signon_realm, username, reason);
ScheduleTask(base::BindOnce(
&PasswordStore::InvokeAndNotifyAboutCompromisedPasswordsChange, this,
std::move(callback)));
} }
void PasswordStore::GetAllCompromisedCredentials( void PasswordStore::GetAllCompromisedCredentials(
...@@ -400,9 +407,13 @@ void PasswordStore::RemoveCompromisedCredentialsByUrlAndTime( ...@@ -400,9 +407,13 @@ void PasswordStore::RemoveCompromisedCredentialsByUrlAndTime(
base::Time remove_end, base::Time remove_end,
base::OnceClosure completion) { base::OnceClosure completion) {
DCHECK(main_task_runner_->RunsTasksInCurrentSequence()); DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
ScheduleTask(base::BindOnce( auto callback = base::BindOnce(
&PasswordStore::RemoveCompromisedCredentialsByUrlAndTimeInternal, this, &PasswordStore::RemoveCompromisedCredentialsByUrlAndTimeInternal, this,
std::move(url_filter), remove_begin, remove_end, std::move(completion))); std::move(url_filter), remove_begin, remove_end, std::move(completion));
ScheduleTask(base::BindOnce(
&PasswordStore::InvokeAndNotifyAboutCompromisedPasswordsChange, this,
std::move(callback)));
} }
void PasswordStore::AddFieldInfo(const FieldInfo& field_info) { void PasswordStore::AddFieldInfo(const FieldInfo& field_info) {
...@@ -439,10 +450,19 @@ void PasswordStore::RemoveObserver(Observer* observer) { ...@@ -439,10 +450,19 @@ void PasswordStore::RemoveObserver(Observer* observer) {
observers_->RemoveObserver(observer); observers_->RemoveObserver(observer);
} }
void PasswordStore::AddCompromisedPasswordsObserver(
CompromisedPasswordsObserver* observer) {
compromised_passwords_observers_->AddObserver(observer);
}
void PasswordStore::RemoveCompromisedPasswordsObserver(
CompromisedPasswordsObserver* observer) {
compromised_passwords_observers_->RemoveObserver(observer);
}
bool PasswordStore::ScheduleTask(base::OnceClosure task) { bool PasswordStore::ScheduleTask(base::OnceClosure task) {
if (background_task_runner_) return background_task_runner_ &&
return background_task_runner_->PostTask(FROM_HERE, std::move(task)); background_task_runner_->PostTask(FROM_HERE, std::move(task));
return false;
} }
bool PasswordStore::IsAbleToSavePasswords() const { bool PasswordStore::IsAbleToSavePasswords() const {
...@@ -692,6 +712,16 @@ void PasswordStore::NotifyLoginsChanged( ...@@ -692,6 +712,16 @@ void PasswordStore::NotifyLoginsChanged(
} }
} }
void PasswordStore::InvokeAndNotifyAboutCompromisedPasswordsChange(
base::OnceCallback<bool()> callback) {
DCHECK(background_task_runner_->RunsTasksInCurrentSequence());
if (std::move(callback).Run()) {
compromised_passwords_observers_->Notify(
FROM_HERE,
&CompromisedPasswordsObserver::OnCompromisedPasswordsChanged);
}
}
#if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
void PasswordStore::CheckReuseImpl(std::unique_ptr<CheckReuseRequest> request, void PasswordStore::CheckReuseImpl(std::unique_ptr<CheckReuseRequest> request,
const base::string16& input, const base::string16& input,
...@@ -953,16 +983,17 @@ void PasswordStore::UnblacklistInternal( ...@@ -953,16 +983,17 @@ void PasswordStore::UnblacklistInternal(
main_task_runner_->PostTask(FROM_HERE, std::move(completion)); main_task_runner_->PostTask(FROM_HERE, std::move(completion));
} }
void PasswordStore::RemoveCompromisedCredentialsByUrlAndTimeInternal( bool PasswordStore::RemoveCompromisedCredentialsByUrlAndTimeInternal(
const base::RepeatingCallback<bool(const GURL&)>& url_filter, const base::RepeatingCallback<bool(const GURL&)>& url_filter,
base::Time remove_begin, base::Time remove_begin,
base::Time remove_end, base::Time remove_end,
base::OnceClosure completion) { base::OnceClosure completion) {
DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); DCHECK(background_task_runner_->RunsTasksInCurrentSequence());
RemoveCompromisedCredentialsByUrlAndTimeImpl(url_filter, remove_begin, bool result = RemoveCompromisedCredentialsByUrlAndTimeImpl(
remove_end); url_filter, remove_begin, remove_end);
if (!completion.is_null()) if (!completion.is_null())
main_task_runner_->PostTask(FROM_HERE, std::move(completion)); main_task_runner_->PostTask(FROM_HERE, std::move(completion));
return result;
} }
void PasswordStore::RemoveFieldInfoByTimeInternal( void PasswordStore::RemoveFieldInfoByTimeInternal(
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/callback_list.h" #include "base/callback_list.h"
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/observer_list_threadsafe.h" #include "base/observer_list_threadsafe.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/time/time.h" #include "base/time/time.h"
...@@ -91,7 +92,20 @@ class PasswordStore : protected PasswordStoreSync, ...@@ -91,7 +92,20 @@ class PasswordStore : protected PasswordStoreSync,
virtual void OnLoginsChanged(const PasswordStoreChangeList& changes) = 0; virtual void OnLoginsChanged(const PasswordStoreChangeList& changes) = 0;
protected: protected:
virtual ~Observer() {} virtual ~Observer() = default;
};
class CompromisedPasswordsObserver {
// An interface used to notify clients (observers) of this object that the
// list of comrpomised crendentials in the password store has changed.
// Register the observer via PasswordStore::AddCompromisedPasswordsObserver.
public:
// Notifies the observer that the list of compromised credentials changed.
// Will be called from the UI thread.
virtual void OnCompromisedPasswordsChanged() = 0;
protected:
virtual ~CompromisedPasswordsObserver() = default;
}; };
// Represents a subset of autofill::PasswordForm needed for credential // Represents a subset of autofill::PasswordForm needed for credential
...@@ -293,6 +307,14 @@ class PasswordStore : protected PasswordStoreSync, ...@@ -293,6 +307,14 @@ class PasswordStore : protected PasswordStoreSync,
// Removes |observer| from the observer list. // Removes |observer| from the observer list.
void RemoveObserver(Observer* observer); void RemoveObserver(Observer* observer);
// Adds an observer to be notified when the list of compromised passwords in
// the password store changes.
void AddCompromisedPasswordsObserver(CompromisedPasswordsObserver* observer);
// Removes |observer| from the list of compromised credentials observer.
void RemoveCompromisedPasswordsObserver(
CompromisedPasswordsObserver* observer);
// Schedules the given |task| to be run on the PasswordStore's TaskRunner. // Schedules the given |task| to be run on the PasswordStore's TaskRunner.
bool ScheduleTask(base::OnceClosure task); bool ScheduleTask(base::OnceClosure task);
...@@ -487,15 +509,15 @@ class PasswordStore : protected PasswordStoreSync, ...@@ -487,15 +509,15 @@ class PasswordStore : protected PasswordStoreSync,
// Synchronous implementation for manipulating with information about // Synchronous implementation for manipulating with information about
// compromised credentials. // compromised credentials.
virtual void AddCompromisedCredentialsImpl( virtual bool AddCompromisedCredentialsImpl(
const CompromisedCredentials& compromised_credentials) = 0; const CompromisedCredentials& compromised_credentials) = 0;
virtual void RemoveCompromisedCredentialsImpl( virtual bool RemoveCompromisedCredentialsImpl(
const std::string& signon_realm, const std::string& signon_realm,
const base::string16& username, const base::string16& username,
RemoveCompromisedCredentialsReason reason) = 0; RemoveCompromisedCredentialsReason reason) = 0;
virtual std::vector<CompromisedCredentials> virtual std::vector<CompromisedCredentials>
GetAllCompromisedCredentialsImpl() = 0; GetAllCompromisedCredentialsImpl() = 0;
virtual void RemoveCompromisedCredentialsByUrlAndTimeImpl( virtual bool RemoveCompromisedCredentialsByUrlAndTimeImpl(
const base::RepeatingCallback<bool(const GURL&)>& url_filter, const base::RepeatingCallback<bool(const GURL&)>& url_filter,
base::Time remove_begin, base::Time remove_begin,
base::Time remove_end) = 0; base::Time remove_end) = 0;
...@@ -520,6 +542,11 @@ class PasswordStore : protected PasswordStoreSync, ...@@ -520,6 +542,11 @@ class PasswordStore : protected PasswordStoreSync,
// been changed. // been changed.
void NotifyLoginsChanged(const PasswordStoreChangeList& changes) override; void NotifyLoginsChanged(const PasswordStoreChangeList& changes) override;
// Invokes callback and notifies observers if there was a change to the list
// of compromised passwords.
void InvokeAndNotifyAboutCompromisedPasswordsChange(
base::OnceCallback<bool()> callback);
#if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
// Saves |username| and a hash of |password| for password reuse checking. // 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 // |is_gaia_password| indicates if it is a Gaia account. |event| is used for
...@@ -652,7 +679,7 @@ class PasswordStore : protected PasswordStoreSync, ...@@ -652,7 +679,7 @@ class PasswordStore : protected PasswordStoreSync,
const base::Closure& completion); const base::Closure& completion);
void UnblacklistInternal(const PasswordStore::FormDigest& form_digest, void UnblacklistInternal(const PasswordStore::FormDigest& form_digest,
base::OnceClosure completion); base::OnceClosure completion);
void RemoveCompromisedCredentialsByUrlAndTimeInternal( bool RemoveCompromisedCredentialsByUrlAndTimeInternal(
const base::RepeatingCallback<bool(const GURL&)>& url_filter, const base::RepeatingCallback<bool(const GURL&)>& url_filter,
base::Time remove_begin, base::Time remove_begin,
base::Time remove_end, base::Time remove_end,
...@@ -761,6 +788,9 @@ class PasswordStore : protected PasswordStoreSync, ...@@ -761,6 +788,9 @@ class PasswordStore : protected PasswordStoreSync,
// The observers. // The observers.
scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_; scoped_refptr<base::ObserverListThreadSafe<Observer>> observers_;
scoped_refptr<base::ObserverListThreadSafe<CompromisedPasswordsObserver>>
compromised_passwords_observers_ = base::MakeRefCounted<
base::ObserverListThreadSafe<CompromisedPasswordsObserver>>();
// Either of two below would actually be set based on a feature flag. // Either of two below would actually be set based on a feature flag.
std::unique_ptr<PasswordSyncableService> syncable_service_; std::unique_ptr<PasswordSyncableService> syncable_service_;
......
...@@ -222,22 +222,20 @@ std::vector<InteractionsStats> PasswordStoreDefault::GetSiteStatsImpl( ...@@ -222,22 +222,20 @@ std::vector<InteractionsStats> PasswordStoreDefault::GetSiteStatsImpl(
: std::vector<InteractionsStats>(); : std::vector<InteractionsStats>();
} }
void PasswordStoreDefault::AddCompromisedCredentialsImpl( bool PasswordStoreDefault::AddCompromisedCredentialsImpl(
const CompromisedCredentials& compromised_credentials) { const CompromisedCredentials& credentials) {
DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
if (login_db_) return login_db_ &&
login_db_->compromised_credentials_table().AddRow(compromised_credentials); login_db_->compromised_credentials_table().AddRow(credentials);
} }
void PasswordStoreDefault::RemoveCompromisedCredentialsImpl( bool PasswordStoreDefault::RemoveCompromisedCredentialsImpl(
const std::string& signon_realm, const std::string& signon_realm,
const base::string16& username, const base::string16& username,
RemoveCompromisedCredentialsReason reason) { RemoveCompromisedCredentialsReason reason) {
DCHECK(background_task_runner()->RunsTasksInCurrentSequence()); DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
if (login_db_) { return login_db_ && login_db_->compromised_credentials_table().RemoveRow(
login_db_->compromised_credentials_table().RemoveRow(signon_realm, username, signon_realm, username, reason);
reason);
}
} }
std::vector<CompromisedCredentials> std::vector<CompromisedCredentials>
...@@ -247,14 +245,14 @@ PasswordStoreDefault::GetAllCompromisedCredentialsImpl() { ...@@ -247,14 +245,14 @@ PasswordStoreDefault::GetAllCompromisedCredentialsImpl() {
: std::vector<CompromisedCredentials>(); : std::vector<CompromisedCredentials>();
} }
void PasswordStoreDefault::RemoveCompromisedCredentialsByUrlAndTimeImpl( bool PasswordStoreDefault::RemoveCompromisedCredentialsByUrlAndTimeImpl(
const base::RepeatingCallback<bool(const GURL&)>& url_filter, const base::RepeatingCallback<bool(const GURL&)>& url_filter,
base::Time remove_begin, base::Time remove_begin,
base::Time remove_end) { base::Time remove_end) {
if (login_db_) { DCHECK(background_task_runner()->RunsTasksInCurrentSequence());
login_db_->compromised_credentials_table().RemoveRowsByUrlAndTime( return login_db_ &&
url_filter, remove_begin, remove_end); login_db_->compromised_credentials_table().RemoveRowsByUrlAndTime(
} url_filter, remove_begin, remove_end);
} }
void PasswordStoreDefault::AddFieldInfoImpl(const FieldInfo& field_info) { void PasswordStoreDefault::AddFieldInfoImpl(const FieldInfo& field_info) {
......
...@@ -73,15 +73,15 @@ class PasswordStoreDefault : public PasswordStore { ...@@ -73,15 +73,15 @@ class PasswordStoreDefault : public PasswordStore {
std::vector<InteractionsStats> GetAllSiteStatsImpl() override; std::vector<InteractionsStats> GetAllSiteStatsImpl() override;
std::vector<InteractionsStats> GetSiteStatsImpl( std::vector<InteractionsStats> GetSiteStatsImpl(
const GURL& origin_domain) override; const GURL& origin_domain) override;
void AddCompromisedCredentialsImpl( bool AddCompromisedCredentialsImpl(
const CompromisedCredentials& compromised_credentials) override; const CompromisedCredentials& compromised_credentials) override;
void RemoveCompromisedCredentialsImpl( bool RemoveCompromisedCredentialsImpl(
const std::string& signon_realm, const std::string& signon_realm,
const base::string16& username, const base::string16& username,
RemoveCompromisedCredentialsReason reason) override; RemoveCompromisedCredentialsReason reason) override;
std::vector<CompromisedCredentials> GetAllCompromisedCredentialsImpl() std::vector<CompromisedCredentials> GetAllCompromisedCredentialsImpl()
override; override;
void RemoveCompromisedCredentialsByUrlAndTimeImpl( bool RemoveCompromisedCredentialsByUrlAndTimeImpl(
const base::RepeatingCallback<bool(const GURL&)>& url_filter, const base::RepeatingCallback<bool(const GURL&)>& url_filter,
base::Time remove_begin, base::Time remove_begin,
base::Time remove_end) override; base::Time remove_end) override;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <utility> #include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/scoped_temp_dir.h" #include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/stl_util.h" #include "base/stl_util.h"
...@@ -26,6 +27,7 @@ ...@@ -26,6 +27,7 @@
#include "components/password_manager/core/browser/form_parsing/form_parser.h" #include "components/password_manager/core/browser/form_parsing/form_parser.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h" #include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/password_reuse_detector.h" #include "components/password_manager/core/browser/password_reuse_detector.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/password_store_consumer.h" #include "components/password_manager/core/browser/password_store_consumer.h"
#include "components/password_manager/core/browser/password_store_default.h" #include "components/password_manager/core/browser/password_store_default.h"
#include "components/password_manager/core/browser/password_store_signin_notifier.h" #include "components/password_manager/core/browser/password_store_signin_notifier.h"
...@@ -109,6 +111,11 @@ class MockPasswordStoreConsumer : public PasswordStoreConsumer { ...@@ -109,6 +111,11 @@ class MockPasswordStoreConsumer : public PasswordStoreConsumer {
DISALLOW_COPY_AND_ASSIGN(MockPasswordStoreConsumer); DISALLOW_COPY_AND_ASSIGN(MockPasswordStoreConsumer);
}; };
struct MockCompromisedPasswordsObserver
: PasswordStore::CompromisedPasswordsObserver {
MOCK_METHOD0(OnCompromisedPasswordsChanged, void());
};
class MockPasswordStoreSigninNotifier : public PasswordStoreSigninNotifier { class MockPasswordStoreSigninNotifier : public PasswordStoreSigninNotifier {
public: public:
MOCK_METHOD1(SubscribeToSigninEvents, void(PasswordStore* store)); MOCK_METHOD1(SubscribeToSigninEvents, void(PasswordStore* store));
...@@ -500,6 +507,94 @@ TEST_F(PasswordStoreTest, CompromisedCredentialsObserverOnLoginAdded) { ...@@ -500,6 +507,94 @@ TEST_F(PasswordStoreTest, CompromisedCredentialsObserverOnLoginAdded) {
store->ShutdownOnUIThread(); store->ShutdownOnUIThread();
} }
TEST_F(PasswordStoreTest,
CompromisedPasswordObserverOnCompromisedCredentialAdded) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kPasswordCheck);
MockCompromisedPasswordsObserver observer;
CompromisedCredentials compromised_credentials(
kTestWebRealm1, base::ASCIIToUTF16("username_value_1"),
base::Time::FromTimeT(1), CompromiseType::kLeaked);
scoped_refptr<PasswordStoreDefault> store = CreatePasswordStore();
store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
store->AddCompromisedPasswordsObserver(&observer);
// Expect a notification after adding a credential.
EXPECT_CALL(observer, OnCompromisedPasswordsChanged);
store->AddCompromisedCredentials(compromised_credentials);
WaitForPasswordStore();
// Adding the same credential should not result in another notification.
EXPECT_CALL(observer, OnCompromisedPasswordsChanged).Times(0);
store->AddCompromisedCredentials(compromised_credentials);
WaitForPasswordStore();
store->ShutdownOnUIThread();
}
TEST_F(PasswordStoreTest,
CompromisedPasswordObserverOnCompromisedCredentialRemoved) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kPasswordCheck);
MockCompromisedPasswordsObserver observer;
CompromisedCredentials compromised_credentials(
kTestWebRealm1, base::ASCIIToUTF16("username_value_1"),
base::Time::FromTimeT(1), CompromiseType::kLeaked);
scoped_refptr<PasswordStoreDefault> store = CreatePasswordStore();
store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
store->AddCompromisedCredentials(compromised_credentials);
WaitForPasswordStore();
store->AddCompromisedPasswordsObserver(&observer);
// Expect a notification after removing a credential.
EXPECT_CALL(observer, OnCompromisedPasswordsChanged);
store->RemoveCompromisedCredentials(
compromised_credentials.signon_realm, compromised_credentials.username,
RemoveCompromisedCredentialsReason::kRemove);
WaitForPasswordStore();
// Removing the same credential should not result in another notification.
EXPECT_CALL(observer, OnCompromisedPasswordsChanged).Times(0);
store->RemoveCompromisedCredentials(
compromised_credentials.signon_realm, compromised_credentials.username,
RemoveCompromisedCredentialsReason::kRemove);
WaitForPasswordStore();
store->ShutdownOnUIThread();
}
TEST_F(PasswordStoreTest,
CompromisedPasswordObserverOnCompromisedCredentialRemovedByTime) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kPasswordCheck);
MockCompromisedPasswordsObserver observer;
CompromisedCredentials compromised_credentials(
kTestWebRealm1, base::ASCIIToUTF16("username_value_1"),
base::Time::FromTimeT(1), CompromiseType::kLeaked);
scoped_refptr<PasswordStoreDefault> store = CreatePasswordStore();
store->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
store->AddCompromisedCredentials(compromised_credentials);
WaitForPasswordStore();
store->AddCompromisedPasswordsObserver(&observer);
// Expect a notification after removing all credential.
EXPECT_CALL(observer, OnCompromisedPasswordsChanged);
store->RemoveCompromisedCredentialsByUrlAndTime(
base::NullCallback(), base::Time::Min(), base::Time::Max(),
base::NullCallback());
WaitForPasswordStore();
store->ShutdownOnUIThread();
}
// When no Android applications are actually affiliated with the realm of the // When no Android applications are actually affiliated with the realm of the
// observed form, GetLoginsWithAffiliations() should still return the exact and // observed form, GetLoginsWithAffiliations() should still return the exact and
// PSL matching results, but not any stored Android credentials. // PSL matching results, but not any stored Android credentials.
......
...@@ -225,16 +225,18 @@ std::vector<InteractionsStats> TestPasswordStore::GetAllSiteStatsImpl() { ...@@ -225,16 +225,18 @@ std::vector<InteractionsStats> TestPasswordStore::GetAllSiteStatsImpl() {
return std::vector<InteractionsStats>(); return std::vector<InteractionsStats>();
} }
void TestPasswordStore::AddCompromisedCredentialsImpl( bool TestPasswordStore::AddCompromisedCredentialsImpl(
const CompromisedCredentials& stats) { const CompromisedCredentials& stats) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return false;
} }
void TestPasswordStore::RemoveCompromisedCredentialsImpl( bool TestPasswordStore::RemoveCompromisedCredentialsImpl(
const std::string& signon_realm, const std::string& signon_realm,
const base::string16& username, const base::string16& username,
RemoveCompromisedCredentialsReason reason) { RemoveCompromisedCredentialsReason reason) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return false;
} }
std::vector<CompromisedCredentials> std::vector<CompromisedCredentials>
...@@ -243,11 +245,12 @@ TestPasswordStore::GetAllCompromisedCredentialsImpl() { ...@@ -243,11 +245,12 @@ TestPasswordStore::GetAllCompromisedCredentialsImpl() {
return std::vector<CompromisedCredentials>(); return std::vector<CompromisedCredentials>();
} }
void TestPasswordStore::RemoveCompromisedCredentialsByUrlAndTimeImpl( bool TestPasswordStore::RemoveCompromisedCredentialsByUrlAndTimeImpl(
const base::RepeatingCallback<bool(const GURL&)>& url_filter, const base::RepeatingCallback<bool(const GURL&)>& url_filter,
base::Time remove_begin, base::Time remove_begin,
base::Time remove_end) { base::Time remove_end) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
return false;
} }
void TestPasswordStore::AddFieldInfoImpl(const FieldInfo& field_info) { void TestPasswordStore::AddFieldInfoImpl(const FieldInfo& field_info) {
......
...@@ -86,15 +86,15 @@ class TestPasswordStore : public PasswordStore { ...@@ -86,15 +86,15 @@ class TestPasswordStore : public PasswordStore {
void AddSiteStatsImpl(const InteractionsStats& stats) override; void AddSiteStatsImpl(const InteractionsStats& stats) override;
void RemoveSiteStatsImpl(const GURL& origin_domain) override; void RemoveSiteStatsImpl(const GURL& origin_domain) override;
std::vector<InteractionsStats> GetAllSiteStatsImpl() override; std::vector<InteractionsStats> GetAllSiteStatsImpl() override;
void AddCompromisedCredentialsImpl( bool AddCompromisedCredentialsImpl(
const CompromisedCredentials& compromised_credentials) override; const CompromisedCredentials& compromised_credentials) override;
void RemoveCompromisedCredentialsImpl( bool RemoveCompromisedCredentialsImpl(
const std::string& signon_realm, const std::string& signon_realm,
const base::string16& username, const base::string16& username,
RemoveCompromisedCredentialsReason reason) override; RemoveCompromisedCredentialsReason reason) override;
std::vector<CompromisedCredentials> GetAllCompromisedCredentialsImpl() std::vector<CompromisedCredentials> GetAllCompromisedCredentialsImpl()
override; override;
void RemoveCompromisedCredentialsByUrlAndTimeImpl( bool RemoveCompromisedCredentialsByUrlAndTimeImpl(
const base::RepeatingCallback<bool(const GURL&)>& url_filter, const base::RepeatingCallback<bool(const GURL&)>& url_filter,
base::Time remove_begin, base::Time remove_begin,
base::Time remove_end) override; base::Time remove_end) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment