session_manager_operation_unittest.cc revision 2385ea399aae016c0806a4f9ef3c9cfe3d2a39df
18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// Copyright (c) 2012 The Chromium Authors. All rights reserved.
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// Use of this source code is governed by a BSD-style license that can be
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd// found in the LICENSE file.
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "chrome/browser/chromeos/settings/session_manager_operation.h"
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "base/basictypes.h"
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "base/bind.h"
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "base/bind_helpers.h"
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "base/memory/ref_counted.h"
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "base/memory/scoped_ptr.h"
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "base/message_loop/message_loop.h"
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "chrome/browser/chromeos/settings/device_settings_test_helper.h"
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "chrome/browser/chromeos/settings/mock_owner_key_util.h"
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "chrome/browser/policy/cloud/cloud_policy_constants.h"
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "chrome/browser/policy/cloud/cloud_policy_validator.h"
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "chrome/browser/policy/cloud/policy_builder.h"
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "content/public/test/test_browser_thread.h"
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "crypto/rsa_private_key.h"
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "testing/gmock/include/gmock/gmock.h"
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "testing/gtest/include/gtest/gtest.h"
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace em = enterprise_management;
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing testing::Mock;
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing testing::_;
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddnamespace chromeos {
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass SessionManagerOperationTest : public testing::Test {
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd public:
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  SessionManagerOperationTest()
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd      : ui_thread_(content::BrowserThread::UI, &message_loop_),
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd        file_thread_(content::BrowserThread::FILE, &message_loop_),
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd        owner_key_util_(new MockOwnerKeyUtil()),
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd        validated_(false) {}
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  virtual void SetUp() OVERRIDE {
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    policy_.payload().mutable_pinned_apps()->add_app_id("fake-app");
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    policy_.Build();
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  }
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  MOCK_METHOD2(OnOperationCompleted,
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd               void(SessionManagerOperation*, DeviceSettingsService::Status));
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  void CheckSuccessfulValidation(
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd      policy::DeviceCloudPolicyValidator* validator) {
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    EXPECT_TRUE(validator->success());
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    EXPECT_TRUE(validator->payload().get());
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    EXPECT_EQ(validator->payload()->SerializeAsString(),
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd              policy_.payload().SerializeAsString());
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    validated_ = true;
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  }
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  void CheckPublicKeyLoaded(SessionManagerOperation* op) {
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    ASSERT_TRUE(op->owner_key().get());
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    ASSERT_TRUE(op->owner_key()->public_key());
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    std::vector<uint8> public_key;
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    ASSERT_TRUE(policy_.GetSigningKey()->ExportPublicKey(&public_key));
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    EXPECT_EQ(public_key, *op->owner_key()->public_key());
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  }
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  void CheckPrivateKeyLoaded(SessionManagerOperation* op) {
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    ASSERT_TRUE(op->owner_key().get());
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    ASSERT_TRUE(op->owner_key()->private_key());
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    std::vector<uint8> expected_key;
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    ASSERT_TRUE(policy_.GetSigningKey()->ExportPrivateKey(&expected_key));
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    std::vector<uint8> actual_key;
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    ASSERT_TRUE(op->owner_key()->private_key()->ExportPrivateKey(&actual_key));
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd    EXPECT_EQ(expected_key, actual_key);
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  }
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd protected:
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  base::MessageLoop message_loop_;
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  content::TestBrowserThread ui_thread_;
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  content::TestBrowserThread file_thread_;
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  policy::DevicePolicyBuilder policy_;
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  DeviceSettingsTestHelper device_settings_test_helper_;
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  scoped_refptr<MockOwnerKeyUtil> owner_key_util_;
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  bool validated_;
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd private:
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  DISALLOW_COPY_AND_ASSIGN(SessionManagerOperationTest);
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddTEST_F(SessionManagerOperationTest, LoadNoPolicyNoKey) {
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  LoadSettingsOperation op(
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd      base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                 base::Unretained(this)));
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  EXPECT_CALL(*this,
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd              OnOperationCompleted(
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                  &op, DeviceSettingsService::STORE_KEY_UNAVAILABLE));
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  device_settings_test_helper_.Flush();
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  Mock::VerifyAndClearExpectations(this);
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  EXPECT_FALSE(op.policy_data().get());
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  EXPECT_FALSE(op.device_settings().get());
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  ASSERT_TRUE(op.owner_key().get());
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  EXPECT_FALSE(op.owner_key()->public_key());
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  EXPECT_FALSE(op.owner_key()->private_key());
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddTEST_F(SessionManagerOperationTest, LoadOwnerKey) {
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  owner_key_util_->SetPublicKeyFromPrivateKey(*policy_.GetSigningKey());
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  LoadSettingsOperation op(
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd      base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                 base::Unretained(this)));
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  EXPECT_CALL(*this,
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd              OnOperationCompleted(
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                  &op, DeviceSettingsService::STORE_NO_POLICY));
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  device_settings_test_helper_.Flush();
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  Mock::VerifyAndClearExpectations(this);
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd  CheckPublicKeyLoaded(&op);
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
124
125TEST_F(SessionManagerOperationTest, LoadPolicy) {
126  owner_key_util_->SetPublicKeyFromPrivateKey(*policy_.GetSigningKey());
127  device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
128  LoadSettingsOperation op(
129      base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
130                 base::Unretained(this)));
131
132  EXPECT_CALL(*this,
133              OnOperationCompleted(
134                  &op, DeviceSettingsService::STORE_SUCCESS));
135  op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
136  device_settings_test_helper_.Flush();
137  Mock::VerifyAndClearExpectations(this);
138
139  ASSERT_TRUE(op.policy_data().get());
140  EXPECT_EQ(policy_.policy_data().SerializeAsString(),
141            op.policy_data()->SerializeAsString());
142  ASSERT_TRUE(op.device_settings().get());
143  EXPECT_EQ(policy_.payload().SerializeAsString(),
144            op.device_settings()->SerializeAsString());
145}
146
147TEST_F(SessionManagerOperationTest, LoadPrivateOwnerKey) {
148  owner_key_util_->SetPrivateKey(policy_.GetSigningKey());
149  LoadSettingsOperation op(
150      base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
151                 base::Unretained(this)));
152
153  EXPECT_CALL(*this,
154              OnOperationCompleted(
155                  &op, DeviceSettingsService::STORE_NO_POLICY));
156  op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
157  device_settings_test_helper_.Flush();
158  Mock::VerifyAndClearExpectations(this);
159
160  CheckPublicKeyLoaded(&op);
161  CheckPrivateKeyLoaded(&op);
162}
163
164TEST_F(SessionManagerOperationTest, RestartLoad) {
165  owner_key_util_->SetPrivateKey(policy_.GetSigningKey());
166  device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
167  LoadSettingsOperation op(
168      base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
169                 base::Unretained(this)));
170
171  EXPECT_CALL(*this, OnOperationCompleted(&op, _)).Times(0);
172  op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
173  device_settings_test_helper_.FlushLoops();
174  device_settings_test_helper_.FlushRetrieve();
175  EXPECT_TRUE(op.owner_key().get());
176  EXPECT_TRUE(op.owner_key()->public_key());
177  Mock::VerifyAndClearExpectations(this);
178
179  // Now install a different key and policy and restart the operation.
180  policy_.SetSigningKey(*policy::PolicyBuilder::CreateTestOtherSigningKey());
181  policy_.payload().mutable_metrics_enabled()->set_metrics_enabled(true);
182  policy_.Build();
183  device_settings_test_helper_.set_policy_blob(policy_.GetBlob());
184  owner_key_util_->SetPrivateKey(policy_.GetSigningKey());
185
186  EXPECT_CALL(*this,
187              OnOperationCompleted(
188                  &op, DeviceSettingsService::STORE_SUCCESS));
189  op.RestartLoad(true);
190  device_settings_test_helper_.Flush();
191  Mock::VerifyAndClearExpectations(this);
192
193  // Check that the new keys have been loaded.
194  CheckPublicKeyLoaded(&op);
195  CheckPrivateKeyLoaded(&op);
196
197  // Verify the new policy.
198  ASSERT_TRUE(op.policy_data().get());
199  EXPECT_EQ(policy_.policy_data().SerializeAsString(),
200            op.policy_data()->SerializeAsString());
201  ASSERT_TRUE(op.device_settings().get());
202  EXPECT_EQ(policy_.payload().SerializeAsString(),
203            op.device_settings()->SerializeAsString());
204}
205
206TEST_F(SessionManagerOperationTest, StoreSettings) {
207  owner_key_util_->SetPublicKeyFromPrivateKey(*policy_.GetSigningKey());
208  StoreSettingsOperation op(
209      base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
210                 base::Unretained(this)),
211      policy_.GetCopy());
212
213  EXPECT_CALL(*this,
214              OnOperationCompleted(
215                  &op, DeviceSettingsService::STORE_SUCCESS));
216  op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
217  device_settings_test_helper_.Flush();
218  Mock::VerifyAndClearExpectations(this);
219
220  EXPECT_EQ(device_settings_test_helper_.policy_blob(),
221            policy_.GetBlob());
222  ASSERT_TRUE(op.policy_data().get());
223  EXPECT_EQ(policy_.policy_data().SerializeAsString(),
224            op.policy_data()->SerializeAsString());
225  ASSERT_TRUE(op.device_settings().get());
226  EXPECT_EQ(policy_.payload().SerializeAsString(),
227            op.device_settings()->SerializeAsString());
228}
229
230TEST_F(SessionManagerOperationTest, SignAndStoreSettings) {
231  base::Time before(base::Time::NowFromSystemTime());
232  owner_key_util_->SetPrivateKey(policy_.GetSigningKey());
233  SignAndStoreSettingsOperation op(
234      base::Bind(&SessionManagerOperationTest::OnOperationCompleted,
235                 base::Unretained(this)),
236      scoped_ptr<em::ChromeDeviceSettingsProto>(
237          new em::ChromeDeviceSettingsProto(policy_.payload())),
238      policy_.policy_data().username());
239
240  EXPECT_CALL(*this,
241              OnOperationCompleted(
242                  &op, DeviceSettingsService::STORE_SUCCESS));
243  op.Start(&device_settings_test_helper_, owner_key_util_, NULL);
244  device_settings_test_helper_.Flush();
245  Mock::VerifyAndClearExpectations(this);
246  base::Time after(base::Time::NowFromSystemTime());
247
248  // The blob should validate.
249  scoped_ptr<em::PolicyFetchResponse> policy_response(
250      new em::PolicyFetchResponse());
251  ASSERT_TRUE(
252      policy_response->ParseFromString(
253          device_settings_test_helper_.policy_blob()));
254  policy::DeviceCloudPolicyValidator* validator =
255      policy::DeviceCloudPolicyValidator::Create(policy_response.Pass());
256  validator->ValidateUsername(policy_.policy_data().username());
257  validator->ValidateTimestamp(
258      before,
259      after,
260      policy::CloudPolicyValidatorBase::TIMESTAMP_REQUIRED);
261  validator->ValidatePolicyType(policy::dm_protocol::kChromeDevicePolicyType);
262  validator->ValidatePayload();
263  std::vector<uint8> public_key;
264  policy_.GetSigningKey()->ExportPublicKey(&public_key);
265  validator->ValidateSignature(public_key, false);
266  validator->StartValidation(
267      base::Bind(&SessionManagerOperationTest::CheckSuccessfulValidation,
268                 base::Unretained(this)));
269
270  message_loop_.RunUntilIdle();
271  EXPECT_TRUE(validated_);
272
273  // Check that the loaded policy_data contains the expected values.
274  EXPECT_EQ(policy::dm_protocol::kChromeDevicePolicyType,
275            op.policy_data()->policy_type());
276  EXPECT_LE((before - base::Time::UnixEpoch()).InMilliseconds(),
277            op.policy_data()->timestamp());
278  EXPECT_GE((after - base::Time::UnixEpoch()).InMilliseconds(),
279            op.policy_data()->timestamp());
280  EXPECT_FALSE(op.policy_data()->has_request_token());
281  EXPECT_EQ(policy_.policy_data().username(), op.policy_data()->username());
282
283  // Loaded device settings should match what the operation received.
284  ASSERT_TRUE(op.device_settings().get());
285  EXPECT_EQ(policy_.payload().SerializeAsString(),
286            op.device_settings()->SerializeAsString());
287}
288
289}  // namespace chromeos
290