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 <set>
6 #include <string>
7 
8 #include "base/memory/ref_counted.h"
9 #include "base/test/metrics/histogram_tester.h"
10 #include "base/values.h"
11 #include "chrome/browser/supervised_user/supervised_user_constants.h"
12 #include "chrome/browser/supervised_user/supervised_user_pref_store.h"
13 #include "chrome/browser/supervised_user/supervised_user_settings_service.h"
14 #include "chrome/common/net/safe_search_util.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/prefs/testing_pref_store.h"
17 #include "extensions/buildflags/buildflags.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 
20 using base::DictionaryValue;
21 using base::Value;
22 
23 namespace {
24 
25 class SupervisedUserPrefStoreFixture : public PrefStore::Observer {
26  public:
27   explicit SupervisedUserPrefStoreFixture(
28       SupervisedUserSettingsService* settings_service);
29   ~SupervisedUserPrefStoreFixture() override;
30 
changed_prefs()31   base::DictionaryValue* changed_prefs() {
32     return &changed_prefs_;
33   }
34 
initialization_completed() const35   bool initialization_completed() const {
36     return initialization_completed_;
37   }
38 
39   // PrefStore::Observer implementation:
40   void OnPrefValueChanged(const std::string& key) override;
41   void OnInitializationCompleted(bool succeeded) override;
42 
43  private:
44   scoped_refptr<SupervisedUserPrefStore> pref_store_;
45   base::DictionaryValue changed_prefs_;
46   bool initialization_completed_;
47 };
48 
SupervisedUserPrefStoreFixture(SupervisedUserSettingsService * settings_service)49 SupervisedUserPrefStoreFixture::SupervisedUserPrefStoreFixture(
50     SupervisedUserSettingsService* settings_service)
51     : pref_store_(new SupervisedUserPrefStore(settings_service)),
52       initialization_completed_(pref_store_->IsInitializationComplete()) {
53   pref_store_->AddObserver(this);
54 }
55 
~SupervisedUserPrefStoreFixture()56 SupervisedUserPrefStoreFixture::~SupervisedUserPrefStoreFixture() {
57   pref_store_->RemoveObserver(this);
58 }
59 
OnPrefValueChanged(const std::string & key)60 void SupervisedUserPrefStoreFixture::OnPrefValueChanged(
61     const std::string& key) {
62   const base::Value* value = nullptr;
63   ASSERT_TRUE(pref_store_->GetValue(key, &value));
64   changed_prefs_.Set(key, std::make_unique<base::Value>(value->Clone()));
65 }
66 
OnInitializationCompleted(bool succeeded)67 void SupervisedUserPrefStoreFixture::OnInitializationCompleted(bool succeeded) {
68   EXPECT_FALSE(initialization_completed_);
69   EXPECT_TRUE(succeeded);
70   EXPECT_TRUE(pref_store_->IsInitializationComplete());
71   initialization_completed_ = true;
72 }
73 
74 }  // namespace
75 
76 class SupervisedUserPrefStoreTest : public ::testing::Test {
77  public:
SupervisedUserPrefStoreTest()78   SupervisedUserPrefStoreTest() {}
79   void SetUp() override;
80   void TearDown() override;
81 
82  protected:
83   SupervisedUserSettingsService service_;
84   scoped_refptr<TestingPrefStore> pref_store_;
85 };
86 
SetUp()87 void SupervisedUserPrefStoreTest::SetUp() {
88   pref_store_ = new TestingPrefStore();
89   service_.Init(pref_store_);
90 }
91 
TearDown()92 void SupervisedUserPrefStoreTest::TearDown() {
93   service_.Shutdown();
94 }
95 
TEST_F(SupervisedUserPrefStoreTest,ConfigureSettings)96 TEST_F(SupervisedUserPrefStoreTest, ConfigureSettings) {
97   SupervisedUserPrefStoreFixture fixture(&service_);
98   EXPECT_FALSE(fixture.initialization_completed());
99 
100   // Prefs should not change yet when the service is ready, but not
101   // activated yet.
102   pref_store_->SetInitializationCompleted();
103   EXPECT_TRUE(fixture.initialization_completed());
104   EXPECT_EQ(0u, fixture.changed_prefs()->size());
105 
106   service_.SetActive(true);
107 
108   // kAllowDeletingBrowserHistory is hardcoded to false for supervised users.
109   bool allow_deleting_browser_history = true;
110   EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(
111       prefs::kAllowDeletingBrowserHistory, &allow_deleting_browser_history));
112   EXPECT_FALSE(allow_deleting_browser_history);
113 
114   // kSupervisedModeManualHosts does not have a hardcoded value.
115   base::DictionaryValue* manual_hosts = nullptr;
116   EXPECT_FALSE(fixture.changed_prefs()->GetDictionary(
117       prefs::kSupervisedUserManualHosts, &manual_hosts));
118 
119   // kForceGoogleSafeSearch defaults to true and kForceYouTubeRestrict defaults
120   // to Moderate for supervised users.
121   bool force_google_safesearch = false;
122   int force_youtube_restrict = safe_search_util::YOUTUBE_RESTRICT_OFF;
123   EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(prefs::kForceGoogleSafeSearch,
124                                                   &force_google_safesearch));
125   EXPECT_TRUE(fixture.changed_prefs()->GetInteger(prefs::kForceYouTubeRestrict,
126                                                   &force_youtube_restrict));
127   EXPECT_TRUE(force_google_safesearch);
128   EXPECT_EQ(force_youtube_restrict,
129             safe_search_util::YOUTUBE_RESTRICT_MODERATE);
130 
131 #if BUILDFLAG(ENABLE_EXTENSIONS)
132   // Permissions requests default to disallowed.
133   bool extensions_may_request_permissions = false;
134   EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(
135       prefs::kSupervisedUserExtensionsMayRequestPermissions,
136       &extensions_may_request_permissions));
137   EXPECT_FALSE(extensions_may_request_permissions);
138 #endif
139 
140   // Activating the service again should not change anything.
141   fixture.changed_prefs()->Clear();
142   service_.SetActive(true);
143   EXPECT_EQ(0u, fixture.changed_prefs()->size());
144 
145   // kSupervisedModeManualHosts can be configured by the custodian.
146   base::Value hosts(base::Value::Type::DICTIONARY);
147   hosts.SetBoolKey("example.com", true);
148   hosts.SetBoolKey("moose.org", false);
149   service_.SetLocalSetting(supervised_users::kContentPackManualBehaviorHosts,
150                            std::make_unique<base::Value>(hosts.Clone()));
151   EXPECT_EQ(1u, fixture.changed_prefs()->size());
152   ASSERT_TRUE(fixture.changed_prefs()->GetDictionary(
153       prefs::kSupervisedUserManualHosts, &manual_hosts));
154   EXPECT_TRUE(*manual_hosts == hosts);
155 
156   // kForceGoogleSafeSearch and kForceYouTubeRestrict can be configured by the
157   // custodian, overriding the hardcoded default.
158   fixture.changed_prefs()->Clear();
159   service_.SetLocalSetting(supervised_users::kForceSafeSearch,
160                            std::make_unique<base::Value>(false));
161   EXPECT_EQ(1u, fixture.changed_prefs()->size());
162   EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(prefs::kForceGoogleSafeSearch,
163                                                   &force_google_safesearch));
164   EXPECT_TRUE(fixture.changed_prefs()->GetInteger(prefs::kForceYouTubeRestrict,
165                                                   &force_youtube_restrict));
166   EXPECT_FALSE(force_google_safesearch);
167   EXPECT_EQ(force_youtube_restrict, safe_search_util::YOUTUBE_RESTRICT_OFF);
168 
169 #if BUILDFLAG(ENABLE_EXTENSIONS)
170   // The custodian can allow sites and apps to request permissions.
171   // Currently tested indirectly by enabling geolocation requests.
172   // TODO(crbug/1024646): Update Kids Management server to set a new bit for
173   // extension permissions and update this test.
174 
175   base::HistogramTester histogram_tester;
176   histogram_tester.ExpectTotalCount(
177       "SupervisedUsers.ExtensionsMayRequestPermissions", 0);
178 
179   fixture.changed_prefs()->Clear();
180   service_.SetLocalSetting(supervised_users::kGeolocationDisabled,
181                            std::make_unique<base::Value>(false));
182   EXPECT_EQ(1u, fixture.changed_prefs()->size());
183   EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(
184       prefs::kSupervisedUserExtensionsMayRequestPermissions,
185       &extensions_may_request_permissions));
186   EXPECT_TRUE(extensions_may_request_permissions);
187 
188   histogram_tester.ExpectUniqueSample(
189       "SupervisedUsers.ExtensionsMayRequestPermissions", /*enabled=*/true, 1);
190   histogram_tester.ExpectTotalCount(
191       "SupervisedUsers.ExtensionsMayRequestPermissions", 1);
192 
193   fixture.changed_prefs()->Clear();
194   service_.SetLocalSetting(supervised_users::kGeolocationDisabled,
195                            std::make_unique<base::Value>(true));
196   EXPECT_EQ(1u, fixture.changed_prefs()->size());
197   EXPECT_TRUE(fixture.changed_prefs()->GetBoolean(
198       prefs::kSupervisedUserExtensionsMayRequestPermissions,
199       &extensions_may_request_permissions));
200   EXPECT_FALSE(extensions_may_request_permissions);
201 
202   histogram_tester.ExpectBucketCount(
203       "SupervisedUsers.ExtensionsMayRequestPermissions", /*enabled=*/false, 1);
204   histogram_tester.ExpectTotalCount(
205       "SupervisedUsers.ExtensionsMayRequestPermissions", 2);
206 
207 #endif
208 }
209 
TEST_F(SupervisedUserPrefStoreTest,ActivateSettingsBeforeInitialization)210 TEST_F(SupervisedUserPrefStoreTest, ActivateSettingsBeforeInitialization) {
211   SupervisedUserPrefStoreFixture fixture(&service_);
212   EXPECT_FALSE(fixture.initialization_completed());
213 
214   service_.SetActive(true);
215   EXPECT_FALSE(fixture.initialization_completed());
216   EXPECT_EQ(0u, fixture.changed_prefs()->size());
217 
218   pref_store_->SetInitializationCompleted();
219   EXPECT_TRUE(fixture.initialization_completed());
220   EXPECT_EQ(0u, fixture.changed_prefs()->size());
221 }
222 
TEST_F(SupervisedUserPrefStoreTest,CreatePrefStoreAfterInitialization)223 TEST_F(SupervisedUserPrefStoreTest, CreatePrefStoreAfterInitialization) {
224   pref_store_->SetInitializationCompleted();
225   service_.SetActive(true);
226 
227   SupervisedUserPrefStoreFixture fixture(&service_);
228   EXPECT_TRUE(fixture.initialization_completed());
229   EXPECT_EQ(0u, fixture.changed_prefs()->size());
230 }
231