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