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