blob: cf80b132fd80afcf13eaee45950225306048ed2e [file] [log] [blame]
// Copyright 2019 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_UI_WEBUI_SETTINGS_SAFETY_CHECK_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_CHECK_HANDLER_H_
#include <stdint.h>
#include <memory>
#include <string>
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "base/types/strong_alias.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/ui/webui/help/version_updater.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "components/password_manager/core/browser/bulk_leak_check_service.h"
#include "components/password_manager/core/browser/ui/insecure_credentials_manager.h"
#include "components/safety_check/safety_check.h"
#include "components/safety_check/update_check_helper.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.h"
#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_scanner_results_win.h"
#endif
// Delegate for accessing external timestamps, overridden for tests.
class TimestampDelegate {
public:
virtual ~TimestampDelegate() = default;
virtual base::Time GetSystemTime();
#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
virtual base::Time FetchChromeCleanerScanCompletionTimestamp();
#endif
};
// Settings page UI handler that checks four areas of browser safety:
// browser updates, password leaks, malicious extensions, and unwanted
// software.
class SafetyCheckHandler
: public settings::SettingsPageUIHandler,
#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
public safe_browsing::ChromeCleanerController::Observer,
#endif
public password_manager::BulkLeakCheckServiceInterface::Observer,
public password_manager::InsecureCredentialsManager::Observer {
public:
// The following enum represent the state of the safety check parent
// component and should be kept in sync with the JS frontend
// (safety_check_browser_proxy.js).
enum class ParentStatus {
kBefore = 0,
kChecking = 1,
kAfter = 2,
};
// The following enums represent the state of each component of the safety
// check and should be kept in sync with the JS frontend
// (safety_check_browser_proxy.js) and |SafetyCheck*| metrics enums in
// enums.xml.
using PasswordsStatus = safety_check::PasswordsStatus;
using SafeBrowsingStatus = safety_check::SafeBrowsingStatus;
using UpdateStatus = safety_check::UpdateStatus;
enum class ExtensionsStatus {
kChecking = 0,
kError = 1,
kNoneBlocklisted = 2,
kBlocklistedAllDisabled = 3,
kBlocklistedReenabledAllByUser = 4,
// In this case, at least one of the extensions was re-enabled by admin.
kBlocklistedReenabledSomeByUser = 5,
kBlocklistedReenabledAllByAdmin = 6,
// New enum values must go above here.
kMaxValue = kBlocklistedReenabledAllByAdmin,
};
enum class ChromeCleanerStatus {
kHidden = 0,
kChecking = 1,
kInfected = 2,
kRebootRequired = 3,
kScanningForUws = 4,
kRemovingUws = 5,
kDisabledByAdmin = 6,
kError = 7,
kNoUwsFoundWithTimestamp = 8,
kNoUwsFoundWithoutTimestamp = 9,
// New enum values must go above here.
kMaxValue = kNoUwsFoundWithoutTimestamp,
};
struct ChromeCleanerResult {
SafetyCheckHandler::ChromeCleanerStatus status;
base::Time cct_completion_time;
};
SafetyCheckHandler();
~SafetyCheckHandler() override;
// Triggers WebUI updates about safety check now running.
// Note: since the checks deal with sensitive user information, this method
// should only be called as a result of an explicit user action.
void SendSafetyCheckStartedWebUiUpdates();
// Triggers all safety check child checks.
// Note: since the checks deal with sensitive user information, this method
// should only be called as a result of an explicit user action.
void PerformSafetyCheck();
// Constructs a string depicting how much time passed since the completion of
// something from the corresponding timestamps and strings IDs.
std::u16string GetStringForTimePassed(base::Time completion_timestamp,
base::Time system_time,
int less_than_one_minute_ago_message_id,
int minutes_ago_message_id,
int hours_ago_message_id,
int yesterday_message_id,
int days_ago_message_id);
// Constructs the 'safety check ran' display string by how long ago safety
// check ran.
std::u16string GetStringForParentRan(base::Time safety_check_completion_time);
std::u16string GetStringForParentRan(base::Time safety_check_completion_time,
base::Time system_time);
#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Constructs the string for the Chrome cleaner 'safe' state which depicts
// how long ago its last check ran.
std::u16string GetStringForChromeCleanerRan();
std::u16string GetStringForChromeCleanerRan(base::Time cct_completion_time,
base::Time system_time);
// safe_browsing::ChromeCleanerController::Observer overrides.
void OnIdle(
safe_browsing::ChromeCleanerController::IdleReason idle_reason) override;
void OnReporterRunning() override;
void OnScanning() override;
void OnInfected(bool is_powered_by_partner,
const safe_browsing::ChromeCleanerScannerResults&
scanner_results) override;
void OnCleaning(bool is_powered_by_partner,
const safe_browsing::ChromeCleanerScannerResults&
scanner_results) override;
void OnRebootRequired() override;
void OnRebootFailed() override;
#endif
protected:
SafetyCheckHandler(
std::unique_ptr<safety_check::UpdateCheckHelper> update_helper,
std::unique_ptr<VersionUpdater> version_updater,
password_manager::BulkLeakCheckService* leak_service,
extensions::PasswordsPrivateDelegate* passwords_delegate,
extensions::ExtensionPrefs* extension_prefs,
extensions::ExtensionServiceInterface* extension_service,
std::unique_ptr<TimestampDelegate> timestamp_delegate);
void SetVersionUpdaterForTesting(
std::unique_ptr<VersionUpdater> version_updater) {
version_updater_ = std::move(version_updater);
}
void SetTimestampDelegateForTesting(
std::unique_ptr<TimestampDelegate> timestamp_delegate) {
timestamp_delegate_ = std::move(timestamp_delegate);
}
private:
// These ensure integers are passed in the correct possitions in the extension
// check methods.
using Compromised = base::StrongAlias<class CompromisedTag, int>;
using Weak = base::StrongAlias<class WeakTag, int>;
using Done = base::StrongAlias<class DoneTag, int>;
using Total = base::StrongAlias<class TotalTag, int>;
using Blocklisted = base::StrongAlias<class BlocklistedTag, int>;
using ReenabledUser = base::StrongAlias<class ReenabledUserTag, int>;
using ReenabledAdmin = base::StrongAlias<class ReenabledAdminTag, int>;
// Handles triggering the safety check from the frontend (by user pressing a
// button).
void HandlePerformSafetyCheck(const base::ListValue* args);
// Handles updating the safety check parent display string to show how long
// ago the safety check last ran.
void HandleGetParentRanDisplayString(const base::ListValue* args);
// Triggers an update check and invokes OnUpdateCheckResult once results
// are available.
void CheckUpdates();
// Triggers a bulk password leak check and invokes OnPasswordsCheckResult once
// results are available.
void CheckPasswords();
// Checks if any of the installed extensions are blocklisted, and in
// that case, if any of those were re-enabled.
void CheckExtensions();
#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
// Checks for unwanted software via the Chrome Cleanup Tool. Only on Windows.
void CheckChromeCleaner();
#endif
// Callbacks that get triggered when each check completes.
void OnUpdateCheckResult(UpdateStatus status);
void OnPasswordsCheckResult(PasswordsStatus status,
Compromised compromised,
Weak weak,
Done done,
Total total);
void OnExtensionsCheckResult(ExtensionsStatus status,
Blocklisted blocklisted,
ReenabledUser reenabled_user,
ReenabledAdmin reenabled_admin);
#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
void OnChromeCleanerCheckResult(ChromeCleanerResult result);
#endif
// Methods for building user-visible strings based on the safety check
// state.
std::u16string GetStringForParent(ParentStatus status);
std::u16string GetStringForUpdates(UpdateStatus status);
std::u16string GetStringForSafeBrowsing(SafeBrowsingStatus status);
std::u16string GetStringForPasswords(PasswordsStatus status,
Compromised compromised,
Weak weak,
Done done,
Total total);
std::u16string GetStringForExtensions(ExtensionsStatus status,
Blocklisted blocklisted,
ReenabledUser reenabled_user,
ReenabledAdmin reenabled_admin);
#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
std::u16string GetStringForChromeCleaner(ChromeCleanerStatus status,
base::Time cct_completion_time,
base::Time system_time);
#endif
// A generic error state often includes the offline state. This method is used
// as a callback for |UpdateCheckHelper| to check connectivity.
void DetermineIfOfflineOrError(bool connected);
// Since the password check API does not distinguish between the cases of
// having no compromised passwords and not having any passwords at all, it is
// necessary to use this method as a callback for
// |PasswordsPrivateDelegate::GetSavedPasswordsList| to distinguish the two
// states here.
void DetermineIfNoPasswordsOrSafe(
const std::vector<extensions::api::passwords_private::PasswordUiEntry>&
passwords);
// Gets the compromised passwords count and invokes an appropriate result
// method depending on the state.
void UpdatePasswordsResultOnCheckIdle();
// A callback passed to |VersionUpdater::CheckForUpdate| to receive the update
// state.
void OnVersionUpdaterResult(VersionUpdater::Status status,
int progress,
bool rollback,
bool powerwash,
const std::string& version,
int64_t update_size,
const std::u16string& message);
// BulkLeakCheckService::Observer implementation.
void OnStateChanged(
password_manager::BulkLeakCheckService::State state) override;
void OnCredentialDone(const password_manager::LeakCheckCredential& credential,
password_manager::IsLeaked is_leaked) override;
// InsecureCredentialsManager::Observer implementation.
void OnInsecureCredentialsChanged(
password_manager::InsecureCredentialsManager::CredentialsView credentials)
override;
// SettingsPageUIHandler implementation.
void OnJavascriptAllowed() override;
void OnJavascriptDisallowed() override;
// WebUIMessageHandler implementation.
void RegisterMessages() override;
// Updates the parent status from the children statuses.
void CompleteParentIfChildrenCompleted();
// Fire a safety check element WebUI update with a state and string.
void FireBasicSafetyCheckWebUiListener(const std::string& event_name,
int new_state,
const std::u16string& display_string);
// The current status of the safety check elements. Before safety
// check is started, the parent is in the 'before' state.
ParentStatus parent_status_ = ParentStatus::kBefore;
UpdateStatus update_status_ = UpdateStatus::kChecking;
PasswordsStatus passwords_status_ = PasswordsStatus::kChecking;
SafeBrowsingStatus safe_browsing_status_ = SafeBrowsingStatus::kChecking;
ExtensionsStatus extensions_status_ = ExtensionsStatus::kChecking;
ChromeCleanerStatus chrome_cleaner_status_ = ChromeCleanerStatus::kHidden;
// System time when safety check completed.
base::Time safety_check_completion_time_;
// Tracks whether there is at least one |OnCredentialDone| callback with
// is_leaked = true.
bool compromised_passwords_exist_ = false;
std::unique_ptr<safety_check::UpdateCheckHelper> update_helper_;
std::unique_ptr<VersionUpdater> version_updater_;
password_manager::BulkLeakCheckServiceInterface* leak_service_ = nullptr;
password_manager::InsecureCredentialsManager* insecure_credentials_manager_ =
nullptr;
extensions::PasswordsPrivateDelegate* passwords_delegate_ = nullptr;
extensions::ExtensionPrefs* extension_prefs_ = nullptr;
extensions::ExtensionServiceInterface* extension_service_ = nullptr;
base::ScopedObservation<
password_manager::BulkLeakCheckServiceInterface,
password_manager::BulkLeakCheckServiceInterface::Observer>
observed_leak_check_{this};
base::ScopedObservation<
password_manager::InsecureCredentialsManager,
password_manager::InsecureCredentialsManager::Observer>
observed_insecure_credentials_manager_{this};
std::unique_ptr<TimestampDelegate> timestamp_delegate_;
base::WeakPtrFactory<SafetyCheckHandler> weak_ptr_factory_{this};
};
#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_SAFETY_CHECK_HANDLER_H_