blob: c03d5a83fdb1e76e75dbd50e16336fd9e4d1cb5a [file] [log] [blame]
// Copyright (c) 2015 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.
#include "components/browsing_data/core/counters/passwords_counter.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/test/integration/passwords_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/autofill/core/common/password_form.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/browsing_data/core/browsing_data_utils.h"
#include "components/browsing_data/core/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
namespace {
using autofill::PasswordForm;
using browsing_data::BrowsingDataCounter;
class PasswordsCounterTest : public InProcessBrowserTest {
public:
PasswordsCounterTest() {}
void SetUpOnMainThread() override {
finished_ = false;
time_ = base::Time::Now();
store_ = PasswordStoreFactory::GetForProfile(
browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS);
SetPasswordsDeletionPref(true);
SetDeletionPeriodPref(browsing_data::TimePeriod::ALL_TIME);
}
void AddLogin(const std::string& origin,
const std::string& username,
bool blacklisted) {
// Add login and wait until the password store actually changes.
// on the database thread.
passwords_helper::AddLogin(
store_.get(), CreateCredentials(origin, username, blacklisted));
}
void RemoveLogin(const std::string& origin,
const std::string& username,
bool blacklisted) {
// Remove login and wait until the password store actually changes
// on the database thread.
passwords_helper::RemoveLogin(
store_.get(), CreateCredentials(origin, username, blacklisted));
}
void SetPasswordsDeletionPref(bool value) {
browser()->profile()->GetPrefs()->SetBoolean(
browsing_data::prefs::kDeletePasswords, value);
}
void SetDeletionPeriodPref(browsing_data::TimePeriod period) {
browser()->profile()->GetPrefs()->SetInteger(
browsing_data::prefs::kDeleteTimePeriod, static_cast<int>(period));
}
void RevertTimeInDays(int days) {
time_ -= base::TimeDelta::FromDays(days);
}
void WaitForCounting() {
// The counting takes place on the database thread. Wait until it finishes.
base::WaitableEvent waitable_event(
base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED);
store_->ScheduleTask(base::Bind(&base::WaitableEvent::Signal,
base::Unretained(&waitable_event)));
waitable_event.Wait();
// At this point, the calculation on DB thread should have finished, and
// a callback should be scheduled on the UI thread. Process the tasks until
// we get a finished result.
run_loop_.reset(new base::RunLoop());
run_loop_->Run();
}
BrowsingDataCounter::ResultInt GetResult() {
DCHECK(finished_);
return result_;
}
void Callback(std::unique_ptr<BrowsingDataCounter::Result> result) {
DCHECK(result);
finished_ = result->Finished();
if (finished_) {
auto* password_result =
static_cast<BrowsingDataCounter::SyncResult*>(result.get());
result_ = password_result->Value();
}
if (run_loop_ && finished_)
run_loop_->Quit();
}
void WaitForUICallbacksFromAddingLogins() {
base::RunLoop loop;
loop.RunUntilIdle();
}
private:
PasswordForm CreateCredentials(const std::string& origin,
const std::string& username,
bool blacklisted) {
PasswordForm result;
result.signon_realm = origin;
result.origin = GURL(origin);
result.username_value = base::ASCIIToUTF16(username);
result.password_value = base::ASCIIToUTF16("hunter2");
result.blacklisted_by_user = blacklisted;
result.date_created = time_;
return result;
}
scoped_refptr<password_manager::PasswordStore> store_;
std::unique_ptr<base::RunLoop> run_loop_;
base::Time time_;
bool finished_;
BrowsingDataCounter::ResultInt result_;
};
// Tests that the counter correctly counts each individual credential on
// the same domain.
IN_PROC_BROWSER_TEST_F(PasswordsCounterTest, SameDomain) {
AddLogin("https://www.google.com", "user1", false);
AddLogin("https://www.google.com", "user2", false);
AddLogin("https://www.google.com", "user3", false);
AddLogin("https://www.chrome.com", "user1", false);
AddLogin("https://www.chrome.com", "user2", false);
WaitForUICallbacksFromAddingLogins();
Profile* profile = browser()->profile();
browsing_data::PasswordsCounter counter(
PasswordStoreFactory::GetForProfile(profile,
ServiceAccessType::EXPLICIT_ACCESS),
ProfileSyncServiceFactory::GetForProfile(profile));
counter.Init(
profile->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
base::Bind(&PasswordsCounterTest::Callback, base::Unretained(this)));
counter.Restart();
WaitForCounting();
EXPECT_EQ(5u, GetResult());
}
// Tests that the counter doesn't count blacklisted entries.
IN_PROC_BROWSER_TEST_F(PasswordsCounterTest, Blacklisted) {
AddLogin("https://www.google.com", "user1", false);
AddLogin("https://www.google.com", "user2", true);
AddLogin("https://www.chrome.com", "user3", true);
WaitForUICallbacksFromAddingLogins();
Profile* profile = browser()->profile();
browsing_data::PasswordsCounter counter(
PasswordStoreFactory::GetForProfile(profile,
ServiceAccessType::EXPLICIT_ACCESS),
ProfileSyncServiceFactory::GetForProfile(profile));
counter.Init(
profile->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
base::Bind(&PasswordsCounterTest::Callback, base::Unretained(this)));
counter.Restart();
WaitForCounting();
EXPECT_EQ(1u, GetResult());
}
// Tests that the counter starts counting automatically when the deletion
// pref changes to true.
IN_PROC_BROWSER_TEST_F(PasswordsCounterTest, PrefChanged) {
SetPasswordsDeletionPref(false);
AddLogin("https://www.google.com", "user", false);
AddLogin("https://www.chrome.com", "user", false);
WaitForUICallbacksFromAddingLogins();
Profile* profile = browser()->profile();
browsing_data::PasswordsCounter counter(
PasswordStoreFactory::GetForProfile(profile,
ServiceAccessType::EXPLICIT_ACCESS),
ProfileSyncServiceFactory::GetForProfile(profile));
counter.Init(
profile->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
base::Bind(&PasswordsCounterTest::Callback, base::Unretained(this)));
SetPasswordsDeletionPref(true);
WaitForCounting();
EXPECT_EQ(2u, GetResult());
}
// Tests that the counter starts counting automatically when
// the password store changes.
IN_PROC_BROWSER_TEST_F(PasswordsCounterTest, StoreChanged) {
AddLogin("https://www.google.com", "user", false);
WaitForUICallbacksFromAddingLogins();
Profile* profile = browser()->profile();
browsing_data::PasswordsCounter counter(
PasswordStoreFactory::GetForProfile(profile,
ServiceAccessType::EXPLICIT_ACCESS),
ProfileSyncServiceFactory::GetForProfile(profile));
counter.Init(
profile->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
base::Bind(&PasswordsCounterTest::Callback, base::Unretained(this)));
counter.Restart();
WaitForCounting();
EXPECT_EQ(1u, GetResult());
AddLogin("https://www.chrome.com", "user", false);
WaitForCounting();
EXPECT_EQ(2u, GetResult());
RemoveLogin("https://www.chrome.com", "user", false);
WaitForCounting();
EXPECT_EQ(1u, GetResult());
}
// Tests that changing the deletion period restarts the counting, and that
// the result takes login creation dates into account.
IN_PROC_BROWSER_TEST_F(PasswordsCounterTest, PeriodChanged) {
AddLogin("https://www.google.com", "user", false);
RevertTimeInDays(2);
AddLogin("https://example.com", "user1", false);
RevertTimeInDays(3);
AddLogin("https://example.com", "user2", false);
RevertTimeInDays(30);
AddLogin("https://www.chrome.com", "user", false);
WaitForUICallbacksFromAddingLogins();
Profile* profile = browser()->profile();
browsing_data::PasswordsCounter counter(
PasswordStoreFactory::GetForProfile(profile,
ServiceAccessType::EXPLICIT_ACCESS),
ProfileSyncServiceFactory::GetForProfile(profile));
counter.Init(
profile->GetPrefs(), browsing_data::ClearBrowsingDataTab::ADVANCED,
base::Bind(&PasswordsCounterTest::Callback, base::Unretained(this)));
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_HOUR);
WaitForCounting();
EXPECT_EQ(1u, GetResult());
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_DAY);
WaitForCounting();
EXPECT_EQ(1u, GetResult());
SetDeletionPeriodPref(browsing_data::TimePeriod::LAST_WEEK);
WaitForCounting();
EXPECT_EQ(3u, GetResult());
SetDeletionPeriodPref(browsing_data::TimePeriod::FOUR_WEEKS);
WaitForCounting();
EXPECT_EQ(3u, GetResult());
SetDeletionPeriodPref(browsing_data::TimePeriod::ALL_TIME);
WaitForCounting();
EXPECT_EQ(4u, GetResult());
}
} // namespace