Commit 0c05f13e authored by Martin Kreichgauer's avatar Martin Kreichgauer Committed by Commit Bot

Update counter for "passwords and other sign-in data" in browsing data deletion

This changes the counter sublabel for the "passwords and other sign-in
data" item in the browsing data deletion dialog to include the number of
WebAuthn credentials stored by authenticators built into Chrome
(currently this is only the Touch ID authenticator on macOS).

The format is:
- "None" if neither passwords nor WebAuthn credentials are present
- the counter label for passwords or WebAuthn credentials if only one of
them is present. E.g., "1 password" or "sign-in data for 3 accounts".
- both counter labels separated by "; " if both are present. E.g., "2
passwords (synced); sign-in data for 1 account".

Note that while passwords can be synced, WebAuthn credentials cannot.

Bug: 879548
Change-Id: I4ea5035841192fce6e185fa4fa4b077986bed041
Reviewed-on: https://chromium-review.googlesource.com/1246822Reviewed-by: default avatarChristian Dullweber <dullweber@chromium.org>
Commit-Queue: Martin Kreichgauer <martinkr@google.com>
Cr-Commit-Position: refs/heads/master@{#595960}
parent 3c6126d9
......@@ -222,6 +222,8 @@ jumbo_split_static_library("browser") {
"browsing_data/counters/downloads_counter.h",
"browsing_data/counters/media_licenses_counter.cc",
"browsing_data/counters/media_licenses_counter.h",
"browsing_data/counters/signin_data_counter.cc",
"browsing_data/counters/signin_data_counter.h",
"browsing_data/counters/site_data_counter.cc",
"browsing_data/counters/site_data_counter.h",
"browsing_data/counters/site_data_counting_helper.cc",
......
......@@ -11,6 +11,7 @@
#include "chrome/browser/browsing_data/counters/cache_counter.h"
#include "chrome/browser/browsing_data/counters/downloads_counter.h"
#include "chrome/browser/browsing_data/counters/media_licenses_counter.h"
#include "chrome/browser/browsing_data/counters/signin_data_counter.h"
#include "chrome/browser/browsing_data/counters/site_data_counter.h"
#include "chrome/browser/browsing_data/counters/site_settings_counter.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
......@@ -21,6 +22,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/web_data_service_factory.h"
#include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/browsing_data/core/counters/autofill_counter.h"
#include "components/browsing_data/core/counters/browsing_data_counter.h"
......@@ -39,6 +41,10 @@
#include "content/public/browser/host_zoom_map.h"
#endif
#if defined(OS_MACOSX)
#include "device/fido/mac/credential_store.h"
#endif
namespace {
history::WebHistoryService* GetUpdatedWebHistoryService(Profile* profile) {
......@@ -55,8 +61,7 @@ BrowsingDataCounterFactory::GetForProfileAndPref(Profile* profile,
return std::make_unique<browsing_data::HistoryCounter>(
HistoryServiceFactory::GetForProfile(
profile, ServiceAccessType::EXPLICIT_ACCESS),
base::Bind(&GetUpdatedWebHistoryService,
base::Unretained(profile)),
base::Bind(&GetUpdatedWebHistoryService, base::Unretained(profile)),
ProfileSyncServiceFactory::GetForProfile(profile));
}
if (pref_name == browsing_data::prefs::kDeleteBrowsingHistoryBasic) {
......@@ -83,10 +88,19 @@ BrowsingDataCounterFactory::GetForProfileAndPref(Profile* profile,
}
if (pref_name == browsing_data::prefs::kDeletePasswords) {
return std::make_unique<browsing_data::PasswordsCounter>(
std::unique_ptr<::device::fido::PlatformCredentialStore> credential_store =
#if defined(OS_MACOSX)
std::make_unique<::device::fido::mac::TouchIdCredentialStore>(
ChromeAuthenticatorRequestDelegate::
TouchIdAuthenticatorConfigForProfile(profile));
#else
nullptr;
#endif
return std::make_unique<browsing_data::SigninDataCounter>(
PasswordStoreFactory::GetForProfile(profile,
ServiceAccessType::EXPLICIT_ACCESS),
ProfileSyncServiceFactory::GetForProfile(profile));
ProfileSyncServiceFactory::GetForProfile(profile),
std::move(credential_store));
}
if (pref_name == browsing_data::prefs::kDeleteFormData) {
......
......@@ -8,6 +8,7 @@
#include "build/build_config.h"
#include "chrome/browser/browsing_data/counters/cache_counter.h"
#include "chrome/browser/browsing_data/counters/media_licenses_counter.h"
#include "chrome/browser/browsing_data/counters/signin_data_counter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/account_consistency_mode_manager.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
......@@ -190,5 +191,43 @@ base::string16 GetChromeCounterTextFromResult(
}
#endif
if (pref_name == browsing_data::prefs::kDeletePasswords) {
const browsing_data::SigninDataCounter::SigninDataResult*
passwords_and_signin_data_result = static_cast<
const browsing_data::SigninDataCounter::SigninDataResult*>(result);
browsing_data::BrowsingDataCounter::ResultInt password_count =
passwords_and_signin_data_result->Value();
browsing_data::BrowsingDataCounter::ResultInt signin_data_count =
passwords_and_signin_data_result->WebAuthnCredentialsValue();
std::vector<base::string16> counts;
if (password_count) {
counts.emplace_back(l10n_util::GetPluralStringFUTF16(
passwords_and_signin_data_result->is_sync_enabled()
? IDS_DEL_PASSWORDS_COUNTER_SYNCED
: IDS_DEL_PASSWORDS_COUNTER,
password_count));
}
if (signin_data_count) {
counts.emplace_back(l10n_util::GetPluralStringFUTF16(
IDS_DEL_SIGNIN_DATA_COUNTER, signin_data_count));
}
switch (counts.size()) {
case 0:
return l10n_util::GetStringUTF16(
IDS_DEL_PASSWORDS_AND_SIGNIN_DATA_COUNTER_NONE);
case 1:
return counts[0];
case 2:
return l10n_util::GetStringFUTF16(
IDS_DEL_PASSWORDS_AND_SIGNIN_DATA_COUNTER_COMBINATION, counts[0],
counts[1]);
default:
NOTREACHED();
}
NOTREACHED();
}
return browsing_data::GetCounterTextFromResult(result);
}
......@@ -11,8 +11,12 @@
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/browsing_data/counters/cache_counter.h"
#include "chrome/browser/browsing_data/counters/signin_data_counter.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/password_manager/core/browser/test_password_store.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/buildflags/buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -109,19 +113,16 @@ TEST_F(BrowsingDataCounterUtilsTest, HostedAppsCounterResult) {
for (const TestCase& test_case : kTestCases) {
// Split the list of installed apps by commas.
std::vector<std::string> apps = base::SplitString(
test_case.apps_list, ",",
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
std::vector<std::string> apps =
base::SplitString(test_case.apps_list, ",", base::TRIM_WHITESPACE,
base::SPLIT_WANT_NONEMPTY);
// The first two apps in the list are used as examples.
std::vector<std::string> examples;
examples.assign(
apps.begin(), apps.begin() + (apps.size() > 2 ? 2 : apps.size()));
examples.assign(apps.begin(),
apps.begin() + (apps.size() > 2 ? 2 : apps.size()));
HostedAppsCounter::HostedAppsResult result(
&counter,
apps.size(),
examples);
HostedAppsCounter::HostedAppsResult result(&counter, apps.size(), examples);
base::string16 output =
GetChromeCounterTextFromResult(&result, GetProfile());
......@@ -173,3 +174,50 @@ TEST_F(BrowsingDataCounterUtilsTest, DeleteCookiesBasicWithMediaLicenses) {
<< output;
}
#endif
// Tests the output for "Passwords and other sign-in data" on the advanced tab.
TEST_F(BrowsingDataCounterUtilsTest, DeletePasswordsAndSigninData) {
// This test assumes that the strings are served exactly as defined,
// i.e. that the locale is set to the default "en".
ASSERT_EQ("en", TestingBrowserProcess::GetGlobal()->GetApplicationLocale());
auto password_store =
base::MakeRefCounted<password_manager::TestPasswordStore>();
// This counter does not really count anything; we just need a reference to
// pass to the SigninDataResult ctor.
browsing_data::SigninDataCounter counter(
password_store, ProfileSyncServiceFactory::GetForProfile(GetProfile()),
nullptr);
const struct TestCase {
int num_passwords;
int num_webauthn_credentials;
bool sync_enabled;
std::string expected_output;
} kTestCases[] = {
{0, 0, false, "None"},
{0, 0, true, "None"},
{1, 0, false, "1 password"},
{1, 0, true, "1 password (synced)"},
{2, 0, false, "2 passwords"},
{2, 0, true, "2 passwords (synced)"},
{0, 1, false, "sign-in data for 1 account"},
{0, 1, true, "sign-in data for 1 account"},
{0, 2, false, "sign-in data for 2 accounts"},
{0, 2, true, "sign-in data for 2 accounts"},
{1, 2, false, "1 password; sign-in data for 2 accounts"},
{2, 1, false, "2 passwords; sign-in data for 1 account"},
{2, 3, true, "2 passwords (synced); sign-in data for 3 accounts"},
};
for (const auto& test_case : kTestCases) {
browsing_data::SigninDataCounter::SigninDataResult result(
&counter, test_case.num_passwords, test_case.num_webauthn_credentials,
test_case.sync_enabled);
std::string output = base::UTF16ToASCII(
GetChromeCounterTextFromResult(&result, GetProfile()));
EXPECT_EQ(test_case.expected_output, output);
}
password_store->ShutdownOnUIThread();
}
// Copyright 2018 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 "chrome/browser/browsing_data/counters/signin_data_counter.h"
namespace browsing_data {
SigninDataCounter::SigninDataCounter(
scoped_refptr<password_manager::PasswordStore> store,
syncer::SyncService* sync_service,
std::unique_ptr<::device::fido::PlatformCredentialStore>
opt_platform_credential_store)
: PasswordsCounter(store, sync_service),
credential_store_(std::move(opt_platform_credential_store)) {}
SigninDataCounter::~SigninDataCounter() = default;
int SigninDataCounter::CountWebAuthnCredentials() {
return credential_store_ ? credential_store_->CountCredentials(
GetPeriodStart(), GetPeriodEnd())
: 0;
}
std::unique_ptr<BrowsingDataCounter::SyncResult>
SigninDataCounter::MakeResult() {
return std::make_unique<SigninDataResult>(
this, num_passwords(), CountWebAuthnCredentials(), is_sync_active());
}
SigninDataCounter::SigninDataResult::SigninDataResult(
const SigninDataCounter* source,
ResultInt num_passwords,
ResultInt num_webauthn_credentials,
bool sync_enabled)
: BrowsingDataCounter::SyncResult(source, num_passwords, sync_enabled),
num_webauthn_credentials_(num_webauthn_credentials) {}
SigninDataCounter::SigninDataResult::~SigninDataResult() {}
} // namespace browsing_data
// Copyright 2018 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_BROWSING_DATA_COUNTERS_SIGNIN_DATA_COUNTER_H_
#define CHROME_BROWSER_BROWSING_DATA_COUNTERS_SIGNIN_DATA_COUNTER_H_
#include <memory>
#include <vector>
#include "components/browsing_data/core/counters/passwords_counter.h"
#include "device/fido/platform_credential_store.h"
namespace browsing_data {
class SigninDataCounter : public PasswordsCounter {
public:
class SigninDataResult : public SyncResult {
public:
SigninDataResult(const SigninDataCounter* source,
ResultInt num_passwords,
ResultInt num_webauthn_credentials,
bool sync_enabled);
~SigninDataResult() override;
ResultInt WebAuthnCredentialsValue() const {
return num_webauthn_credentials_;
}
private:
ResultInt num_webauthn_credentials_;
};
explicit SigninDataCounter(
scoped_refptr<password_manager::PasswordStore> password_store,
syncer::SyncService* sync_service,
std::unique_ptr<::device::fido::PlatformCredentialStore>
opt_platform_credential_store);
~SigninDataCounter() override;
private:
int CountWebAuthnCredentials();
std::unique_ptr<SyncResult> MakeResult() override;
std::unique_ptr<::device::fido::PlatformCredentialStore> credential_store_;
};
} // namespace browsing_data
#endif // CHROME_BROWSER_BROWSING_DATA_COUNTERS_SIGNIN_DATA_COUNTER_H_
......@@ -54,17 +54,22 @@ void PasswordsCounter::Count() {
store_->GetAutofillableLogins(this);
}
std::unique_ptr<BrowsingDataCounter::SyncResult>
PasswordsCounter::MakeResult() {
return std::make_unique<BrowsingDataCounter::SyncResult>(this, num_passwords_,
is_sync_active());
}
void PasswordsCounter::OnGetPasswordStoreResults(
std::vector<std::unique_ptr<autofill::PasswordForm>> results) {
base::Time start = GetPeriodStart();
base::Time end = GetPeriodEnd();
int num_passwords = std::count_if(
num_passwords_ = std::count_if(
results.begin(), results.end(),
[start, end](const std::unique_ptr<autofill::PasswordForm>& form) {
return (form->date_created >= start && form->date_created < end);
});
ReportResult(std::make_unique<SyncResult>(this, num_passwords,
sync_tracker_.IsSyncActive()));
ReportResult(MakeResult());
}
void PasswordsCounter::OnLoginsChanged(
......
......@@ -26,6 +26,12 @@ class PasswordsCounter : public browsing_data::BrowsingDataCounter,
const char* GetPrefName() const override;
protected:
virtual std::unique_ptr<SyncResult> MakeResult();
bool is_sync_active() { return sync_tracker_.IsSyncActive(); };
int num_passwords() { return num_passwords_; }
private:
void OnInitialized() override;
......@@ -44,6 +50,7 @@ class PasswordsCounter : public browsing_data::BrowsingDataCounter,
base::CancelableTaskTracker cancelable_task_tracker_;
scoped_refptr<password_manager::PasswordStore> store_;
SyncTracker sync_tracker_;
int num_passwords_;
};
} // namespace browsing_data
......
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