1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/supervised_user/supervised_user_pref_store.h"
6
7 #include <utility>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/metrics/histogram_functions.h"
13 #include "base/values.h"
14 #include "build/build_config.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/prefs/incognito_mode_prefs.h"
17 #include "chrome/browser/supervised_user/supervised_user_constants.h"
18 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
19 #include "chrome/browser/supervised_user/supervised_user_url_filter.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/net/safe_search_util.h"
22 #include "chrome/common/pref_names.h"
23 #include "components/feed/core/shared_prefs/pref_names.h"
24 #include "components/prefs/pref_value_map.h"
25 #include "components/signin/public/base/signin_pref_names.h"
26 #include "extensions/buildflags/buildflags.h"
27
28 namespace {
29
30 struct SupervisedUserSettingsPrefMappingEntry {
31 const char* settings_name;
32 const char* pref_name;
33 };
34
35 SupervisedUserSettingsPrefMappingEntry kSupervisedUserSettingsPrefMapping[] = {
36 {
37 supervised_users::kContentPackDefaultFilteringBehavior,
38 prefs::kDefaultSupervisedUserFilteringBehavior,
39 },
40 {
41 supervised_users::kContentPackManualBehaviorHosts,
42 prefs::kSupervisedUserManualHosts,
43 },
44 {
45 supervised_users::kContentPackManualBehaviorURLs,
46 prefs::kSupervisedUserManualURLs,
47 },
48 {
49 supervised_users::kForceSafeSearch,
50 prefs::kForceGoogleSafeSearch,
51 },
52 {
53 supervised_users::kSafeSitesEnabled,
54 prefs::kSupervisedUserSafeSites,
55 },
56 {
57 supervised_users::kSigninAllowed,
58 prefs::kSigninAllowed,
59 },
60 {
61 supervised_users::kUserName,
62 prefs::kProfileName,
63 },
64 };
65
66 } // namespace
67
SupervisedUserPrefStore(SupervisedUserSettingsService * supervised_user_settings_service)68 SupervisedUserPrefStore::SupervisedUserPrefStore(
69 SupervisedUserSettingsService* supervised_user_settings_service) {
70 user_settings_subscription_ =
71 supervised_user_settings_service->SubscribeForSettingsChange(
72 base::Bind(&SupervisedUserPrefStore::OnNewSettingsAvailable,
73 base::Unretained(this)));
74
75 // The SupervisedUserSettingsService must be created before the PrefStore, and
76 // it will notify the PrefStore to unsubscribe both subscriptions when it is
77 // shut down.
78 shutdown_subscription_ =
79 supervised_user_settings_service->SubscribeForShutdown(
80 base::BindRepeating(
81 &SupervisedUserPrefStore::OnSettingsServiceShutdown,
82 base::Unretained(this)));
83 }
84
GetValue(const std::string & key,const base::Value ** value) const85 bool SupervisedUserPrefStore::GetValue(const std::string& key,
86 const base::Value** value) const {
87 return prefs_->GetValue(key, value);
88 }
89
GetValues() const90 std::unique_ptr<base::DictionaryValue> SupervisedUserPrefStore::GetValues()
91 const {
92 return prefs_->AsDictionaryValue();
93 }
94
AddObserver(PrefStore::Observer * observer)95 void SupervisedUserPrefStore::AddObserver(PrefStore::Observer* observer) {
96 observers_.AddObserver(observer);
97 }
98
RemoveObserver(PrefStore::Observer * observer)99 void SupervisedUserPrefStore::RemoveObserver(PrefStore::Observer* observer) {
100 observers_.RemoveObserver(observer);
101 }
102
HasObservers() const103 bool SupervisedUserPrefStore::HasObservers() const {
104 return observers_.might_have_observers();
105 }
106
IsInitializationComplete() const107 bool SupervisedUserPrefStore::IsInitializationComplete() const {
108 return !!prefs_;
109 }
110
~SupervisedUserPrefStore()111 SupervisedUserPrefStore::~SupervisedUserPrefStore() {
112 }
113
OnNewSettingsAvailable(const base::DictionaryValue * settings)114 void SupervisedUserPrefStore::OnNewSettingsAvailable(
115 const base::DictionaryValue* settings) {
116 std::unique_ptr<PrefValueMap> old_prefs = std::move(prefs_);
117 prefs_.reset(new PrefValueMap);
118 if (settings) {
119 // Set hardcoded prefs and defaults.
120 prefs_->SetInteger(prefs::kDefaultSupervisedUserFilteringBehavior,
121 SupervisedUserURLFilter::ALLOW);
122 prefs_->SetBoolean(prefs::kForceGoogleSafeSearch, true);
123 prefs_->SetInteger(prefs::kForceYouTubeRestrict,
124 safe_search_util::YOUTUBE_RESTRICT_MODERATE);
125 prefs_->SetBoolean(prefs::kHideWebStoreIcon, false);
126 prefs_->SetBoolean(prefs::kSigninAllowed, false);
127 prefs_->SetBoolean(feed::prefs::kEnableSnippets, false);
128
129 // Copy supervised user settings to prefs.
130 for (const auto& entry : kSupervisedUserSettingsPrefMapping) {
131 const base::Value* value = NULL;
132 if (settings->GetWithoutPathExpansion(entry.settings_name, &value))
133 prefs_->SetValue(entry.pref_name, value->Clone());
134 }
135
136 // Manually set preferences that aren't direct copies of the settings value.
137 {
138 bool record_history = true;
139 settings->GetBoolean(supervised_users::kRecordHistory, &record_history);
140 prefs_->SetBoolean(prefs::kAllowDeletingBrowserHistory, !record_history);
141 prefs_->SetInteger(prefs::kIncognitoModeAvailability,
142 record_history ? IncognitoModePrefs::DISABLED
143 : IncognitoModePrefs::ENABLED);
144 }
145
146 {
147 // Note that |prefs::kForceGoogleSafeSearch| is set automatically as part
148 // of |kSupervisedUserSettingsPrefMapping|, but this can't be done for
149 // |prefs::kForceYouTubeRestrict| because it is an int, not a bool.
150 bool force_safe_search = true;
151 settings->GetBoolean(supervised_users::kForceSafeSearch,
152 &force_safe_search);
153 prefs_->SetInteger(
154 prefs::kForceYouTubeRestrict,
155 force_safe_search ? safe_search_util::YOUTUBE_RESTRICT_MODERATE
156 : safe_search_util::YOUTUBE_RESTRICT_OFF);
157 }
158
159 #if BUILDFLAG(ENABLE_EXTENSIONS)
160 {
161 // TODO(crbug/1024646): Update Kids Management server to set a new bit for
162 // extension permissions. Until then, rely on other side effects of the
163 // "Permissions for sites, apps and extensions" setting, like geolocation
164 // being disallowed.
165 bool permissions_disallowed = true;
166 settings->GetBoolean(supervised_users::kGeolocationDisabled,
167 &permissions_disallowed);
168 prefs_->SetBoolean(prefs::kSupervisedUserExtensionsMayRequestPermissions,
169 !permissions_disallowed);
170 base::UmaHistogramBoolean(
171 "SupervisedUsers.ExtensionsMayRequestPermissions",
172 !permissions_disallowed);
173 }
174 #endif
175 }
176
177 if (!old_prefs) {
178 for (Observer& observer : observers_)
179 observer.OnInitializationCompleted(true);
180 return;
181 }
182
183 std::vector<std::string> changed_prefs;
184 prefs_->GetDifferingKeys(old_prefs.get(), &changed_prefs);
185
186 // Send out change notifications.
187 for (const std::string& pref : changed_prefs) {
188 for (Observer& observer : observers_)
189 observer.OnPrefValueChanged(pref);
190 }
191 }
192
OnSettingsServiceShutdown()193 void SupervisedUserPrefStore::OnSettingsServiceShutdown() {
194 user_settings_subscription_.reset();
195 shutdown_subscription_.reset();
196 }
197