12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
149ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/mock_cryptohome_client.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/mock_session_manager_client.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h"
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/mock_cloud_policy_store.h"
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/policy_builder.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "policy/policy_constants.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "policy/proto/cloud_policy.pb.h"
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_local.pb.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace em = enterprise_management;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::AllOf;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::AnyNumber;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Eq;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Mock;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Property;
34bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochusing testing::Return;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::SaveArg;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::_;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace policy {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kLegacyDeviceId[] = "legacy-device-id";
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kLegacyToken[] = "legacy-token";
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSanitizedUsername[] =
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "0123456789ABCDEF0123456789ABCDEF012345678@example.com";
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDefaultHomepage[] = "http://chromium.org";
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ACTION_P2(SendSanitizedUsername, call_status, sanitized_username) {
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostTask(
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      FROM_HERE, base::Bind(arg1, call_status, sanitized_username));
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class UserCloudPolicyStoreChromeOSTest : public testing::Test {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UserCloudPolicyStoreChromeOSTest() {}
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(cryptohome_client_,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                GetSanitizedUsername(PolicyBuilder::kFakeUsername, _))
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .Times(AnyNumber())
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .WillRepeatedly(
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_SUCCESS,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  kSanitizedUsername));
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(tmp_dir_.CreateUniqueTempDir());
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    store_.reset(new UserCloudPolicyStoreChromeOS(&cryptohome_client_,
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  &session_manager_client_,
688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                                  loop_.message_loop_proxy(),
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  PolicyBuilder::kFakeUsername,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  user_policy_dir(),
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  token_file(),
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                  policy_file()));
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    store_->AddObserver(&observer_);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Install the initial public key, so that by default the validation of
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the stored/loaded policy blob succeeds.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<uint8> public_key;
782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    ASSERT_TRUE(policy_.GetSigningKey()->ExportPublicKey(&public_key));
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StoreUserPolicyKey(public_key);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy_.payload().mutable_homepagelocation()->set_value(kDefaultHomepage);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    policy_.Build();
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    store_->RemoveObserver(&observer_);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    store_.reset();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Install an expectation on |observer_| for an error code.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ExpectError(CloudPolicyStore::Status error) {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(observer_,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                OnStoreError(AllOf(Eq(store_.get()),
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   Property(&CloudPolicyStore::status,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            Eq(error)))));
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Triggers a store_->Load() operation, handles the expected call to
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |session_manager_client_| and sends |response|.
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void PerformPolicyLoad(const std::string& response) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Issue a load command.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback;
104a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    EXPECT_CALL(session_manager_client_,
105a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _))
106a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        .WillOnce(SaveArg<1>(&retrieve_callback));
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    store_->Load();
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Mock::VerifyAndClearExpectations(&session_manager_client_);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_FALSE(retrieve_callback.is_null());
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Run the callback.
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    retrieve_callback.Run(response);
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verifies that store_->policy_map() has the HomepageLocation entry with
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the |expected_value|.
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void VerifyPolicyMap(const char* expected_value) {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1U, store_->policy_map().size());
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PolicyMap::Entry* entry =
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        store_->policy_map().Get(key::kHomepageLocation);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(entry);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(base::StringValue(expected_value).Equals(entry->value));
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StoreUserPolicyKey(const std::vector<uint8>& public_key) {
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ASSERT_TRUE(base::CreateDirectory(user_policy_key_file().DirName()));
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::WriteFile(user_policy_key_file(),
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        reinterpret_cast<const char*>(public_key.data()),
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                        public_key.size()));
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Stores the current |policy_| and verifies that it is published.
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If |new_public_key| is set then it will be persisted after storing but
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // before loading the policy, so that the signature validation can succeed.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If |previous_value| is set then a previously existing policy with that
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // value will be expected; otherwise no previous policy is expected.
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If |new_value| is set then a new policy with that value is expected after
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // storing the |policy_| blob.
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void PerformStorePolicy(const std::vector<uint8>* new_public_key,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          const char* previous_value,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          const char* new_value) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chromeos::SessionManagerClient::StorePolicyCallback store_callback;
146a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    EXPECT_CALL(session_manager_client_,
147a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                StorePolicyForUser(PolicyBuilder::kFakeUsername,
148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                   policy_.GetBlob(), _))
149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        .WillOnce(SaveArg<2>(&store_callback));
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    store_->Store(policy_.policy());
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Mock::VerifyAndClearExpectations(&session_manager_client_);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_FALSE(store_callback.is_null());
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The new policy shouldn't be present yet.
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PolicyMap previous_policy;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(previous_value != NULL, store_->policy() != NULL);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (previous_value) {
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      previous_policy.Set(key::kHomepageLocation,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          POLICY_LEVEL_MANDATORY,
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          POLICY_SCOPE_USER,
162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          new base::StringValue(previous_value), NULL);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(previous_policy.Equals(store_->policy_map()));
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Store the new public key so that the validation after the retrieve
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // operation completes can verify the signature.
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (new_public_key)
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      StoreUserPolicyKey(*new_public_key);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Let the store operation complete.
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chromeos::SessionManagerClient::RetrievePolicyCallback retrieve_callback;
174a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    EXPECT_CALL(session_manager_client_,
175a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                RetrievePolicyForUser(PolicyBuilder::kFakeUsername, _))
176a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        .WillOnce(SaveArg<1>(&retrieve_callback));
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    store_callback.Run(true);
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(previous_policy.Equals(store_->policy_map()));
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Mock::VerifyAndClearExpectations(&session_manager_client_);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_FALSE(retrieve_callback.is_null());
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Finish the retrieve callback.
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    retrieve_callback.Run(policy_.GetBlob());
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(store_->policy());
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(policy_.policy_data().SerializeAsString(),
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              store_->policy()->SerializeAsString());
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VerifyPolicyMap(new_value);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void VerifyStoreHasValidationError() {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_FALSE(store_->policy());
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(store_->policy_map().empty());
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RunUntilIdle() {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    loop_.RunUntilIdle();
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    loop_.RunUntilIdle();
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath user_policy_dir() {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return tmp_dir_.path().AppendASCII("var_run_user_policy");
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath user_policy_key_file() {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return user_policy_dir().AppendASCII(kSanitizedUsername)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            .AppendASCII("policy.pub");
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath token_file() {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return tmp_dir_.path().AppendASCII("token");
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath policy_file() {
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return tmp_dir_.path().AppendASCII("policy");
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoopForUI loop_;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chromeos::MockCryptohomeClient cryptohome_client_;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chromeos::MockSessionManagerClient session_manager_client_;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UserPolicyBuilder policy_;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockCloudPolicyStoreObserver observer_;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<UserCloudPolicyStoreChromeOS> store_;
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir tmp_dir_;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreChromeOSTest);
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStore) {
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start without any public key to trigger the initial key checks.
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make the policy blob contain a new public key.
2402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  policy_.SetDefaultNewSigningKey();
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.Build();
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<uint8> new_public_key;
2432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage));
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStoreValidationFail) {
249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Start without any public key to trigger the initial key checks.
250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
251f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Make the policy blob contain a new public key.
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.SetDefaultSigningKey();
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.Build();
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  *policy_.policy().mutable_new_public_key_verification_signature() = "garbage";
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(session_manager_client_,
257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              StorePolicyForUser(
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0);
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  store_->Store(policy_.policy());
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RunUntilIdle();
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Mock::VerifyAndClearExpectations(&session_manager_client_);
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, InitialStoreMissingSignatureFailure) {
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Start without any public key to trigger the initial key checks.
266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Make the policy blob contain a new public key.
268f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.SetDefaultSigningKey();
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.Build();
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.policy().clear_new_public_key_verification_signature();
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(session_manager_client_,
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              StorePolicyForUser(
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0);
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  store_->Store(policy_.policy());
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RunUntilIdle();
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Mock::VerifyAndClearExpectations(&session_manager_client_);
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithExistingKey) {
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PerformStorePolicy(NULL, NULL, kDefaultHomepage));
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithRotation) {
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make the policy blob contain a new public key.
2872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  policy_.SetDefaultNewSigningKey();
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.Build();
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<uint8> new_public_key;
2902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PerformStorePolicy(&new_public_key, NULL, kDefaultHomepage));
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest,
296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)       StoreWithRotationMissingSignatureError) {
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Make the policy blob contain a new public key.
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.SetDefaultNewSigningKey();
299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.Build();
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.policy().clear_new_public_key_verification_signature();
301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(session_manager_client_,
303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              StorePolicyForUser(
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0);
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  store_->Store(policy_.policy());
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RunUntilIdle();
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Mock::VerifyAndClearExpectations(&session_manager_client_);
308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithRotationValidationError) {
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Make the policy blob contain a new public key.
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.SetDefaultNewSigningKey();
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  policy_.Build();
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  *policy_.policy().mutable_new_public_key_verification_signature() = "garbage";
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(session_manager_client_,
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              StorePolicyForUser(
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  PolicyBuilder::kFakeUsername, policy_.GetBlob(), _)).Times(0);
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  store_->Store(policy_.policy());
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RunUntilIdle();
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Mock::VerifyAndClearExpectations(&session_manager_client_);
322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, StoreFail) {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store policy.
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chromeos::SessionManagerClient::StorePolicyCallback store_callback;
327a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_CALL(session_manager_client_,
328a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              StorePolicyForUser(PolicyBuilder::kFakeUsername,
329010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 policy_.GetBlob(), _))
330010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      .WillOnce(SaveArg<2>(&store_callback));
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_->Store(policy_.policy());
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&session_manager_client_);
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(store_callback.is_null());
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Let the store operation complete.
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectError(CloudPolicyStore::STATUS_STORE_ERROR);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_callback.Run(false);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(store_->policy());
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(store_->policy_map().empty());
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR, store_->status());
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, StoreValidationError) {
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.policy_data().clear_policy_type();
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.Build();
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store policy.
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chromeos::SessionManagerClient::StorePolicyCallback store_callback;
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
352a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_CALL(session_manager_client_,
353a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              StorePolicyForUser(PolicyBuilder::kFakeUsername,
354010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 policy_.GetBlob(), _))
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(0);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_->Store(policy_.policy());
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&session_manager_client_);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithoutPolicyKey) {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Make the dbus call to cryptohome fail.
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&cryptohome_client_);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(cryptohome_client_,
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetSanitizedUsername(PolicyBuilder::kFakeUsername, _))
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(AnyNumber())
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillRepeatedly(SendSanitizedUsername(chromeos::DBUS_METHOD_CALL_FAILURE,
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                            std::string()));
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store policy.
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chromeos::SessionManagerClient::StorePolicyCallback store_callback;
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
373a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_CALL(session_manager_client_,
374a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              StorePolicyForUser(PolicyBuilder::kFakeUsername,
375010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 policy_.GetBlob(), _))
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(0);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_->Store(policy_.policy());
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&session_manager_client_);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, StoreWithInvalidSignature) {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Break the signature.
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.policy().mutable_policy_data_signature()->append("garbage");
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Store policy.
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chromeos::SessionManagerClient::StorePolicyCallback store_callback;
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
389a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_CALL(session_manager_client_,
390a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              StorePolicyForUser(PolicyBuilder::kFakeUsername,
391010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                 policy_.GetBlob(), _))
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Times(0);
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  store_->Store(policy_.policy());
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunUntilIdle();
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&session_manager_client_);
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, Load) {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&observer_);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that the policy has been loaded.
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(store_->policy());
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(policy_.policy_data().SerializeAsString(),
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            store_->policy()->SerializeAsString());
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPolicyMap(kDefaultHomepage);
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoPolicy) {
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&observer_);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify no policy has been installed.
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(store_->policy());
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(store_->policy_map().empty());
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidPolicy) {
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectError(CloudPolicyStore::STATUS_PARSE_ERROR);
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad("invalid"));
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify no policy has been installed.
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(store_->policy());
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(store_->policy_map().empty());
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status());
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, LoadValidationError) {
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.policy_data().clear_policy_type();
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.Build();
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyStoreHasValidationError();
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, LoadNoKey) {
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The loaded policy can't be verified without the public key.
4437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyStoreHasValidationError();
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, LoadInvalidSignature) {
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Break the signature.
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.policy().mutable_policy_data_signature()->append("garbage");
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectError(CloudPolicyStore::STATUS_VALIDATION_ERROR);
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(policy_.GetBlob()));
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyStoreHasValidationError();
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationFull) {
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::DeviceCredentials credentials;
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  credentials.set_device_token(kLegacyToken);
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  credentials.set_device_id(kLegacyDeviceId);
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(credentials.SerializeToString(&data));
464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_NE(-1, base::WriteFile(token_file(), data.c_str(), data.size()));
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::CachedCloudPolicyResponse cached_policy;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy());
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(cached_policy.SerializeToString(&data));
469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_NE(-1, base::WriteFile(policy_file(), data.c_str(), data.size()));
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&observer_);
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that legacy user policy and token have been loaded.
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::PolicyData expected_policy_data;
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(expected_policy_data.ParseFromString(
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  cached_policy.cloud_policy().policy_data()));
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_policy_data.clear_public_key_version();
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_policy_data.set_request_token(kLegacyToken);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_policy_data.set_device_id(kLegacyDeviceId);
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(store_->policy());
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(expected_policy_data.SerializeAsString(),
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            store_->policy()->SerializeAsString());
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPolicyMap(kDefaultHomepage);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoToken) {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::Sequence seq;
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::CachedCloudPolicyResponse cached_policy;
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy());
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(cached_policy.SerializeToString(&data));
496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_NE(-1, base::WriteFile(policy_file(), data.c_str(), data.size()));
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&observer_);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify the legacy cache has been loaded.
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::PolicyData expected_policy_data;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(expected_policy_data.ParseFromString(
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  cached_policy.cloud_policy().policy_data()));
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_policy_data.clear_public_key_version();
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(store_->policy());
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(expected_policy_data.SerializeAsString(),
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            store_->policy()->SerializeAsString());
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPolicyMap(kDefaultHomepage);
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationNoPolicy) {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::DeviceCredentials credentials;
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  credentials.set_device_token(kLegacyToken);
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  credentials.set_device_id(kLegacyDeviceId);
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(credentials.SerializeToString(&data));
521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_NE(-1, base::WriteFile(token_file(), data.c_str(), data.size()));
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&observer_);
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that legacy user policy and token have been loaded.
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::PolicyData expected_policy_data;
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_policy_data.set_request_token(kLegacyToken);
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_policy_data.set_device_id(kLegacyDeviceId);
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(store_->policy());
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(expected_policy_data.SerializeAsString(),
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            store_->policy()->SerializeAsString());
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(store_->policy_map().empty());
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(UserCloudPolicyStoreChromeOSTest, MigrationAndStoreNew) {
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start without an existing public key.
5407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ASSERT_TRUE(base::DeleteFile(user_policy_key_file(), false));
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string data;
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::CachedCloudPolicyResponse cached_policy;
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  cached_policy.mutable_cloud_policy()->CopyFrom(policy_.policy());
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(cached_policy.SerializeToString(&data));
546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_NE(-1, base::WriteFile(policy_file(), data.c_str(), data.size()));
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(PerformPolicyLoad(""));
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Mock::VerifyAndClearExpectations(&observer_);
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify the legacy cache has been loaded.
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  em::PolicyData expected_policy_data;
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(expected_policy_data.ParseFromString(
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  cached_policy.cloud_policy().policy_data()));
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected_policy_data.clear_public_key_version();
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(store_->policy());
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(expected_policy_data.SerializeAsString(),
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            store_->policy()->SerializeAsString());
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPolicyMap(kDefaultHomepage);
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
5627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(base::PathExists(policy_file()));
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now store a new policy using the new homepage location.
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char kNewHomepage[] = "http://google.com";
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.payload().mutable_homepagelocation()->set_value(kNewHomepage);
5672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  policy_.SetDefaultNewSigningKey();
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy_.Build();
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<uint8> new_public_key;
5702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ASSERT_TRUE(policy_.GetNewSigningKey()->ExportPublicKey(&new_public_key));
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PerformStorePolicy(&new_public_key, kDefaultHomepage, kNewHomepage));
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  VerifyPolicyMap(kNewHomepage);
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Verify that the legacy cache has been removed.
5767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(base::PathExists(policy_file()));
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
579bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediately) {
580bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
581bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(session_manager_client_,
582bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
583bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      .WillOnce(Return(policy_.GetBlob()));
584bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(cryptohome_client_,
585bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch              BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername))
586bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      .WillOnce(Return(kSanitizedUsername));
587bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
588bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(store_->policy());
589bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  store_->LoadImmediately();
590bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // Note: verify that the |observer_| got notified synchronously, without
591bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // having to spin the current loop. TearDown() will flush the loop so this
592bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // must be done within the test.
593bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&observer_);
594bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&session_manager_client_);
595bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&cryptohome_client_);
596bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
597bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  // The policy should become available without having to spin any loops.
598bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  ASSERT_TRUE(store_->policy());
599bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_EQ(policy_.policy_data().SerializeAsString(),
600bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch            store_->policy()->SerializeAsString());
601bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  VerifyPolicyMap(kDefaultHomepage);
602bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
603bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
604bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
605bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoPolicy) {
606bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(observer_, OnStoreLoaded(store_.get()));
607bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(session_manager_client_,
608bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
609bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      .WillOnce(Return(""));
610bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
611bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(store_->policy());
612bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  store_->LoadImmediately();
613bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&observer_);
614bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&session_manager_client_);
615bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
616bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(store_->policy());
617bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_TRUE(store_->policy_map().empty());
618bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status());
619bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
620bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
621bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyInvalidBlob) {
622bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(observer_, OnStoreError(store_.get()));
623bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(session_manager_client_,
624bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
625bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      .WillOnce(Return("le blob"));
626bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
627bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(store_->policy());
628bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  store_->LoadImmediately();
629bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&observer_);
630bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&session_manager_client_);
631bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
632bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(store_->policy());
633bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_TRUE(store_->policy_map().empty());
634bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_EQ(CloudPolicyStore::STATUS_PARSE_ERROR, store_->status());
635bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
636bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
637bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyDBusFailure) {
638bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(observer_, OnStoreError(store_.get()));
639bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(session_manager_client_,
640bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
641bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      .WillOnce(Return(policy_.GetBlob()));
642bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(cryptohome_client_,
643bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch              BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername))
644bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      .WillOnce(Return(""));
645bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
646bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(store_->policy());
647bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  store_->LoadImmediately();
648bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&observer_);
649bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&session_manager_client_);
650bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&cryptohome_client_);
651bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
652bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(store_->policy());
653bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_TRUE(store_->policy_map().empty());
654bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR, store_->status());
655bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
656bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
657bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben MurdochTEST_F(UserCloudPolicyStoreChromeOSTest, LoadImmediatelyNoUserPolicyKey) {
658bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(observer_, OnStoreError(store_.get()));
659bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(session_manager_client_,
660bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch              BlockingRetrievePolicyForUser(PolicyBuilder::kFakeUsername))
661bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      .WillOnce(Return(policy_.GetBlob()));
662bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_CALL(cryptohome_client_,
663bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch              BlockingGetSanitizedUsername(PolicyBuilder::kFakeUsername))
6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      .WillOnce(Return("wrong@example.com"));
665bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
666bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(store_->policy());
667bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  store_->LoadImmediately();
668bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&observer_);
669bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&session_manager_client_);
670bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  Mock::VerifyAndClearExpectations(&cryptohome_client_);
671bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
672bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_FALSE(store_->policy());
673bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_TRUE(store_->policy_map().empty());
674bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  EXPECT_EQ(CloudPolicyStore::STATUS_VALIDATION_ERROR, store_->status());
675bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch}
676bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace policy
680