Commit 5afe20d8 authored by timidger's avatar timidger Committed by Commit Bot

Added DisableExtension mojo method to the ChromePrompt interface.

This allows the Chrome Cleanup Tool to request Chrome to delete extensions it finds.

This was put in the mojom interface because it's the simplest way to add to the CCT
interface to Chrome. This has no real dependency on the chrome prompt
workflow.

Also changes the chrome cleaner to only build on platforms that support extensions as it was breaking on android (which we don't support).

R=joenotcharles@chromium.org, joenotcharles@google.com, kinuko@chromium.org, reillyg@chromium.org

Bug: 889568
Change-Id: Idbbebda824e3d7764940773964f50045639617bd
Reviewed-on: https://chromium-review.googlesource.com/1207219
Commit-Queue: Preston Carpenter <timidger@google.com>
Reviewed-by: default avatarDemetrios Papadopoulos <dpapad@chromium.org>
Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarJoe Mason <joenotcharles@chromium.org>
Reviewed-by: default avatarJialiu Lin <jialiul@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594711}
parent 342d2451
......@@ -7,31 +7,6 @@ import("//third_party/protobuf/proto_library.gni")
static_library("safe_browsing") {
sources = [
"chrome_cleaner/chrome_cleaner_controller_impl_win.cc",
"chrome_cleaner/chrome_cleaner_controller_impl_win.h",
"chrome_cleaner/chrome_cleaner_controller_win.h",
"chrome_cleaner/chrome_cleaner_extensions_util_win.h",
"chrome_cleaner/chrome_cleaner_fetcher_win.cc",
"chrome_cleaner/chrome_cleaner_fetcher_win.h",
"chrome_cleaner/chrome_cleaner_navigation_util_win.cc",
"chrome_cleaner/chrome_cleaner_navigation_util_win.h",
"chrome_cleaner/chrome_cleaner_reboot_dialog_controller_impl_win.cc",
"chrome_cleaner/chrome_cleaner_reboot_dialog_controller_impl_win.h",
"chrome_cleaner/chrome_cleaner_reboot_dialog_controller_win.h",
"chrome_cleaner/chrome_cleaner_runner_win.cc",
"chrome_cleaner/chrome_cleaner_runner_win.h",
"chrome_cleaner/chrome_cleaner_scanner_results.cc",
"chrome_cleaner/chrome_cleaner_scanner_results.h",
"chrome_cleaner/reporter_runner_win.cc",
"chrome_cleaner/reporter_runner_win.h",
"chrome_cleaner/settings_resetter_win.cc",
"chrome_cleaner/settings_resetter_win.h",
"chrome_cleaner/srt_chrome_prompt_impl.cc",
"chrome_cleaner/srt_chrome_prompt_impl.h",
"chrome_cleaner/srt_client_info_win.cc",
"chrome_cleaner/srt_client_info_win.h",
"chrome_cleaner/srt_field_trial_win.cc",
"chrome_cleaner/srt_field_trial_win.h",
"safe_browsing_controller_client.cc",
"safe_browsing_controller_client.h",
"safe_browsing_tab_observer.cc",
......@@ -50,9 +25,34 @@ static_library("safe_browsing") {
if (enable_extensions) {
sources += [
"chrome_cleaner/chrome_cleaner_controller_impl_win.cc",
"chrome_cleaner/chrome_cleaner_controller_impl_win.h",
"chrome_cleaner/chrome_cleaner_controller_win.h",
"chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc",
"chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h",
"chrome_cleaner/chrome_cleaner_dialog_controller_win.h",
"chrome_cleaner/chrome_cleaner_extensions_util_win.h",
"chrome_cleaner/chrome_cleaner_fetcher_win.cc",
"chrome_cleaner/chrome_cleaner_fetcher_win.h",
"chrome_cleaner/chrome_cleaner_navigation_util_win.cc",
"chrome_cleaner/chrome_cleaner_navigation_util_win.h",
"chrome_cleaner/chrome_cleaner_reboot_dialog_controller_impl_win.cc",
"chrome_cleaner/chrome_cleaner_reboot_dialog_controller_impl_win.h",
"chrome_cleaner/chrome_cleaner_reboot_dialog_controller_win.h",
"chrome_cleaner/chrome_cleaner_runner_win.cc",
"chrome_cleaner/chrome_cleaner_runner_win.h",
"chrome_cleaner/chrome_cleaner_scanner_results.cc",
"chrome_cleaner/chrome_cleaner_scanner_results.h",
"chrome_cleaner/reporter_runner_win.cc",
"chrome_cleaner/reporter_runner_win.h",
"chrome_cleaner/settings_resetter_win.cc",
"chrome_cleaner/settings_resetter_win.h",
"chrome_cleaner/srt_chrome_prompt_impl.cc",
"chrome_cleaner/srt_chrome_prompt_impl.h",
"chrome_cleaner/srt_client_info_win.cc",
"chrome_cleaner/srt_client_info_win.h",
"chrome_cleaner/srt_field_trial_win.cc",
"chrome_cleaner/srt_field_trial_win.h",
"settings_reset_prompt/default_settings_fetcher.cc",
"settings_reset_prompt/default_settings_fetcher.h",
"settings_reset_prompt/settings_reset_prompt_config.cc",
......
......@@ -472,6 +472,7 @@ void ChromeCleanerControllerImpl::Scan(
void ChromeCleanerControllerImpl::ReplyWithUserResponse(
Profile* profile,
extensions::ExtensionService* extension_service,
UserResponse user_response) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
......@@ -489,6 +490,7 @@ void ChromeCleanerControllerImpl::ReplyWithUserResponse(
RecordCleanerLogsAcceptanceHistogram(true);
new_state = State::kCleaning;
delegate_->TagForResetting(profile);
extension_service_ = extension_service;
break;
case UserResponse::kAcceptedWithoutLogs:
acceptance = PromptAcceptance::ACCEPTED_WITHOUT_LOGS;
......@@ -496,6 +498,7 @@ void ChromeCleanerControllerImpl::ReplyWithUserResponse(
RecordCleanerLogsAcceptanceHistogram(false);
new_state = State::kCleaning;
delegate_->TagForResetting(profile);
extension_service_ = extension_service;
break;
case UserResponse::kDenied: // Fallthrough
case UserResponse::kDismissed:
......@@ -626,7 +629,8 @@ void ChromeCleanerControllerImpl::OnChromeCleanerFetchedAndVerified(
: ChromeCleanerRunner::ChromeMetricsStatus::kDisabled;
ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
executable_path, *reporter_invocation_, metrics_status,
extension_service_, executable_path, *reporter_invocation_,
metrics_status,
base::Bind(&ChromeCleanerControllerImpl::WeakOnPromptUser,
weak_factory_.GetWeakPtr()),
base::Bind(&ChromeCleanerControllerImpl::OnConnectionClosed,
......
......@@ -65,6 +65,7 @@ class ChromeCleanerControllerImpl : public ChromeCleanerController {
void OnSwReporterReady(SwReporterInvocationSequence&& invocations) override;
void Scan(const SwReporterInvocation& reporter_invocation) override;
void ReplyWithUserResponse(Profile* profile,
extensions::ExtensionService* extension_service,
UserResponse user_response) override;
void Reboot() override;
bool IsAllowedByPolicy() override;
......@@ -122,6 +123,8 @@ class ChromeCleanerControllerImpl : public ChromeCleanerController {
// Pointer to either real_delegate_ or one set by tests.
ChromeCleanerControllerDelegate* delegate_;
extensions::ExtensionService* extension_service_;
State state_ = State::kIdle;
// The logs permission checkboxes in the Chrome Cleaner dialog and webui page
// are opt out.
......
......@@ -16,6 +16,7 @@
#include "base/test/multiprocess_test.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
......@@ -235,14 +236,16 @@ typedef std::tuple<CleanerProcessStatus,
// Test fixture that runs a mock Chrome Cleaner process in various
// configurations and mocks the user's response.
class ChromeCleanerControllerTest
: public testing::TestWithParam<ChromeCleanerControllerTestParams>,
: public testing::WithParamInterface<ChromeCleanerControllerTestParams>,
public ChromeCleanerRunnerTestDelegate,
public ChromeCleanerControllerDelegate {
public ChromeCleanerControllerDelegate,
public extensions::ExtensionServiceTestBase {
public:
ChromeCleanerControllerTest() = default;
~ChromeCleanerControllerTest() override {}
void SetUp() override {
InitializeEmptyExtensionService();
std::tie(process_status_, crash_point_, uws_found_status_,
registry_keys_reporting_, extensions_reporting_, user_response_) =
GetParam();
......@@ -436,11 +439,6 @@ class ChromeCleanerControllerTest
}
protected:
// We need this because we need UI and IO threads during tests. The thread
// bundle should be the first member of the class so that it will be destroyed
// last.
content::TestBrowserThreadBundle thread_bundle_;
CleanerProcessStatus process_status_;
MockChromeCleanerProcess::CrashPoint crash_point_;
UwsFoundStatus uws_found_status_;
......@@ -482,7 +480,8 @@ MULTIPROCESS_TEST_MAIN(MockChromeCleanerProcessMain) {
}
TEST_P(ChromeCleanerControllerTest, WithMockCleanerProcess) {
TestingProfileManager profile_manager(TestingBrowserProcess::GetGlobal());
TestingProfileManager profile_manager(TestingBrowserProcess::GetGlobal(),
&testing_local_state_);
ASSERT_TRUE(profile_manager.SetUp());
constexpr char kTestProfileName1[] = "Test 1";
......@@ -524,8 +523,8 @@ TEST_P(ChromeCleanerControllerTest, WithMockCleanerProcess) {
EXPECT_CALL(mock_observer_, OnInfected(_, _))
.WillOnce(DoAll(SaveArg<1>(&scanner_results_on_infected),
InvokeWithoutArgs([this, profile1]() {
controller_->ReplyWithUserResponse(profile1,
user_response_);
controller_->ReplyWithUserResponse(
profile1, service(), user_response_);
})));
// Since logs upload is enabled by default, OnLogsEnabledChanged() will be
// called only if the user response is kAcceptedWithoutLogs.
......
......@@ -11,6 +11,7 @@
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_scanner_results.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h"
#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
......@@ -190,8 +191,10 @@ class ChromeCleanerController {
// in the kInfected state. This gracefully handles cases where multiple user
// responses are received, for example if a user manages to click on a
// "Cleanup" button multiple times.
virtual void ReplyWithUserResponse(Profile* profile,
UserResponse user_response) = 0;
virtual void ReplyWithUserResponse(
Profile* profile,
extensions::ExtensionService* extension_service,
UserResponse user_response) = 0;
// If the controller is in the kRebootRequired state, initiates a reboot of
// the computer. Call this after obtaining permission from the user to
......
......@@ -7,6 +7,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
......@@ -15,6 +16,7 @@
#include "chrome/browser/ui/browser_list.h"
#include "components/component_updater/pref_names.h"
#include "components/prefs/pref_service.h"
#include "extensions/browser/extension_system.h"
#include "ui/base/window_open_disposition.h"
namespace safe_browsing {
......@@ -87,8 +89,13 @@ void ChromeCleanerDialogControllerImpl::Accept(bool logs_enabled) {
base::RecordAction(
base::UserMetricsAction("SoftwareReporter.PromptDialog_Accepted"));
Profile* profile = browser_->profile();
extensions::ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile)->extension_service();
cleaner_controller_->ReplyWithUserResponse(
browser_->profile(),
profile, extension_service,
logs_enabled
? ChromeCleanerController::UserResponse::kAcceptedWithLogs
: ChromeCleanerController::UserResponse::kAcceptedWithoutLogs);
......@@ -108,8 +115,14 @@ void ChromeCleanerDialogControllerImpl::Cancel() {
base::RecordAction(
base::UserMetricsAction("SoftwareReporter.PromptDialog_Canceled"));
Profile* profile = browser_->profile();
extensions::ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile)->extension_service();
cleaner_controller_->ReplyWithUserResponse(
browser_->profile(), ChromeCleanerController::UserResponse::kDenied);
profile, extension_service,
ChromeCleanerController::UserResponse::kDenied);
OnInteractionDone();
}
......@@ -124,8 +137,14 @@ void ChromeCleanerDialogControllerImpl::Close() {
base::RecordAction(
base::UserMetricsAction("SoftwareReporter.PromptDialog_Dismissed"));
Profile* profile = browser_->profile();
extensions::ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile)->extension_service();
cleaner_controller_->ReplyWithUserResponse(
browser_->profile(), ChromeCleanerController::UserResponse::kDismissed);
profile, extension_service,
ChromeCleanerController::UserResponse::kDismissed);
OnInteractionDone();
}
......
......@@ -23,10 +23,12 @@
#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_task_traits.h"
#include "extensions/browser/extension_system.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"
using extensions::ExtensionService;
using chrome_cleaner::mojom::ChromePrompt;
using chrome_cleaner::mojom::ChromePromptRequest;
using content::BrowserThread;
......@@ -47,6 +49,7 @@ ChromeCleanerRunner::ProcessStatus::ProcessStatus(LaunchStatus launch_status,
// static
void ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
ExtensionService* extension_service,
const base::FilePath& cleaner_executable_path,
const SwReporterInvocation& reporter_invocation,
ChromeMetricsStatus metrics_status,
......@@ -55,9 +58,10 @@ void ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
ChromeCleanerRunner::ProcessDoneCallback on_process_done,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
auto cleaner_runner = base::WrapRefCounted(new ChromeCleanerRunner(
cleaner_executable_path, reporter_invocation, metrics_status,
std::move(on_prompt_user), std::move(on_connection_closed),
std::move(on_process_done), std::move(task_runner)));
extension_service, cleaner_executable_path, reporter_invocation,
metrics_status, std::move(on_prompt_user),
std::move(on_connection_closed), std::move(on_process_done),
std::move(task_runner)));
auto launch_and_wait = base::BindOnce(
&ChromeCleanerRunner::LaunchAndWaitForExitOnBackgroundThread,
cleaner_runner);
......@@ -74,6 +78,7 @@ void ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
}
ChromeCleanerRunner::ChromeCleanerRunner(
ExtensionService* extension_service,
const base::FilePath& cleaner_executable_path,
const SwReporterInvocation& reporter_invocation,
ChromeMetricsStatus metrics_status,
......@@ -85,7 +90,8 @@ ChromeCleanerRunner::ChromeCleanerRunner(
cleaner_command_line_(cleaner_executable_path),
on_prompt_user_(std::move(on_prompt_user)),
on_connection_closed_(std::move(on_connection_closed)),
on_process_done_(std::move(on_process_done)) {
on_process_done_(std::move(on_process_done)),
extension_service_(extension_service) {
DCHECK(on_prompt_user_);
DCHECK(on_connection_closed_);
DCHECK(on_process_done_);
......@@ -213,7 +219,7 @@ void ChromeCleanerRunner::CreateChromePromptImpl(
// Cannot use std::make_unique() since it does not support creating
// std::unique_ptrs with custom deleters.
chrome_prompt_impl_.reset(new ChromePromptImpl(
std::move(chrome_prompt_request),
extension_service_, std::move(chrome_prompt_request),
base::Bind(&ChromeCleanerRunner::OnConnectionClosed,
base::RetainedRef(this)),
base::Bind(&ChromeCleanerRunner::OnPromptUser, base::RetainedRef(this))));
......
......@@ -21,6 +21,7 @@
#include "chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h"
#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_system.h"
namespace safe_browsing {
......@@ -88,15 +89,19 @@ class ChromeCleanerRunner
//
// This function will pass command line flags to the Chrome Cleaner executable
// as appropriate based on the flags in |reporter_invocation| and the
// |metrics_status| parameters The Cleaner process will communicate with
// |metrics_status| parameters. The Cleaner process will communicate with
// Chrome via a Mojo IPC interface and any IPC requests or notifications are
// passed to the caller via the |on_prompt_user| and |on_connection_closed|
// callbacks. Finally, when the Chrome Cleaner process terminates, a
// ProcessStatus is passed along to |on_process_done|.
//
// This IPC interface needs the |extension_service| in order to
// disable extensions that the Cleaner process wants to disable.
//
// The details of the mojo interface are documented in
// "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h".
static void RunChromeCleanerAndReplyWithExitCode(
extensions::ExtensionService* extension_service,
const base::FilePath& cleaner_executable_path,
const SwReporterInvocation& reporter_invocation,
ChromeMetricsStatus metrics_status,
......@@ -110,7 +115,8 @@ class ChromeCleanerRunner
~ChromeCleanerRunner();
ChromeCleanerRunner(const base::FilePath& cleaner_executable_path,
ChromeCleanerRunner(extensions::ExtensionService* extension_service,
const base::FilePath& cleaner_executable_path,
const SwReporterInvocation& reporter_invocation,
ChromeMetricsStatus metrics_status,
ChromePromptImpl::OnPromptUser on_prompt_user,
......@@ -139,6 +145,7 @@ class ChromeCleanerRunner
std::unique_ptr<ChromePromptImpl, content::BrowserThread::DeleteOnIOThread>
chrome_prompt_impl_;
extensions::ExtensionService* extension_service_;
};
// A delegate class used to override launching of the Cleaner proccess for
......
......@@ -115,6 +115,7 @@ class ChromeCleanerRunnerSimpleTest
reporter_invocation.set_chrome_prompt(chrome_prompt_);
ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
/*extension_service=*/nullptr,
base::FilePath(FILE_PATH_LITERAL("cleaner.exe")), reporter_invocation,
metrics_status_,
base::BindOnce(&ChromeCleanerRunnerSimpleTest::OnPromptUser,
......@@ -300,6 +301,7 @@ class ChromeCleanerRunnerTest
void CallRunChromeCleaner() {
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
ChromeCleanerRunner::RunChromeCleanerAndReplyWithExitCode(
/*extension_service=*/nullptr,
base::FilePath(FILE_PATH_LITERAL("cleaner.exe")),
SwReporterInvocation(command_line), ChromeMetricsStatus::kDisabled,
base::BindOnce(&ChromeCleanerRunnerTest::OnPromptUser,
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_SAFE_BROWSING_CHROME_CLEANER_MOCK_CHROME_CLEANER_CONTROLLER_WIN_H_
#define CHROME_BROWSER_SAFE_BROWSING_CHROME_CLEANER_MOCK_CHROME_CLEANER_CONTROLLER_WIN_H_
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h"
#include "testing/gmock/include/gmock/gmock.h"
......@@ -32,7 +33,8 @@ class MockChromeCleanerController
MOCK_METHOD0(RequestUserInitiatedScan, void());
MOCK_METHOD1(MockedOnSwReporterReady, void(SwReporterInvocationSequence&));
MOCK_METHOD1(Scan, void(const safe_browsing::SwReporterInvocation&));
MOCK_METHOD2(ReplyWithUserResponse, void(Profile*, UserResponse));
MOCK_METHOD3(ReplyWithUserResponse,
void(Profile*, extensions::ExtensionService*, UserResponse));
MOCK_METHOD0(Reboot, void());
MOCK_METHOD0(IsAllowedByPolicy, bool());
MOCK_METHOD0(IsReportingAllowedByPolicy, bool());
......
......@@ -4,12 +4,17 @@
#include "chrome/browser/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h"
#include <algorithm>
#include <utility>
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_service.h"
#include "components/crx_file/id_util.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/disable_reason.h"
namespace safe_browsing {
......@@ -18,10 +23,13 @@ using chrome_cleaner::mojom::ChromePromptRequest;
using chrome_cleaner::mojom::PromptAcceptance;
using content::BrowserThread;
ChromePromptImpl::ChromePromptImpl(ChromePromptRequest request,
base::Closure on_connection_closed,
OnPromptUser on_prompt_user)
ChromePromptImpl::ChromePromptImpl(
extensions::ExtensionService* extension_service,
ChromePromptRequest request,
base::RepeatingClosure on_connection_closed,
OnPromptUser on_prompt_user)
: binding_(this, std::move(request)),
extension_service_(extension_service),
on_prompt_user_(std::move(on_prompt_user)) {
DCHECK(on_prompt_user_);
DCHECK_CURRENTLY_ON(BrowserThread::IO);
......@@ -56,4 +64,28 @@ void ChromePromptImpl::PromptUser(
}
}
void ChromePromptImpl::DisableExtensions(
const std::vector<base::string16>& extension_ids,
ChromePrompt::DisableExtensionsCallback callback) {
if (extension_service_ == nullptr) {
std::move(callback).Run(false);
return;
}
bool ids_are_valid = std::all_of(
extension_ids.begin(), extension_ids.end(), [](const base::string16& id) {
return crx_file::id_util::IdIsValid(base::UTF16ToUTF8(id));
});
if (!ids_are_valid) {
std::move(callback).Run(false);
return;
}
int reason = extensions::disable_reason::DISABLE_EXTERNAL_EXTENSION;
for (const base::string16& extension_id : extension_ids) {
extension_service_->DisableExtension(base::UTF16ToUTF8(extension_id),
reason);
}
std::move(callback).Run(true);
}
} // namespace safe_browsing
......@@ -12,6 +12,7 @@
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_scanner_results.h"
#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h"
#include "mojo/public/cpp/bindings/binding.h"
......@@ -26,7 +27,8 @@ class ChromePromptImpl : public chrome_cleaner::mojom::ChromePrompt {
ChromeCleanerScannerResults&&,
chrome_cleaner::mojom::ChromePrompt::PromptUserCallback)>;
ChromePromptImpl(chrome_cleaner::mojom::ChromePromptRequest request,
ChromePromptImpl(extensions::ExtensionService* extension_service,
chrome_cleaner::mojom::ChromePromptRequest request,
base::Closure on_connection_closed,
OnPromptUser on_prompt_user);
~ChromePromptImpl() override;
......@@ -38,8 +40,14 @@ class ChromePromptImpl : public chrome_cleaner::mojom::ChromePrompt {
chrome_cleaner::mojom::ChromePrompt::PromptUserCallback callback)
override;
void DisableExtensions(
const std::vector<base::string16>& extension_ids,
chrome_cleaner::mojom::ChromePrompt::DisableExtensionsCallback callback)
override;
private:
mojo::Binding<chrome_cleaner::mojom::ChromePrompt> binding_;
extensions::ExtensionService* extension_service_;
OnPromptUser on_prompt_user_;
DISALLOW_COPY_AND_ASSIGN(ChromePromptImpl);
......
// 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/safe_browsing/chrome_cleaner/srt_chrome_prompt_impl.h"
#include "base/location.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/extensions/test_extension_service.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/mock_extension_system.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/extension_set.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace safe_browsing {
class ExtensionDeletionTest : public extensions::ExtensionServiceTestBase {
public:
ExtensionDeletionTest() { InitializeEmptyExtensionService(); }
~ExtensionDeletionTest() override = default;
void SetUp() override {}
private:
DISALLOW_COPY_AND_ASSIGN(ExtensionDeletionTest);
};
TEST_F(ExtensionDeletionTest, DisableExtensionTest) {
std::vector<base::string16> extension_ids{};
extensions::ExtensionService* extension_service = this->service();
for (int i = 40; i < 43; i++) {
scoped_refptr<extensions::Extension> extension =
extensions::ExtensionBuilder(base::NumberToString(i))
.SetManifestKey("version", "1")
.Build();
auto id = extension->id();
extension_ids.push_back(base::UTF8ToUTF16(id));
extension_service->AddExtension(extension.get());
extension_service->EnableExtension(id);
}
std::unique_ptr<ChromePromptImpl> chrome_prompt =
std::make_unique<ChromePromptImpl>(extension_service, nullptr,
base::DoNothing(), base::DoNothing());
std::vector<base::string16> extensions_to_disable{extension_ids[0]};
chrome_prompt->DisableExtensions(
extensions_to_disable,
base::BindOnce([](bool result) { EXPECT_TRUE(result); }));
EXPECT_FALSE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[0])));
EXPECT_TRUE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[1])));
EXPECT_TRUE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[2])));
extensions_to_disable.push_back(extension_ids[2]);
chrome_prompt->DisableExtensions(
extensions_to_disable,
base::BindOnce([](bool result) { EXPECT_TRUE(result); }));
EXPECT_FALSE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[0])));
EXPECT_TRUE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[1])));
EXPECT_FALSE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[2])));
extensions_to_disable.push_back(extension_ids[1]);
chrome_prompt->DisableExtensions(
extensions_to_disable,
base::BindOnce([](bool result) { EXPECT_TRUE(result); }));
EXPECT_FALSE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[0])));
EXPECT_FALSE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[1])));
EXPECT_FALSE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[2])));
}
TEST_F(ExtensionDeletionTest, EmptyDeletionTest) {
std::vector<base::string16> extension_ids{};
extensions::ExtensionService* extension_service = this->service();
std::unique_ptr<ChromePromptImpl> chrome_prompt =
std::make_unique<ChromePromptImpl>(extension_service, nullptr,
base::DoNothing(), base::DoNothing());
for (int i = 40; i < 43; i++) {
scoped_refptr<extensions::Extension> extension =
extensions::ExtensionBuilder(base::NumberToString(i))
.SetManifestKey("version", "1")
.Build();
auto id = extension->id();
extension_ids.push_back(base::UTF8ToUTF16(id));
extension_service->AddExtension(extension.get());
extension_service->EnableExtension(id);
}
chrome_prompt->DisableExtensions(
{}, base::BindOnce([](bool result) { EXPECT_TRUE(result); }));
EXPECT_TRUE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[0])));
EXPECT_TRUE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[1])));
EXPECT_TRUE(extension_service->IsExtensionEnabled(
base::UTF16ToUTF8(extension_ids[2])));
}
TEST_F(ExtensionDeletionTest, BadlyFormattedDeletionTest) {
std::vector<base::string16> extension_ids{};
extensions::ExtensionService* extension_service = this->service();
std::unique_ptr<ChromePromptImpl> chrome_prompt =
std::make_unique<ChromePromptImpl>(extension_service, nullptr,
base::DoNothing(), base::DoNothing());
for (int i = 40; i < 43; i++) {
scoped_refptr<extensions::Extension> extension =
extensions::ExtensionBuilder(base::NumberToString(i))
.SetManifestKey("version", "1")
.Build();
auto id = extension->id();
extension_ids.push_back(base::UTF8ToUTF16(id));
extension_service->AddExtension(extension.get());
extension_service->EnableExtension(id);
}
chrome_prompt->DisableExtensions(
{L"bad-extension-id"},
base::BindOnce([](bool result) { EXPECT_FALSE(result); }));
chrome_prompt->DisableExtensions(
{L""}, base::BindOnce([](bool result) { EXPECT_FALSE(result); }));
chrome_prompt->DisableExtensions(
{L"🤷☝¯\\_(ツ)_/¯✌🤷"},
base::BindOnce([](bool result) { EXPECT_FALSE(result); }));
}
TEST_F(ExtensionDeletionTest, NotInstalledExtensionTest) {
std::vector<base::string16> extension_ids{};
extensions::ExtensionService* extension_service = this->service();
std::unique_ptr<ChromePromptImpl> chrome_prompt =
std::make_unique<ChromePromptImpl>(extension_service, nullptr,
base::DoNothing(), base::DoNothing());
for (int i = 40; i < 43; i++) {
// Don't actually install the extension
scoped_refptr<extensions::Extension> extension =
extensions::ExtensionBuilder(base::NumberToString(i))
.SetManifestKey("version", "1")
.Build();
auto id = extension->id();
extension_ids.push_back(base::UTF8ToUTF16(id));
}
chrome_prompt->DisableExtensions(
extension_ids, base::BindOnce([](bool result) { EXPECT_TRUE(result); }));
}
} // namespace safe_browsing
......@@ -18,6 +18,7 @@
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/reporter_runner_win.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
......@@ -27,6 +28,7 @@
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_message_handler.h"
#include "extensions/browser/extension_system.h"
#include "ui/base/l10n/l10n_util.h"
using safe_browsing::ChromeCleanerController;
......@@ -284,8 +286,11 @@ void ChromeCleanupHandler::HandleStartCleanup(const base::ListValue* args) {
base::RecordAction(
base::UserMetricsAction("SoftwareReporter.CleanupWebui_StartCleanup"));
extensions::ExtensionService* extension_service =
extensions::ExtensionSystem::Get(profile_)->extension_service();
controller_->ReplyWithUserResponse(
profile_,
profile_, extension_service,
allow_logs_upload
? ChromeCleanerController::UserResponse::kAcceptedWithLogs
: ChromeCleanerController::UserResponse::kAcceptedWithoutLogs);
......
......@@ -110,6 +110,10 @@ class MockChromePrompt : public mojom::ChromePrompt {
CloseConnectionIf(ParentDisconnected::kOnDone);
}
void DisableExtensions(
const std::vector<base::string16>& extension_ids,
ChromePrompt::DisableExtensionsCallback callback) override {}
// Close the IPC connection on the parent process depending on the value of
// |parent_disconnected|.
void CloseConnectionIf(ParentDisconnected parent_disconnected) {
......
......@@ -3100,6 +3100,7 @@ test("unit_tests") {
"../browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win_unittest.cc",
"../browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.cc",
"../browser/safe_browsing/chrome_cleaner/mock_chrome_cleaner_process_win.h",
"../browser/safe_browsing/chrome_cleaner/srt_delete_extension_win_unittest.cc",
"../browser/safe_browsing/chrome_cleaner/srt_field_trial_win_unittest.cc",
"../browser/search/background/ntp_background_service_unittest.cc",
"../browser/search/iframe_source_unittest.cc",
......
......@@ -45,7 +45,17 @@ class ProfileManager : public ::ProfileManagerWithoutInit {
TestingProfileManager::TestingProfileManager(TestingBrowserProcess* process)
: called_set_up_(false),
browser_process_(process),
local_state_(process),
owned_local_state_(std::make_unique<ScopedTestingLocalState>(process)),
profile_manager_(nullptr) {
local_state_ = owned_local_state_.get();
}
TestingProfileManager::TestingProfileManager(
TestingBrowserProcess* process,
ScopedTestingLocalState* local_state)
: called_set_up_(false),
browser_process_(process),
local_state_(local_state),
profile_manager_(nullptr) {}
TestingProfileManager::~TestingProfileManager() {
......
......@@ -37,6 +37,8 @@ class PrefServiceSyncable;
class TestingProfileManager {
public:
explicit TestingProfileManager(TestingBrowserProcess* browser_process);
TestingProfileManager(TestingBrowserProcess* browser_process,
ScopedTestingLocalState* local_state);
~TestingProfileManager();
// This needs to be called in testing::Test::SetUp() to put the object in a
......@@ -110,7 +112,7 @@ class TestingProfileManager {
const base::FilePath& profiles_dir();
ProfileManager* profile_manager();
ProfileAttributesStorage* profile_attributes_storage();
ScopedTestingLocalState* local_state() { return &local_state_; }
ScopedTestingLocalState* local_state() { return local_state_; }
private:
friend class ProfileAttributesStorageTest;
......@@ -149,7 +151,10 @@ class TestingProfileManager {
TestingBrowserProcess* browser_process_;
// Local state in which all the profiles are registered.
ScopedTestingLocalState local_state_;
ScopedTestingLocalState* local_state_;
// Owned local state for when it's not provided in the constructor.
std::unique_ptr<ScopedTestingLocalState> owned_local_state_;
// Weak reference to the profile manager.
ProfileManager* profile_manager_;
......
......@@ -58,4 +58,12 @@ interface ChromePrompt {
[MinVersion=1] array<RegistryKey>? registry_keys,
[MinVersion=2] array<ExtensionId>? extension_ids)
=> (PromptAcceptance prompt_acceptance);
// Params:
// - extension_ids: list of IDs of extensions that will be removed from
// Chrome. If there are any invalid IDs, none are removed and false is
// returned.
// Returns:
// - success: indicates if the extension removal was successful.
DisableExtensions(array<ExtensionId> extension_ids) => (bool success);
};
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