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/policy/user_cloud_policy_store_chromeos.h"
6
7#include <vector>
8
9#include "base/basictypes.h"
10#include "base/bind.h"
11#include "base/files/file_util.h"
12#include "base/files/scoped_temp_dir.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/message_loop/message_loop.h"
15#include "base/threading/sequenced_worker_pool.h"
16#include "chromeos/dbus/mock_cryptohome_client.h"
17#include "chromeos/dbus/mock_session_manager_client.h"
18#include "components/policy/core/common/cloud/cloud_policy_constants.h"
19#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
20#include "components/policy/core/common/cloud/policy_builder.h"
21#include "policy/policy_constants.h"
22#include "policy/proto/cloud_policy.pb.h"
23#include "policy/proto/device_management_local.pb.h"
24#include "testing/gmock/include/gmock/gmock.h"
25#include "testing/gtest/include/gtest/gtest.h"
26
27namespace em = enterprise_management;
28
29using testing::AllOf;
30using testing::AnyNumber;
31using testing::Eq;
32using testing::Mock;
33using testing::Property;
34using testing::Return;
35using testing::SaveArg;
36using testing::_;
37
38namespace policy {
39
40namespace {
41
42const char kLegacyDeviceId[] = "legacy-device-id";
43const char kLegacyToken[] = "legacy-token";
44const char kSanitizedUsername[] =
45    "0123456789ABCDEF0123456789ABCDEF012345678@example.com";
46const char kDefaultHomepage[] = "http://chromium.org";
47
48ACTION_P2(SendSanitizedUsername, call_status, sanitized_username) {
49  base::MessageLoop::current()->PostTask(
50      FROM_HERE, base::Bind(arg1, call_status, sanitized_username));
51}
52
53class UserCloudPolicyStoreChromeOSTest : public testing::Test {
54 protected:
55  UserCloudPolicyStoreChromeOSTest() {}
56
57  virtual void SetUp() OVERRIDE {
58    EXPECT_CALL(cryptohome_client_,
59                GetSanitizedUsername(PolicyBuilder::kFakeUsername, _))
60        .Times(AnyNumber())
61        .WillRepeatedly(
62            SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_SUCCESS,
63                                  kSanitizedUsername));
64
65    ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
66    store_.reset(new UserCloudPolicyStoreChromeOS(&cryptohome_client_,
67                                                  &session_manager_client_,
68                                                  loop_.message_loop_proxy(),
69                                                  PolicyBuilder::kFakeUsername,
70                                                  user_policy_dir(),
71                                                  token_file(),
72                                                  policy_file()));
73    store_->AddObserver(&observer_);
74
75    // Install the initial public key, so that by default the validation of
76    // the stored/loaded policy blob succeeds.
77    std::vector<uint8> public_key;
78    ASSERT_TRUE(policy_.GetSigningKey()->ExportPublicKey(&public_key));
79    StoreUserPolicyKey(public_key);
80
81    policy_.payload().mutable_homepagelocation()->set_value(kDefaultHomepage);
82    policy_.Build();
83  }
84
85  virtual void TearDown() OVERRIDE {
86    store_->RemoveObserver(&observer_);
87    store_.reset();
88    RunUntilIdle();
89  }
90
91  // Install an expectation on |observer_| for an error code.
92  void ExpectError(CloudPolicyStore::Status error) {
93    EXPECT_CALL(observer_,
94                OnStoreError(AllOf(Eq(store_.get()),
95                                   Property(&CloudPolicyStore::status,
96                                            Eq(error)))));
97  }
98
99  // Triggers a store_->Load() operation, handles the expected call to
100  // |session_manager_client_| and sends |response|.
101  void PerformPolicyLoad(const std::string& response) {
102    // Issue a load command.
103    chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback;
104    EXPECT_CALL(session_manager_client_,
105                RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _))
106        .WillOnce(SaveArg<1>(&retrieve_callback));
107    store_->Load();
108    RunUntilIdle();
109    Mock::VerifyAndClearExpectations(&session_manager_client_);
110    ASSERT_FALSE(retrieve_callback.is_null());
111
112    // Run the callback.
113    retrieve_callback.Run(response);
114    RunUntilIdle();
115  }
116
117  // Verifies that store_->policy_map() has the HomepageLocation entry with
118  // the |expected_value|.
119  void VerifyPolicyMap(const char* expected_value) {
120    EXPECT_EQ(1U, store_->policy_map().size());
121    const PolicyMap::Entry* entry =
122        store_->policy_map().Get(key::kHomepageLocation);
123    ASSERT_TRUE(entry);
124    EXPECT_TRUE(base::StringValue(expected_value).Equals(entry->value));
125  }
126
127  void StoreUserPolicyKey(const std::vector<uint8>& public_key) {
128    ASSERT_TRUE(base::CreateDirectory(user_policy_key_file().DirName()));
129    ASSERT_TRUE(
130        base::WriteFile(user_policy_key_file(),
131                        reinterpret_cast<const char*>(public_key.data()),
132                        public_key.size()));
133  }
134
135  // Stores the current |policy_| and verifies that it is published.
136  // If |new_public_key| is set then it will be persisted after storing but
137  // before loading the policy, so that the signature validation can succeed.
138  // If |previous_value| is set then a previously existing policy with that
139  // value will be expected; otherwise no previous policy is expected.
140  // If |new_value| is set then a new policy with that value is expected after
141  // storing the |policy_| blob.
142  void PerformStorePolicy(const std::vector<uint8>* new_public_key,
143                          const char* previous_value,
144                          const char* new_value) {
145    chromeos::SessionManagerClient::StorePolicyCallback store_callback;
146    EXPECT_CALL(session_manager_client_,
147                StorePolicyForUser(PolicyBuilder::kFakeUsername,
148                                   policy_.GetBlob(), _))
149        .WillOnce(SaveArg<2>(&store_callback));
150    store_->Store(policy_.policy());
151    RunUntilIdle();
152    Mock::VerifyAndClearExpectations(&session_manager_client_);
153    ASSERT_FALSE(store_callback.is_null());
154
155    // The new policy shouldn't be present yet.
156    PolicyMap previous_policy;
157    EXPECT_EQ(previous_value != NULL, store_->policy() != NULL);
158    if (previous_value) {
159      previous_policy.Set(key::kHomepageLocation,
160                          POLICY_LEVEL_MANDATORY,
161                          POLICY_SCOPE_USER,
162                          new base::StringValue(previous_value), NULL);
163    }
164    EXPECT_TRUE(previous_policy.Equals(store_->policy_map()));
165    EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
166
167    // Store the new public key so that the validation after the retrieve
168    // operation completes can verify the signature.
169    if (new_public_key)
170      StoreUserPolicyKey(*new_public_key);
171
172    // Let the store operation complete.
173    chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback;
174    EXPECT_CALL(session_manager_client_,
175                RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _))
176        .WillOnce(SaveArg<1>(&retrieve_callback));
177    store_callback.Run(true);
178    RunUntilIdle();
179    EXPECT_TRUE(previous_policy.Equals(store_->policy_map()));
180    EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
181    Mock::VerifyAndClearExpectations(&session_manager_client_);
182    ASSERT_FALSE(retrieve_callback.is_null());
183
184    // Finish the retrieve callback.
185    EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
186    retrieve_callback.Run(policy_.GetBlob());
187    RunUntilIdle();
188    ASSERT_TRUE(store_->policy());
189    EXPECT_EQ(policy_.policy_data().SerializeAsString(),
190              store_->policy()->SerializeAsString());
191    VerifyPolicyMap(new_value);
192    EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
193  }
194
195  void VerifyStoreHasValidationError() {
196    EXPECT_FALSE(store_->policy());
197    EXPECT_TRUE(store_->policy_map().empty());
198    EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
199  }
200
201  void RunUntilIdle() {
202    loop_.RunUntilIdle();
203    loop_.RunUntilIdle();
204  }
205
206  base::FilePath user_policy_dir() {
207    return tmp_dir_.path().AppendASCII("var_run_user_policy");
208  }
209
210  base::FilePath user_policy_key_file() {
211    return user_policy_dir().AppendASCII(kSanitizedUsername)
212                            .AppendASCII("policy.pub");
213  }
214
215  base::FilePath token_file() {
216    return tmp_dir_.path().AppendASCII("token");
217  }
218
219  base::FilePath policy_file() {
220    return tmp_dir_.path().AppendASCII("policy");
221  }
222
223  base::MessageLoopForUI loop_;
224  chromeos::MockCryptohomeClient cryptohome_client_;
225  chromeos::MockSessionManagerClient session_manager_client_;
226  UserPolicyBuilder policy_;
227  MockCloudPolicyStoreObserver observer_;
228  scoped_ptr<UserCloudPolicyStoreChromeOS> store_;
229
230 private:
231  base::ScopedTempDir tmp_dir_;
232
233  DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreChromeOSTest);
234};
235
236TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStore) {
237  // Start without any public key to trigger the initial key checks.
238  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
239  // Make the policy blob contain a new public key.
240  policy_.SetDefaultNewSigningKey();
241  policy_.Build();
242  std::vector<uint8> new_public_key;
243  ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
244  ASSERT_NO_FATAL_FAILURE(
245      PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage));
246}
247
248TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStoreValidationFail) {
249  // Start without any public key to trigger the initial key checks.
250  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
251  // Make the policy blob contain a new public key.
252  policy_.SetDefaultSigningKey();
253  policy_.Build();
254  *policy_.policy().mutable_new_public_key_verification_signature() = "garbage";
255
256  EXPECT_CALL(session_manager_client_,
257              StorePolicyForUser(
258                  PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0);
259  store_->Store(policy_.policy());
260  RunUntilIdle();
261  Mock::VerifyAndClearExpectations(&session_manager_client_);
262}
263
264TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStoreMissingSignatureFailure) {
265  // Start without any public key to trigger the initial key checks.
266  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
267  // Make the policy blob contain a new public key.
268  policy_.SetDefaultSigningKey();
269  policy_.Build();
270  policy_.policy().clear_new_public_key_verification_signature();
271
272  EXPECT_CALL(session_manager_client_,
273              StorePolicyForUser(
274                  PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0);
275  store_->Store(policy_.policy());
276  RunUntilIdle();
277  Mock::VerifyAndClearExpectations(&session_manager_client_);
278}
279
280TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithExistingKey) {
281  ASSERT_NO_FATAL_FAILURE(
282      PerformStorePolicy(NULL, NULL, kDefaultHomepage));
283}
284
285TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithRotation) {
286  // Make the policy blob contain a new public key.
287  policy_.SetDefaultNewSigningKey();
288  policy_.Build();
289  std::vector<uint8> new_public_key;
290  ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
291  ASSERT_NO_FATAL_FAILURE(
292      PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage));
293}
294
295TEST_F(UserCloudPolicyStoreChromeOSTest,
296       StoreWithRotationMissingSignatureError) {
297  // Make the policy blob contain a new public key.
298  policy_.SetDefaultNewSigningKey();
299  policy_.Build();
300  policy_.policy().clear_new_public_key_verification_signature();
301
302  EXPECT_CALL(session_manager_client_,
303              StorePolicyForUser(
304                  PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0);
305  store_->Store(policy_.policy());
306  RunUntilIdle();
307  Mock::VerifyAndClearExpectations(&session_manager_client_);
308}
309
310TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithRotationValidationError) {
311  // Make the policy blob contain a new public key.
312  policy_.SetDefaultNewSigningKey();
313  policy_.Build();
314  *policy_.policy().mutable_new_public_key_verification_signature() = "garbage";
315
316  EXPECT_CALL(session_manager_client_,
317              StorePolicyForUser(
318                  PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0);
319  store_->Store(policy_.policy());
320  RunUntilIdle();
321  Mock::VerifyAndClearExpectations(&session_manager_client_);
322}
323
324TEST_F(UserCloudPolicyStoreChromeOSTest, StoreFail) {
325  // Store policy.
326  chromeos::SessionManagerClient::StorePolicyCallback store_callback;
327  EXPECT_CALL(session_manager_client_,
328              StorePolicyForUser(PolicyBuilder::kFakeUsername,
329                                 policy_.GetBlob(), _))
330      .WillOnce(SaveArg<2>(&store_callback));
331  store_->Store(policy_.policy());
332  RunUntilIdle();
333  Mock::VerifyAndClearExpectations(&session_manager_client_);
334  ASSERT_FALSE(store_callback.is_null());
335
336  // Let the store operation complete.
337  ExpectError(CloudPolicyStore::STATUS_STORE_ERROR);
338  store_callback.Run(false);
339  RunUntilIdle();
340  EXPECT_FALSE(store_->policy());
341  EXPECT_TRUE(store_->policy_map().empty());
342  EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR, store_->status());
343}
344
345TEST_F(UserCloudPolicyStoreChromeOSTest, StoreValidationError) {
346  policy_.policy_data().clear_policy_type();
347  policy_.Build();
348
349  // Store policy.
350  chromeos::SessionManagerClient::StorePolicyCallback store_callback;
351  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
352  EXPECT_CALL(session_manager_client_,
353              StorePolicyForUser(PolicyBuilder::kFakeUsername,
354                                 policy_.GetBlob(), _))
355      .Times(0);
356  store_->Store(policy_.policy());
357  RunUntilIdle();
358  Mock::VerifyAndClearExpectations(&session_manager_client_);
359}
360
361TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithoutPolicyKey) {
362  // Make the dbus call to cryptohome fail.
363  Mock::VerifyAndClearExpectations(&cryptohome_client_);
364  EXPECT_CALL(cryptohome_client_,
365              GetSanitizedUsername(PolicyBuilder::kFakeUsername, _))
366      .Times(AnyNumber())
367      .WillRepeatedly(SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_FAILURE,
368                                            std::string()));
369
370  // Store policy.
371  chromeos::SessionManagerClient::StorePolicyCallback store_callback;
372  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
373  EXPECT_CALL(session_manager_client_,
374              StorePolicyForUser(PolicyBuilder::kFakeUsername,
375                                 policy_.GetBlob(), _))
376      .Times(0);
377  store_->Store(policy_.policy());
378  RunUntilIdle();
379  Mock::VerifyAndClearExpectations(&session_manager_client_);
380}
381
382TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithInvalidSignature) {
383  // Break the signature.
384  policy_.policy().mutable_policy_data_signature()->append("garbage");
385
386  // Store policy.
387  chromeos::SessionManagerClient::StorePolicyCallback store_callback;
388  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
389  EXPECT_CALL(session_manager_client_,
390              StorePolicyForUser(PolicyBuilder::kFakeUsername,
391                                 policy_.GetBlob(), _))
392      .Times(0);
393  store_->Store(policy_.policy());
394  RunUntilIdle();
395  Mock::VerifyAndClearExpectations(&session_manager_client_);
396}
397
398TEST_F(UserCloudPolicyStoreChromeOSTest, Load) {
399  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
400  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
401  Mock::VerifyAndClearExpectations(&observer_);
402
403  // Verify that the policy has been loaded.
404  ASSERT_TRUE(store_->policy());
405  EXPECT_EQ(policy_.policy_data().SerializeAsString(),
406            store_->policy()->SerializeAsString());
407  VerifyPolicyMap(kDefaultHomepage);
408  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
409}
410
411TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoPolicy) {
412  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
413  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
414  Mock::VerifyAndClearExpectations(&observer_);
415
416  // Verify no policy has been installed.
417  EXPECT_FALSE(store_->policy());
418  EXPECT_TRUE(store_->policy_map().empty());
419  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
420}
421
422TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidPolicy) {
423  ExpectError(CloudPolicyStore::STATUS_PARSE_ERROR);
424  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("invalid"));
425
426  // Verify no policy has been installed.
427  EXPECT_FALSE(store_->policy());
428  EXPECT_TRUE(store_->policy_map().empty());
429  EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status());
430}
431
432TEST_F(UserCloudPolicyStoreChromeOSTest, LoadValidationError) {
433  policy_.policy_data().clear_policy_type();
434  policy_.Build();
435
436  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
437  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
438  VerifyStoreHasValidationError();
439}
440
441TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoKey) {
442  // The loaded policy can't be verified without the public key.
443  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
444  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
445  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
446  VerifyStoreHasValidationError();
447}
448
449TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidSignature) {
450  // Break the signature.
451  policy_.policy().mutable_policy_data_signature()->append("garbage");
452  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
453  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
454  VerifyStoreHasValidationError();
455}
456
457TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationFull) {
458  std::string data;
459
460  em::DeviceCredentials credentials;
461  credentials.set_device_token(kLegacyToken);
462  credentials.set_device_id(kLegacyDeviceId);
463  ASSERT_TRUE(credentials.SerializeToString(&data));
464  ASSERT_NE(-1, base::WriteFile(token_file(), data.c_str(), data.size()));
465
466  em::CachedCloudPolicyResponse cached_policy;
467  cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy());
468  ASSERT_TRUE(cached_policy.SerializeToString(&data));
469  ASSERT_NE(-1, base::WriteFile(policy_file(), data.c_str(), data.size()));
470
471  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
472  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
473  Mock::VerifyAndClearExpectations(&observer_);
474
475  // Verify that legacy user policy and token have been loaded.
476  em::PolicyData expected_policy_data;
477  EXPECT_TRUE(expected_policy_data.ParseFromString(
478                  cached_policy.cloud_policy().policy_data()));
479  expected_policy_data.clear_public_key_version();
480  expected_policy_data.set_request_token(kLegacyToken);
481  expected_policy_data.set_device_id(kLegacyDeviceId);
482  ASSERT_TRUE(store_->policy());
483  EXPECT_EQ(expected_policy_data.SerializeAsString(),
484            store_->policy()->SerializeAsString());
485  VerifyPolicyMap(kDefaultHomepage);
486  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
487}
488
489TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoToken) {
490  std::string data;
491  testing::Sequence seq;
492
493  em::CachedCloudPolicyResponse cached_policy;
494  cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy());
495  ASSERT_TRUE(cached_policy.SerializeToString(&data));
496  ASSERT_NE(-1, base::WriteFile(policy_file(), data.c_str(), data.size()));
497
498  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
499  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
500  Mock::VerifyAndClearExpectations(&observer_);
501
502  // Verify the legacy cache has been loaded.
503  em::PolicyData expected_policy_data;
504  EXPECT_TRUE(expected_policy_data.ParseFromString(
505                  cached_policy.cloud_policy().policy_data()));
506  expected_policy_data.clear_public_key_version();
507  ASSERT_TRUE(store_->policy());
508  EXPECT_EQ(expected_policy_data.SerializeAsString(),
509            store_->policy()->SerializeAsString());
510  VerifyPolicyMap(kDefaultHomepage);
511  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
512}
513
514TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoPolicy) {
515  std::string data;
516
517  em::DeviceCredentials credentials;
518  credentials.set_device_token(kLegacyToken);
519  credentials.set_device_id(kLegacyDeviceId);
520  ASSERT_TRUE(credentials.SerializeToString(&data));
521  ASSERT_NE(-1, base::WriteFile(token_file(), data.c_str(), data.size()));
522
523  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
524  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
525  Mock::VerifyAndClearExpectations(&observer_);
526
527  // Verify that legacy user policy and token have been loaded.
528  em::PolicyData expected_policy_data;
529  expected_policy_data.set_request_token(kLegacyToken);
530  expected_policy_data.set_device_id(kLegacyDeviceId);
531  ASSERT_TRUE(store_->policy());
532  EXPECT_EQ(expected_policy_data.SerializeAsString(),
533            store_->policy()->SerializeAsString());
534  EXPECT_TRUE(store_->policy_map().empty());
535  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
536}
537
538TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationAndStoreNew) {
539  // Start without an existing public key.
540  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
541
542  std::string data;
543  em::CachedCloudPolicyResponse cached_policy;
544  cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy());
545  ASSERT_TRUE(cached_policy.SerializeToString(&data));
546  ASSERT_NE(-1, base::WriteFile(policy_file(), data.c_str(), data.size()));
547
548  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
549  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
550  Mock::VerifyAndClearExpectations(&observer_);
551
552  // Verify the legacy cache has been loaded.
553  em::PolicyData expected_policy_data;
554  EXPECT_TRUE(expected_policy_data.ParseFromString(
555                  cached_policy.cloud_policy().policy_data()));
556  expected_policy_data.clear_public_key_version();
557  ASSERT_TRUE(store_->policy());
558  EXPECT_EQ(expected_policy_data.SerializeAsString(),
559            store_->policy()->SerializeAsString());
560  VerifyPolicyMap(kDefaultHomepage);
561  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
562  EXPECT_TRUE(base::PathExists(policy_file()));
563
564  // Now store a new policy using the new homepage location.
565  const char kNewHomepage[] = "http://google.com";
566  policy_.payload().mutable_homepagelocation()->set_value(kNewHomepage);
567  policy_.SetDefaultNewSigningKey();
568  policy_.Build();
569  std::vector<uint8> new_public_key;
570  ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
571  ASSERT_NO_FATAL_FAILURE(
572      PerformStorePolicy(&new_public_key, kDefaultHomepage, kNewHomepage));
573  VerifyPolicyMap(kNewHomepage);
574
575  // Verify that the legacy cache has been removed.
576  EXPECT_FALSE(base::PathExists(policy_file()));
577}
578
579TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediately) {
580  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
581  EXPECT_CALL(session_manager_client_,
582              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
583      .WillOnce(Return(policy_.GetBlob()));
584  EXPECT_CALL(cryptohome_client_,
585              BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername))
586      .WillOnce(Return(kSanitizedUsername));
587
588  EXPECT_FALSE(store_->policy());
589  store_->LoadImmediately();
590  // Note: verify that the |observer_| got notified synchronously, without
591  // having to spin the current loop. TearDown() will flush the loop so this
592  // must be done within the test.
593  Mock::VerifyAndClearExpectations(&observer_);
594  Mock::VerifyAndClearExpectations(&session_manager_client_);
595  Mock::VerifyAndClearExpectations(&cryptohome_client_);
596
597  // The policy should become available without having to spin any loops.
598  ASSERT_TRUE(store_->policy());
599  EXPECT_EQ(policy_.policy_data().SerializeAsString(),
600            store_->policy()->SerializeAsString());
601  VerifyPolicyMap(kDefaultHomepage);
602  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
603}
604
605TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoPolicy) {
606  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
607  EXPECT_CALL(session_manager_client_,
608              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
609      .WillOnce(Return(""));
610
611  EXPECT_FALSE(store_->policy());
612  store_->LoadImmediately();
613  Mock::VerifyAndClearExpectations(&observer_);
614  Mock::VerifyAndClearExpectations(&session_manager_client_);
615
616  EXPECT_FALSE(store_->policy());
617  EXPECT_TRUE(store_->policy_map().empty());
618  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
619}
620
621TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyInvalidBlob) {
622  EXPECT_CALL(observer_, OnStoreError(store_.get()));
623  EXPECT_CALL(session_manager_client_,
624              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
625      .WillOnce(Return("le blob"));
626
627  EXPECT_FALSE(store_->policy());
628  store_->LoadImmediately();
629  Mock::VerifyAndClearExpectations(&observer_);
630  Mock::VerifyAndClearExpectations(&session_manager_client_);
631
632  EXPECT_FALSE(store_->policy());
633  EXPECT_TRUE(store_->policy_map().empty());
634  EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status());
635}
636
637TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyDBusFailure) {
638  EXPECT_CALL(observer_, OnStoreError(store_.get()));
639  EXPECT_CALL(session_manager_client_,
640              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
641      .WillOnce(Return(policy_.GetBlob()));
642  EXPECT_CALL(cryptohome_client_,
643              BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername))
644      .WillOnce(Return(""));
645
646  EXPECT_FALSE(store_->policy());
647  store_->LoadImmediately();
648  Mock::VerifyAndClearExpectations(&observer_);
649  Mock::VerifyAndClearExpectations(&session_manager_client_);
650  Mock::VerifyAndClearExpectations(&cryptohome_client_);
651
652  EXPECT_FALSE(store_->policy());
653  EXPECT_TRUE(store_->policy_map().empty());
654  EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR, store_->status());
655}
656
657TEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoUserPolicyKey) {
658  EXPECT_CALL(observer_, OnStoreError(store_.get()));
659  EXPECT_CALL(session_manager_client_,
660              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
661      .WillOnce(Return(policy_.GetBlob()));
662  EXPECT_CALL(cryptohome_client_,
663              BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername))
664      .WillOnce(Return("wrong@example.com"));
665
666  EXPECT_FALSE(store_->policy());
667  store_->LoadImmediately();
668  Mock::VerifyAndClearExpectations(&observer_);
669  Mock::VerifyAndClearExpectations(&session_manager_client_);
670  Mock::VerifyAndClearExpectations(&cryptohome_client_);
671
672  EXPECT_FALSE(store_->policy());
673  EXPECT_TRUE(store_->policy_map().empty());
674  EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
675}
676
677}  // namespace
678
679}  // namespace policy
680