blob: 28d4fc7171159f641c8b15319552f89055011906 [file] [log] [blame]
// Copyright 2020 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/generated_safe_browsing_pref.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/settings_private.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
namespace settings_api = extensions::api::settings_private;
namespace safe_browsing {
const char kGeneratedSafeBrowsingPref[] = "generated.safe_browsing";
GeneratedSafeBrowsingPref::GeneratedSafeBrowsingPref(Profile* profile)
: profile_(profile) {
user_prefs_registrar_.Init(profile->GetPrefs());
user_prefs_registrar_.Add(
prefs::kSafeBrowsingEnabled,
base::BindRepeating(
&GeneratedSafeBrowsingPref::OnSafeBrowsingPreferencesChanged,
base::Unretained(this)));
user_prefs_registrar_.Add(
prefs::kSafeBrowsingEnhanced,
base::BindRepeating(
&GeneratedSafeBrowsingPref::OnSafeBrowsingPreferencesChanged,
base::Unretained(this)));
user_prefs_registrar_.Add(
prefs::kSafeBrowsingScoutReportingEnabled,
base::BindRepeating(
&GeneratedSafeBrowsingPref::OnSafeBrowsingPreferencesChanged,
base::Unretained(this)));
}
extensions::settings_private::SetPrefResult GeneratedSafeBrowsingPref::SetPref(
const base::Value* value) {
if (!value->is_int())
return extensions::settings_private::SetPrefResult::PREF_TYPE_MISMATCH;
auto selection = static_cast<SafeBrowsingSetting>(value->GetInt());
if (selection != SafeBrowsingSetting::DISABLED &&
selection != SafeBrowsingSetting::STANDARD &&
selection != SafeBrowsingSetting::ENHANCED)
return extensions::settings_private::SetPrefResult::PREF_TYPE_MISMATCH;
// If SBER is forcefully disabled, Enhanced cannot be selected by the user.
const PrefService::Preference* reporting_pref =
profile_->GetPrefs()->FindPreference(
prefs::kSafeBrowsingScoutReportingEnabled);
const bool reporting_on = reporting_pref->GetValue()->GetBool();
const bool reporting_enforced = !reporting_pref->IsUserModifiable();
if (reporting_enforced && !reporting_on &&
selection == SafeBrowsingSetting::ENHANCED) {
return extensions::settings_private::SetPrefResult::PREF_NOT_MODIFIABLE;
}
// kSafeBrowsingEnabled is considered the canonical source for Safe Browsing
// management.
const PrefService::Preference* enabled_pref =
profile_->GetPrefs()->FindPreference(prefs::kSafeBrowsingEnabled);
if (!enabled_pref->IsUserModifiable()) {
return extensions::settings_private::SetPrefResult::PREF_NOT_MODIFIABLE;
}
// Update both Safe Browsing preferences to match selection.
profile_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled,
selection != SafeBrowsingSetting::DISABLED);
profile_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnhanced,
selection == SafeBrowsingSetting::ENHANCED);
return extensions::settings_private::SetPrefResult::SUCCESS;
}
std::unique_ptr<extensions::api::settings_private::PrefObject>
GeneratedSafeBrowsingPref::GetPrefObject() const {
auto pref_object =
std::make_unique<extensions::api::settings_private::PrefObject>();
pref_object->key = kGeneratedSafeBrowsingPref;
pref_object->type = extensions::api::settings_private::PREF_TYPE_NUMBER;
auto safe_browsing_enabled =
profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled);
auto safe_browsing_enhanced_enabled =
profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnhanced);
if (safe_browsing_enhanced_enabled && safe_browsing_enabled) {
pref_object->value = std::make_unique<base::Value>(
static_cast<int>(SafeBrowsingSetting::ENHANCED));
} else if (safe_browsing_enabled) {
pref_object->value = std::make_unique<base::Value>(
static_cast<int>(SafeBrowsingSetting::STANDARD));
} else {
pref_object->value = std::make_unique<base::Value>(
static_cast<int>(SafeBrowsingSetting::DISABLED));
}
ApplySafeBrowsingManagementState(profile_, pref_object.get());
return pref_object;
}
void GeneratedSafeBrowsingPref::OnSafeBrowsingPreferencesChanged() {
NotifyObservers(kGeneratedSafeBrowsingPref);
}
/* static */
void GeneratedSafeBrowsingPref::ApplySafeBrowsingManagementState(
const Profile* profile,
settings_api::PrefObject* pref_object) {
// Computing the effective Safe Browsing managed state requires inspecting
// three different preferences. It is possible that these may be in
// temporarily conflicting managed states. The enabled preference is always
// taken as the canonical source of management.
const PrefService::Preference* enabled_pref =
profile->GetPrefs()->FindPreference(prefs::kSafeBrowsingEnabled);
const bool enabled_enforced = !enabled_pref->IsUserModifiable();
const bool enabled_recommended =
(enabled_pref && enabled_pref->GetRecommendedValue());
const bool enabled_recommended_on =
enabled_recommended && enabled_pref->GetRecommendedValue()->GetBool();
// The enhanced preference may have a recommended setting. This only takes
// effect if the enabled preference also has a recommended setting.
const PrefService::Preference* enhanced_pref =
profile->GetPrefs()->FindPreference(prefs::kSafeBrowsingEnhanced);
const bool enhanced_recommended_on =
enhanced_pref->GetRecommendedValue() &&
enhanced_pref->GetRecommendedValue()->GetBool();
// A forcefully disabled reporting preference will disallow enhanced from
// being selected and thus it must also be considered.
const PrefService::Preference* reporting_pref =
profile->GetPrefs()->FindPreference(
prefs::kSafeBrowsingScoutReportingEnabled);
const bool reporting_on = reporting_pref->GetValue()->GetBool();
const bool reporting_enforced = !reporting_pref->IsUserModifiable();
if (!enabled_enforced && !enabled_recommended && !reporting_enforced) {
// No relevant policies are applied.
return;
}
if (enabled_enforced) {
// Preference is fully controlled.
pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED;
extensions::settings_private::GeneratedPref::ApplyControlledByFromPref(
pref_object, enabled_pref);
return;
}
if (enabled_recommended) {
// Set enforcement to recommended. This may be upgraded to enforced later
// in this function.
pref_object->enforcement =
settings_api::Enforcement::ENFORCEMENT_RECOMMENDED;
if (enhanced_recommended_on) {
pref_object->recommended_value = std::make_unique<base::Value>(
static_cast<int>(SafeBrowsingSetting::ENHANCED));
} else if (enabled_recommended_on) {
pref_object->recommended_value = std::make_unique<base::Value>(
static_cast<int>(SafeBrowsingSetting::STANDARD));
} else {
pref_object->recommended_value = std::make_unique<base::Value>(
static_cast<int>(SafeBrowsingSetting::DISABLED));
}
}
if (reporting_enforced && !reporting_on) {
// Reporting has been forcefully disabled by policy. Enhanced protection is
// thus also implicitly disabled by the same policy.
pref_object->enforcement = settings_api::Enforcement::ENFORCEMENT_ENFORCED;
extensions::settings_private::GeneratedPref::ApplyControlledByFromPref(
pref_object, reporting_pref);
pref_object->user_selectable_values =
std::make_unique<std::vector<std::unique_ptr<base::Value>>>();
pref_object->user_selectable_values->push_back(
std::make_unique<base::Value>(
static_cast<int>(SafeBrowsingSetting::STANDARD)));
pref_object->user_selectable_values->push_back(
std::make_unique<base::Value>(
static_cast<int>(SafeBrowsingSetting::DISABLED)));
}
}
} // namespace safe_browsing