• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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/chromeos/settings/device_settings_provider.h"
6 
7 #include <string>
8 
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/files/file_util.h"
12 #include "base/path_service.h"
13 #include "base/test/scoped_path_override.h"
14 #include "base/values.h"
15 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
16 #include "chrome/browser/chromeos/policy/device_local_account.h"
17 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
18 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/test/base/scoped_testing_local_state.h"
21 #include "chrome/test/base/testing_browser_process.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "chromeos/settings/cros_settings_names.h"
24 #include "components/user_manager/user.h"
25 #include "policy/proto/device_management_backend.pb.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 
29 namespace em = enterprise_management;
30 
31 namespace chromeos {
32 
33 using ::testing::AnyNumber;
34 using ::testing::Mock;
35 using ::testing::_;
36 
37 class DeviceSettingsProviderTest : public DeviceSettingsTestBase {
38  public:
39   MOCK_METHOD1(SettingChanged, void(const std::string&));
40   MOCK_METHOD0(GetTrustedCallback, void(void));
41 
42  protected:
DeviceSettingsProviderTest()43   DeviceSettingsProviderTest()
44       : local_state_(TestingBrowserProcess::GetGlobal()),
45         user_data_dir_override_(chrome::DIR_USER_DATA) {}
46 
SetUp()47   virtual void SetUp() OVERRIDE {
48     DeviceSettingsTestBase::SetUp();
49 
50     EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
51     provider_.reset(
52         new DeviceSettingsProvider(
53             base::Bind(&DeviceSettingsProviderTest::SettingChanged,
54                        base::Unretained(this)),
55             &device_settings_service_));
56     Mock::VerifyAndClearExpectations(this);
57   }
58 
TearDown()59   virtual void TearDown() OVERRIDE {
60     DeviceSettingsTestBase::TearDown();
61   }
62 
63   ScopedTestingLocalState local_state_;
64 
65   scoped_ptr<DeviceSettingsProvider> provider_;
66 
67   base::ScopedPathOverride user_data_dir_override_;
68 
69  private:
70   DISALLOW_COPY_AND_ASSIGN(DeviceSettingsProviderTest);
71 };
72 
TEST_F(DeviceSettingsProviderTest,InitializationTest)73 TEST_F(DeviceSettingsProviderTest, InitializationTest) {
74   // Have the service load a settings blob.
75   EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
76   ReloadDeviceSettings();
77   Mock::VerifyAndClearExpectations(this);
78 
79   // Verify that the policy blob has been correctly parsed and trusted.
80   // The trusted flag should be set before the call to PrepareTrustedValues.
81   EXPECT_EQ(CrosSettingsProvider::TRUSTED,
82             provider_->PrepareTrustedValues(base::Closure()));
83   const base::Value* value = provider_->Get(kStatsReportingPref);
84   ASSERT_TRUE(value);
85   bool bool_value;
86   EXPECT_TRUE(value->GetAsBoolean(&bool_value));
87   EXPECT_FALSE(bool_value);
88 }
89 
TEST_F(DeviceSettingsProviderTest,InitializationTestUnowned)90 TEST_F(DeviceSettingsProviderTest, InitializationTestUnowned) {
91   // Have the service check the key.
92   owner_key_util_->Clear();
93   ReloadDeviceSettings();
94 
95   // The trusted flag should be set before the call to PrepareTrustedValues.
96   EXPECT_EQ(CrosSettingsProvider::TRUSTED,
97             provider_->PrepareTrustedValues(base::Closure()));
98   const base::Value* value = provider_->Get(kReleaseChannel);
99   ASSERT_TRUE(value);
100   std::string string_value;
101   EXPECT_TRUE(value->GetAsString(&string_value));
102   EXPECT_TRUE(string_value.empty());
103 
104   // Sets should succeed though and be readable from the cache.
105   EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
106   EXPECT_CALL(*this, SettingChanged(kReleaseChannel)).Times(1);
107   base::StringValue new_value("stable-channel");
108   provider_->Set(kReleaseChannel, new_value);
109   Mock::VerifyAndClearExpectations(this);
110 
111   // This shouldn't trigger a write.
112   device_settings_test_helper_.set_policy_blob(std::string());
113   FlushDeviceSettings();
114   EXPECT_EQ(std::string(), device_settings_test_helper_.policy_blob());
115 
116   // Verify the change has been applied.
117   const base::Value* saved_value = provider_->Get(kReleaseChannel);
118   ASSERT_TRUE(saved_value);
119   EXPECT_TRUE(saved_value->GetAsString(&string_value));
120   ASSERT_EQ("stable-channel", string_value);
121 }
122 
TEST_F(DeviceSettingsProviderTest,SetPrefFailed)123 TEST_F(DeviceSettingsProviderTest, SetPrefFailed) {
124   // If we are not the owner no sets should work.
125   base::FundamentalValue value(true);
126   EXPECT_CALL(*this, SettingChanged(kStatsReportingPref)).Times(1);
127   provider_->Set(kStatsReportingPref, value);
128   Mock::VerifyAndClearExpectations(this);
129 
130   // This shouldn't trigger a write.
131   device_settings_test_helper_.set_policy_blob(std::string());
132   FlushDeviceSettings();
133   EXPECT_EQ(std::string(), device_settings_test_helper_.policy_blob());
134 
135   // Verify the change has not been applied.
136   const base::Value* saved_value = provider_->Get(kStatsReportingPref);
137   ASSERT_TRUE(saved_value);
138   bool bool_value;
139   EXPECT_TRUE(saved_value->GetAsBoolean(&bool_value));
140   EXPECT_FALSE(bool_value);
141 }
142 
TEST_F(DeviceSettingsProviderTest,SetPrefSucceed)143 TEST_F(DeviceSettingsProviderTest, SetPrefSucceed) {
144   owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
145   InitOwner(device_policy_.policy_data().username(), true);
146   FlushDeviceSettings();
147 
148   base::FundamentalValue value(true);
149   EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
150   EXPECT_CALL(*this, SettingChanged(kStatsReportingPref)).Times(1);
151   provider_->Set(kStatsReportingPref, value);
152   Mock::VerifyAndClearExpectations(this);
153 
154   // Process the store.
155   device_settings_test_helper_.set_policy_blob(std::string());
156   FlushDeviceSettings();
157 
158   // Verify that the device policy has been adjusted.
159   ASSERT_TRUE(device_settings_service_.device_settings());
160   EXPECT_TRUE(device_settings_service_.device_settings()->
161                   metrics_enabled().metrics_enabled());
162 
163   // Verify the change has been applied.
164   const base::Value* saved_value = provider_->Get(kStatsReportingPref);
165   ASSERT_TRUE(saved_value);
166   bool bool_value;
167   EXPECT_TRUE(saved_value->GetAsBoolean(&bool_value));
168   EXPECT_TRUE(bool_value);
169 }
170 
TEST_F(DeviceSettingsProviderTest,SetPrefTwice)171 TEST_F(DeviceSettingsProviderTest, SetPrefTwice) {
172   owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey());
173   InitOwner(device_policy_.policy_data().username(), true);
174   FlushDeviceSettings();
175 
176   EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
177 
178   base::StringValue value1("beta");
179   provider_->Set(kReleaseChannel, value1);
180   base::StringValue value2("dev");
181   provider_->Set(kReleaseChannel, value2);
182 
183   // Let the changes propagate through the system.
184   device_settings_test_helper_.set_policy_blob(std::string());
185   FlushDeviceSettings();
186 
187   // Verify the second change has been applied.
188   const base::Value* saved_value = provider_->Get(kReleaseChannel);
189   EXPECT_TRUE(value2.Equals(saved_value));
190 
191   Mock::VerifyAndClearExpectations(this);
192 }
193 
TEST_F(DeviceSettingsProviderTest,PolicyRetrievalFailedBadSignature)194 TEST_F(DeviceSettingsProviderTest, PolicyRetrievalFailedBadSignature) {
195   owner_key_util_->SetPublicKeyFromPrivateKey(*device_policy_.GetSigningKey());
196   device_policy_.policy().set_policy_data_signature("bad signature");
197   device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
198   ReloadDeviceSettings();
199 
200   // Verify that the cached settings blob is not "trusted".
201   EXPECT_EQ(DeviceSettingsService::STORE_VALIDATION_ERROR,
202             device_settings_service_.status());
203   EXPECT_EQ(CrosSettingsProvider::PERMANENTLY_UNTRUSTED,
204             provider_->PrepareTrustedValues(base::Closure()));
205 }
206 
TEST_F(DeviceSettingsProviderTest,PolicyRetrievalNoPolicy)207 TEST_F(DeviceSettingsProviderTest, PolicyRetrievalNoPolicy) {
208   owner_key_util_->SetPublicKeyFromPrivateKey(*device_policy_.GetSigningKey());
209   device_settings_test_helper_.set_policy_blob(std::string());
210   ReloadDeviceSettings();
211 
212   // Verify that the cached settings blob is not "trusted".
213   EXPECT_EQ(DeviceSettingsService::STORE_NO_POLICY,
214             device_settings_service_.status());
215   EXPECT_EQ(CrosSettingsProvider::PERMANENTLY_UNTRUSTED,
216             provider_->PrepareTrustedValues(base::Closure()));
217 }
218 
TEST_F(DeviceSettingsProviderTest,PolicyFailedPermanentlyNotification)219 TEST_F(DeviceSettingsProviderTest, PolicyFailedPermanentlyNotification) {
220   device_settings_test_helper_.set_policy_blob(std::string());
221 
222   EXPECT_CALL(*this, GetTrustedCallback());
223   EXPECT_EQ(CrosSettingsProvider::TEMPORARILY_UNTRUSTED,
224             provider_->PrepareTrustedValues(
225                 base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback,
226                            base::Unretained(this))));
227 
228   ReloadDeviceSettings();
229   Mock::VerifyAndClearExpectations(this);
230 
231   EXPECT_EQ(CrosSettingsProvider::PERMANENTLY_UNTRUSTED,
232             provider_->PrepareTrustedValues(base::Closure()));
233 }
234 
TEST_F(DeviceSettingsProviderTest,PolicyLoadNotification)235 TEST_F(DeviceSettingsProviderTest, PolicyLoadNotification) {
236   EXPECT_CALL(*this, GetTrustedCallback());
237 
238   EXPECT_EQ(CrosSettingsProvider::TEMPORARILY_UNTRUSTED,
239             provider_->PrepareTrustedValues(
240                 base::Bind(&DeviceSettingsProviderTest::GetTrustedCallback,
241                            base::Unretained(this))));
242 
243   ReloadDeviceSettings();
244   Mock::VerifyAndClearExpectations(this);
245 }
246 
TEST_F(DeviceSettingsProviderTest,StatsReportingMigration)247 TEST_F(DeviceSettingsProviderTest, StatsReportingMigration) {
248   // Create the legacy consent file.
249   base::FilePath consent_file;
250   ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &consent_file));
251   consent_file = consent_file.AppendASCII("Consent To Send Stats");
252   ASSERT_EQ(1, base::WriteFile(consent_file, "0", 1));
253 
254   // This should trigger migration because the metrics policy isn't in the blob.
255   device_settings_test_helper_.set_policy_blob(std::string());
256   FlushDeviceSettings();
257   EXPECT_EQ(std::string(), device_settings_test_helper_.policy_blob());
258 
259   // Verify that migration has kicked in.
260   const base::Value* saved_value = provider_->Get(kStatsReportingPref);
261   ASSERT_TRUE(saved_value);
262   bool bool_value;
263   EXPECT_TRUE(saved_value->GetAsBoolean(&bool_value));
264   EXPECT_FALSE(bool_value);
265 }
266 
TEST_F(DeviceSettingsProviderTest,LegacyDeviceLocalAccounts)267 TEST_F(DeviceSettingsProviderTest, LegacyDeviceLocalAccounts) {
268   EXPECT_CALL(*this, SettingChanged(_)).Times(AnyNumber());
269   em::DeviceLocalAccountInfoProto* account =
270       device_policy_.payload().mutable_device_local_accounts()->add_account();
271   account->set_deprecated_public_session_id(
272       policy::PolicyBuilder::kFakeUsername);
273   device_policy_.Build();
274   device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob());
275   ReloadDeviceSettings();
276   Mock::VerifyAndClearExpectations(this);
277 
278   // On load, the deprecated spec should have been converted to the new format.
279   base::ListValue expected_accounts;
280   scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
281   entry_dict->SetString(kAccountsPrefDeviceLocalAccountsKeyId,
282                         policy::PolicyBuilder::kFakeUsername);
283   entry_dict->SetInteger(kAccountsPrefDeviceLocalAccountsKeyType,
284                          policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION);
285   expected_accounts.Append(entry_dict.release());
286   const base::Value* actual_accounts =
287       provider_->Get(kAccountsPrefDeviceLocalAccounts);
288   EXPECT_TRUE(base::Value::Equals(&expected_accounts, actual_accounts));
289 }
290 
291 } // namespace chromeos
292