summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjkummerow@chromium.org <jkummerow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-29 14:19:27 +0000
committerjkummerow@chromium.org <jkummerow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-29 14:19:27 +0000
commit82e4080d97b52798c3605fa73979c0bdf0fdc597 (patch)
tree56f9ce7093b4faea11ae8528842b5b7fa5c5b72a
parent34daae316805e93a5d61faa6124e1a2f5172676e (diff)
downloadchromium_src-82e4080d97b52798c3605fa73979c0bdf0fdc597.zip
chromium_src-82e4080d97b52798c3605fa73979c0bdf0fdc597.tar.gz
chromium_src-82e4080d97b52798c3605fa73979c0bdf0fdc597.tar.bz2
Send policy blobs to session_manager
And also read policy back from session_manager into CloudPolicyCache, but there are no consumers of those values yet. BUG=chromium-os:11258 TEST=UserPolicyCacheTest.*; DevicePolicyCacheTest.* Review URL: http://codereview.chromium.org/6705031 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79677 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/login/signed_settings_helper.cc99
-rw-r--r--chrome/browser/chromeos/login/signed_settings_helper.h20
-rw-r--r--chrome/browser/policy/browser_policy_connector.cc27
-rw-r--r--chrome/browser/policy/cloud_policy_cache.cc462
-rw-r--r--chrome/browser/policy/cloud_policy_cache.h149
-rw-r--r--chrome/browser/policy/cloud_policy_cache_base.cc155
-rw-r--r--chrome/browser/policy/cloud_policy_cache_base.h128
-rw-r--r--chrome/browser/policy/cloud_policy_cache_unittest.cc651
-rw-r--r--chrome/browser/policy/cloud_policy_controller.cc9
-rw-r--r--chrome/browser/policy/cloud_policy_controller.h10
-rw-r--r--chrome/browser/policy/cloud_policy_controller_unittest.cc10
-rw-r--r--chrome/browser/policy/cloud_policy_subsystem.cc10
-rw-r--r--chrome/browser/policy/cloud_policy_subsystem.h9
-rw-r--r--chrome/browser/policy/device_policy_cache.cc97
-rw-r--r--chrome/browser/policy/device_policy_cache.h66
-rw-r--r--chrome/browser/policy/device_policy_cache_unittest.cc142
-rw-r--r--chrome/browser/policy/device_token_fetcher.cc8
-rw-r--r--chrome/browser/policy/device_token_fetcher.h10
-rw-r--r--chrome/browser/policy/device_token_fetcher_unittest.cc6
-rw-r--r--chrome/browser/policy/profile_policy_connector.cc5
-rw-r--r--chrome/browser/policy/user_policy_cache.cc153
-rw-r--r--chrome/browser/policy/user_policy_cache.h43
-rw-r--r--chrome/browser/policy/user_policy_cache_unittest.cc338
-rw-r--r--chrome/chrome_browser.gypi9
-rw-r--r--chrome/chrome_tests.gypi4
-rw-r--r--chrome/common/chrome_switches.cc7
-rw-r--r--chrome/common/chrome_switches.h2
27 files changed, 1286 insertions, 1343 deletions
diff --git a/chrome/browser/chromeos/login/signed_settings_helper.cc b/chrome/browser/chromeos/login/signed_settings_helper.cc
index d8f5613b..b83a170 100644
--- a/chrome/browser/chromeos/login/signed_settings_helper.cc
+++ b/chrome/browser/chromeos/login/signed_settings_helper.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/chromeos/login/signed_settings.h"
+#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "content/browser/browser_thread.h"
namespace chromeos {
@@ -54,7 +55,7 @@ class OpContext {
void Cancel() {
CancelCallback();
- if (!executing_)
+ if (!executing_)
OnOpCompleted();
}
@@ -117,7 +118,7 @@ class WhitelistOpContext : public SignedSettings::Delegate<bool>,
// chromeos::SignedSettings::Delegate implementation
virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code,
- bool value) {
+ bool value) OVERRIDE {
if (callback_) {
switch (type_) {
case CHECK:
@@ -139,7 +140,7 @@ class WhitelistOpContext : public SignedSettings::Delegate<bool>,
protected:
// OpContext implemenetation
- virtual void CreateOp() {
+ virtual void CreateOp() OVERRIDE {
switch (type_) {
case CHECK:
op_ = SignedSettings::CreateCheckWhitelistOp(email_, this);
@@ -177,7 +178,7 @@ class StorePropertyOpContext : public SignedSettings::Delegate<bool>,
// chromeos::SignedSettings::Delegate implementation
virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code,
- bool unused) {
+ bool unused) OVERRIDE {
VLOG(2) << "OnSettingsOpCompleted, code = " << code;
if (callback_)
callback_->OnStorePropertyCompleted(code, name_, value_);
@@ -186,7 +187,7 @@ class StorePropertyOpContext : public SignedSettings::Delegate<bool>,
protected:
// OpContext implemenetation
- virtual void CreateOp() {
+ virtual void CreateOp() OVERRIDE {
op_ = SignedSettings::CreateStorePropertyOp(name_, value_, this);
}
@@ -210,7 +211,7 @@ class RetrievePropertyOpContext
// chromeos::SignedSettings::Delegate implementation
virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code,
- std::string value) {
+ std::string value) OVERRIDE {
if (callback_)
callback_->OnRetrievePropertyCompleted(code, name_, value);
@@ -219,7 +220,7 @@ class RetrievePropertyOpContext
protected:
// OpContext implemenetation
- virtual void CreateOp() {
+ virtual void CreateOp() OVERRIDE {
op_ = SignedSettings::CreateRetrievePropertyOp(name_, this);
}
@@ -229,6 +230,64 @@ class RetrievePropertyOpContext
DISALLOW_COPY_AND_ASSIGN(RetrievePropertyOpContext);
};
+class StorePolicyOpContext : public SignedSettings::Delegate<bool>,
+ public OpContext {
+ public:
+ StorePolicyOpContext(const em::PolicyFetchResponse& policy,
+ SignedSettingsHelper::Callback* callback,
+ Delegate* delegate)
+ : OpContext(callback, delegate),
+ policy_(policy) {
+ }
+
+ // chromeos::SignedSettings::Delegate implementation
+ virtual void OnSettingsOpCompleted(SignedSettings::ReturnCode code,
+ bool unused) OVERRIDE {
+ VLOG(2) << "OnSettingsOpCompleted, code = " << code;
+ if (callback_)
+ callback_->OnStorePolicyCompleted(code);
+ OnOpCompleted();
+ }
+
+ protected:
+ // OpContext implementation
+ virtual void CreateOp() OVERRIDE {
+ op_ = SignedSettings::CreateStorePolicyOp(&policy_, this);
+ }
+
+ private:
+ em::PolicyFetchResponse policy_;
+ DISALLOW_COPY_AND_ASSIGN(StorePolicyOpContext);
+};
+
+class RetrievePolicyOpContext
+ : public SignedSettings::Delegate<const em::PolicyFetchResponse&>,
+ public OpContext {
+ public:
+ RetrievePolicyOpContext(SignedSettingsHelper::Callback* callback,
+ Delegate* delegate)
+ : OpContext(callback, delegate) {
+ }
+
+ // chromeos::SignedSettings::Delegate implementation
+ virtual void OnSettingsOpCompleted(
+ SignedSettings::ReturnCode code,
+ const em::PolicyFetchResponse& policy) OVERRIDE {
+ if (callback_)
+ callback_->OnRetrievePolicyCompleted(code, policy);
+ OnOpCompleted();
+ }
+
+ protected:
+ // OpContext implementation
+ virtual void CreateOp() OVERRIDE {
+ op_ = SignedSettings::CreateRetrievePolicyOp(this);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RetrievePolicyOpContext);
+};
+
} // namespace
@@ -237,16 +296,19 @@ class SignedSettingsHelperImpl : public SignedSettingsHelper,
public:
// SignedSettingsHelper implementation
virtual void StartCheckWhitelistOp(const std::string& email,
- Callback* callback);
+ Callback* callback) OVERRIDE;
virtual void StartWhitelistOp(const std::string& email,
bool add_to_whitelist,
- Callback* callback);
+ Callback* callback) OVERRIDE;
virtual void StartStorePropertyOp(const std::string& name,
const std::string& value,
- Callback* callback);
+ Callback* callback) OVERRIDE;
virtual void StartRetrieveProperty(const std::string& name,
- Callback* callback);
- virtual void CancelCallback(Callback* callback);
+ Callback* callback) OVERRIDE;
+ virtual void StartStorePolicyOp(const em::PolicyFetchResponse& policy,
+ Callback* callback) OVERRIDE;
+ virtual void StartRetrievePolicyOp(Callback* callback) OVERRIDE;
+ virtual void CancelCallback(Callback* callback) OVERRIDE;
// OpContext::Delegate implementation
virtual void OnOpCreated(OpContext* context);
@@ -304,7 +366,7 @@ void SignedSettingsHelperImpl::StartWhitelistOp(
void SignedSettingsHelperImpl::StartStorePropertyOp(
const std::string& name,
const std::string& value,
- SignedSettingsHelper::SignedSettingsHelper::Callback* callback) {
+ SignedSettingsHelper::Callback* callback) {
AddOpContext(new StorePropertyOpContext(
name,
value,
@@ -321,6 +383,17 @@ void SignedSettingsHelperImpl::StartRetrieveProperty(
this));
}
+void SignedSettingsHelperImpl::StartStorePolicyOp(
+ const em::PolicyFetchResponse& policy,
+ SignedSettingsHelper::Callback* callback) {
+ AddOpContext(new StorePolicyOpContext(policy, callback, this));
+}
+
+void SignedSettingsHelperImpl::StartRetrievePolicyOp(
+ SignedSettingsHelper::Callback* callback) {
+ AddOpContext(new RetrievePolicyOpContext(callback, this));
+}
+
void SignedSettingsHelperImpl::CancelCallback(
SignedSettingsHelper::Callback* callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
diff --git a/chrome/browser/chromeos/login/signed_settings_helper.h b/chrome/browser/chromeos/login/signed_settings_helper.h
index d65b677..406ba7b 100644
--- a/chrome/browser/chromeos/login/signed_settings_helper.h
+++ b/chrome/browser/chromeos/login/signed_settings_helper.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,8 +6,14 @@
#define CHROME_BROWSER_CHROMEOS_LOGIN_SIGNED_SETTINGS_HELPER_H_
#pragma once
+#include <string>
+
#include "chrome/browser/chromeos/login/signed_settings.h"
+namespace enterprise_management {
+class PolicyFetchResponse;
+} // namespace enterprise_management
+namespace em = enterprise_management;
namespace chromeos {
class SignedSettings;
@@ -43,6 +49,15 @@ class SignedSettingsHelper {
SignedSettings::ReturnCode code,
const std::string& name,
const std::string& value) {}
+
+ // Callback of StorePolicyOp.
+ virtual void OnStorePolicyCompleted(
+ SignedSettings::ReturnCode code) {}
+
+ // Callback of RetrievePolicyOp.
+ virtual void OnRetrievePolicyCompleted(
+ SignedSettings::ReturnCode code,
+ const em::PolicyFetchResponse& policy) {}
};
// Class factory
@@ -59,6 +74,9 @@ class SignedSettingsHelper {
Callback* callback) = 0;
virtual void StartRetrieveProperty(const std::string& name,
Callback* callback) = 0;
+ virtual void StartStorePolicyOp(const em::PolicyFetchResponse& policy,
+ Callback* callback) = 0;
+ virtual void StartRetrievePolicyOp(Callback* callback) = 0;
// Cancels all pending calls of given callback.
virtual void CancelCallback(Callback* callback) = 0;
diff --git a/chrome/browser/policy/browser_policy_connector.cc b/chrome/browser/policy/browser_policy_connector.cc
index 382d6d2..ce6c17f 100644
--- a/chrome/browser/policy/browser_policy_connector.cc
+++ b/chrome/browser/policy/browser_policy_connector.cc
@@ -29,16 +29,10 @@
#endif
#if defined(OS_CHROMEOS)
+#include "chrome/browser/policy/device_policy_cache.h"
#include "chrome/browser/policy/device_policy_identity_strategy.h"
#endif
-namespace {
-
-const FilePath::CharType kDevicePolicyCacheFile[] =
- FILE_PATH_LITERAL("Policy");
-
-} // namespace
-
namespace policy {
BrowserPolicyConnector::BrowserPolicyConnector() {
@@ -49,20 +43,11 @@ BrowserPolicyConnector::BrowserPolicyConnector() {
#if defined(OS_CHROMEOS)
CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(switches::kDevicePolicyCacheDir)) {
- FilePath cache_dir(command_line->GetSwitchValuePath(
- switches::kDevicePolicyCacheDir));
-
- if (!file_util::CreateDirectory(cache_dir)) {
- LOG(WARNING) << "Device policy cache directory "
- << cache_dir.value()
- << " is not accessible, skipping initialization.";
- } else {
- identity_strategy_.reset(new DevicePolicyIdentityStrategy());
- cloud_policy_subsystem_.reset(
- new CloudPolicySubsystem(cache_dir.Append(kDevicePolicyCacheFile),
- identity_strategy_.get()));
- }
+ if (command_line->HasSwitch(switches::kEnableDevicePolicy)) {
+ identity_strategy_.reset(new DevicePolicyIdentityStrategy());
+ cloud_policy_subsystem_.reset(
+ new CloudPolicySubsystem(identity_strategy_.get(),
+ new DevicePolicyCache()));
}
#endif
}
diff --git a/chrome/browser/policy/cloud_policy_cache.cc b/chrome/browser/policy/cloud_policy_cache.cc
deleted file mode 100644
index a3e83ae..0000000
--- a/chrome/browser/policy/cloud_policy_cache.cc
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/policy/cloud_policy_cache.h"
-
-#include <limits>
-
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "base/task.h"
-#include "base/values.h"
-#include "chrome/browser/policy/configuration_policy_pref_store.h"
-#include "chrome/browser/policy/proto/cloud_policy.pb.h"
-#include "chrome/browser/policy/proto/device_management_constants.h"
-#include "chrome/browser/policy/proto/device_management_local.pb.h"
-#include "content/browser/browser_thread.h"
-
-using google::protobuf::RepeatedField;
-using google::protobuf::RepeatedPtrField;
-
-// This CloudPolicyCache currently supports two protocols for the interaction
-// with DMServer: the old "DevicePolicy" format, which is being used in the
-// CrOS Pilot Program and will be deprecated afterwards, and the new
-// "CloudPolicy" format, which will be used exclusively after the public launch
-// of ChromeOS.
-
-namespace policy {
-
-// Decodes a CloudPolicySettings object into two maps with mandatory and
-// recommended settings, respectively. The implementation is generated code
-// in policy/cloud_policy_generated.cc.
-void DecodePolicy(const em::CloudPolicySettings& policy,
- PolicyMap* mandatory, PolicyMap* recommended);
-
-// A thin ConfigurationPolicyProvider implementation sitting on top of
-// CloudPolicyCache for hooking up with ConfigurationPolicyPrefStore.
-class CloudPolicyCache::CloudPolicyProvider
- : public ConfigurationPolicyProvider {
- public:
- CloudPolicyProvider(const PolicyDefinitionList* policy_list,
- CloudPolicyCache* cache,
- CloudPolicyCache::PolicyLevel level)
- : ConfigurationPolicyProvider(policy_list),
- cache_(cache),
- level_(level) {}
- virtual ~CloudPolicyProvider() {}
-
- virtual bool Provide(ConfigurationPolicyStoreInterface* store) {
- if (!cache_->has_device_policy()) {
- if (level_ == POLICY_LEVEL_MANDATORY)
- ApplyPolicyMap(&cache_->mandatory_policy_, store);
- else if (level_ == POLICY_LEVEL_RECOMMENDED)
- ApplyPolicyMap(&cache_->recommended_policy_, store);
- } else {
- ApplyPolicyValueTree(cache_->device_policy_.get(), store);
- }
- return true;
- }
-
- virtual bool IsInitializationComplete() const {
- return cache_->initialization_complete_;
- }
-
- virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) {
- cache_->observer_list_.AddObserver(observer);
- }
- virtual void RemoveObserver(ConfigurationPolicyProvider::Observer* observer) {
- cache_->observer_list_.RemoveObserver(observer);
- }
-
- private:
- // The underlying policy cache.
- CloudPolicyCache* cache_;
- // Policy level this provider will handle.
- CloudPolicyCache::PolicyLevel level_;
-
- DISALLOW_COPY_AND_ASSIGN(CloudPolicyProvider);
-};
-
-// Saves policy information to a file.
-class PersistPolicyTask : public Task {
- public:
- PersistPolicyTask(const FilePath& path,
- const em::PolicyFetchResponse* cloud_policy_response,
- const em::DevicePolicyResponse* device_policy_response,
- const bool is_unmanaged)
- : path_(path),
- cloud_policy_response_(cloud_policy_response),
- device_policy_response_(device_policy_response),
- is_unmanaged_(is_unmanaged) {}
-
- private:
- // Task override.
- virtual void Run();
-
- const FilePath path_;
- scoped_ptr<const em::PolicyFetchResponse> cloud_policy_response_;
- scoped_ptr<const em::DevicePolicyResponse> device_policy_response_;
- const bool is_unmanaged_;
-};
-
-void PersistPolicyTask::Run() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- std::string data;
- em::CachedCloudPolicyResponse cached_policy;
- if (cloud_policy_response_.get()) {
- cached_policy.mutable_cloud_policy()->CopyFrom(*cloud_policy_response_);
- } else if (device_policy_response_.get()) {
- cached_policy.mutable_device_policy()->CopyFrom(*device_policy_response_);
- cached_policy.set_timestamp(base::Time::NowFromSystemTime().ToTimeT());
- }
- if (is_unmanaged_) {
- cached_policy.set_unmanaged(true);
- cached_policy.set_timestamp(base::Time::NowFromSystemTime().ToTimeT());
- }
- if (!cached_policy.SerializeToString(&data)) {
- LOG(WARNING) << "Failed to serialize policy data";
- return;
- }
-
- int size = data.size();
- if (file_util::WriteFile(path_, data.c_str(), size) != size) {
- LOG(WARNING) << "Failed to write " << path_.value();
- return;
- }
-}
-
-CloudPolicyCache::CloudPolicyCache(
- const FilePath& backing_file_path)
- : backing_file_path_(backing_file_path),
- device_policy_(new DictionaryValue),
- initialization_complete_(false),
- is_unmanaged_(false),
- has_device_policy_(false) {
- managed_policy_provider_.reset(
- new CloudPolicyProvider(
- ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
- this,
- POLICY_LEVEL_MANDATORY));
- recommended_policy_provider_.reset(
- new CloudPolicyProvider(
- ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
- this,
- POLICY_LEVEL_RECOMMENDED));
-}
-
-CloudPolicyCache::~CloudPolicyCache() {
- FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
- observer_list_, OnProviderGoingAway());
-}
-
-void CloudPolicyCache::LoadFromFile() {
- // TODO(jkummerow): This method is doing file IO during browser startup. In
- // the long run it would be better to delay this until the FILE thread exists.
- if (!file_util::PathExists(backing_file_path_) || initialization_complete_) {
- return;
- }
-
- // Read the protobuf from the file.
- std::string data;
- if (!file_util::ReadFileToString(backing_file_path_, &data)) {
- LOG(WARNING) << "Failed to read policy data from "
- << backing_file_path_.value();
- return;
- }
-
- em::CachedCloudPolicyResponse cached_response;
- if (!cached_response.ParseFromArray(data.c_str(), data.size())) {
- LOG(WARNING) << "Failed to parse policy data read from "
- << backing_file_path_.value();
- return;
- }
- base::Time timestamp;
- PolicyMap mandatory_policy;
- PolicyMap recommended_policy;
- is_unmanaged_ = cached_response.unmanaged();
- if (is_unmanaged_ || cached_response.has_device_policy())
- timestamp = base::Time::FromTimeT(cached_response.timestamp());
- if (cached_response.has_cloud_policy()) {
- DCHECK(!is_unmanaged_);
- bool ok = DecodePolicyResponse(cached_response.cloud_policy(),
- &mandatory_policy,
- &recommended_policy,
- &timestamp);
- if (!ok) {
- LOG(WARNING) << "Decoding policy data failed.";
- return;
- }
- }
- if (timestamp > base::Time::NowFromSystemTime()) {
- LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value()
- << ", file is from the future.";
- return;
- }
- // Swap in the new policy information.
- if (cached_response.has_cloud_policy()) {
- mandatory_policy_.Swap(&mandatory_policy);
- recommended_policy_.Swap(&recommended_policy);
- has_device_policy_ = false;
- } else if (cached_response.has_device_policy()) {
- scoped_ptr<DictionaryValue> value(
- DecodeDevicePolicy(cached_response.device_policy()));
- device_policy_.reset(value.release());
- has_device_policy_ = true;
- }
- last_policy_refresh_time_ = timestamp;
- initialization_complete_ = true;
-
- FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
- observer_list_, OnUpdatePolicy());
-}
-
-void CloudPolicyCache::SetPolicy(const em::PolicyFetchResponse& policy) {
- DCHECK(CalledOnValidThread());
- bool initialization_was_not_complete = !initialization_complete_;
- is_unmanaged_ = false;
- last_policy_refresh_time_ = base::Time::NowFromSystemTime();
- base::Time timestamp;
- PolicyMap mandatory_policy;
- PolicyMap recommended_policy;
- bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy,
- &timestamp);
- if (!ok)
- return;
-
- const bool new_policy_differs =
- !mandatory_policy_.Equals(mandatory_policy) ||
- !recommended_policy_.Equals(recommended_policy);
- mandatory_policy_.Swap(&mandatory_policy);
- recommended_policy_.Swap(&recommended_policy);
- initialization_complete_ = true;
- has_device_policy_ = false;
-
- if (new_policy_differs || initialization_was_not_complete) {
- FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
- observer_list_, OnUpdatePolicy());
- }
-
- if (timestamp > base::Time::NowFromSystemTime() +
- base::TimeDelta::FromMinutes(1)) {
- LOG(WARNING) << "Server returned policy with timestamp from the future, "
- "not persisting to disk.";
- } else {
- em::PolicyFetchResponse* policy_copy = new em::PolicyFetchResponse;
- policy_copy->CopyFrom(policy);
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- new PersistPolicyTask(backing_file_path_, policy_copy, NULL, false));
- }
-}
-
-void CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) {
- DCHECK(CalledOnValidThread());
- bool initialization_was_not_complete = !initialization_complete_;
- is_unmanaged_ = false;
- DictionaryValue* value = DecodeDevicePolicy(policy);
- const bool new_policy_differs = !(value->Equals(device_policy_.get()));
- base::Time now(base::Time::NowFromSystemTime());
- device_policy_.reset(value);
- initialization_complete_ = true;
- last_policy_refresh_time_ = now;
- has_device_policy_ = true;
-
- if (new_policy_differs || initialization_was_not_complete) {
- FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
- observer_list_, OnUpdatePolicy());
- }
-
- em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse;
- policy_copy->CopyFrom(policy);
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- new PersistPolicyTask(backing_file_path_, NULL, policy_copy, false));
-}
-
-ConfigurationPolicyProvider* CloudPolicyCache::GetManagedPolicyProvider() {
- DCHECK(CalledOnValidThread());
- return managed_policy_provider_.get();
-}
-
-ConfigurationPolicyProvider* CloudPolicyCache::GetRecommendedPolicyProvider() {
- DCHECK(CalledOnValidThread());
- return recommended_policy_provider_.get();
-}
-
-void CloudPolicyCache::SetUnmanaged() {
- DCHECK(CalledOnValidThread());
- is_unmanaged_ = true;
- mandatory_policy_.Clear();
- recommended_policy_.Clear();
- device_policy_.reset(new DictionaryValue);
- last_policy_refresh_time_ = base::Time::NowFromSystemTime();
-
- FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
- observer_list_, OnUpdatePolicy());
-
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- new PersistPolicyTask(backing_file_path_, NULL, NULL, true));
-}
-
-// static
-bool CloudPolicyCache::DecodePolicyResponse(
- const em::PolicyFetchResponse& policy_response,
- PolicyMap* mandatory,
- PolicyMap* recommended,
- base::Time* timestamp) {
- std::string data = policy_response.policy_data();
-
- em::PolicyData policy_data;
- if (!policy_data.ParseFromString(data)) {
- LOG(WARNING) << "Failed to parse PolicyData protobuf.";
- return false;
- }
-
- // TODO(jkummerow): Verify policy_data.device_token(). Needs final
- // specification which token we're actually sending / expecting to get back.
-
- // TODO(jkummerow): Store policy_data.device_name(), if we decide to transfer
- // it from the server to the client.
-
- *timestamp = base::Time::UnixEpoch() +
- base::TimeDelta::FromMilliseconds(policy_data.timestamp());
- em::CloudPolicySettings policy;
- if (!policy.ParseFromString(policy_data.policy_value())) {
- LOG(WARNING) << "Failed to parse CloudPolicySettings protobuf.";
- return false;
- }
- DecodePolicy(policy, mandatory, recommended);
- return true;
-}
-
-// static
-bool CloudPolicyCache::VerifySignature(
- const std::string& signature,
- const std::string& data,
- const RepeatedPtrField<std::string>& certificate_chain) {
- // TODO(jkummerow): Implement this. Non-trivial because we want to do it
- // for all platforms -> it's enough work to deserve its own CL.
- // Don't forget to also verify the hostname of the server against the cert.
- return true;
-}
-
-// static
-Value* CloudPolicyCache::DecodeIntegerValue(google::protobuf::int64 value) {
- if (value < std::numeric_limits<int>::min() ||
- value > std::numeric_limits<int>::max()) {
- LOG(WARNING) << "Integer value " << value
- << " out of numeric limits, ignoring.";
- return NULL;
- }
-
- return Value::CreateIntegerValue(static_cast<int>(value));
-}
-
-// static
-Value* CloudPolicyCache::DecodeValue(const em::GenericValue& value) {
- if (!value.has_value_type())
- return NULL;
-
- switch (value.value_type()) {
- case em::GenericValue::VALUE_TYPE_BOOL:
- if (value.has_bool_value())
- return Value::CreateBooleanValue(value.bool_value());
- return NULL;
- case em::GenericValue::VALUE_TYPE_INT64:
- if (value.has_int64_value())
- return DecodeIntegerValue(value.int64_value());
- return NULL;
- case em::GenericValue::VALUE_TYPE_STRING:
- if (value.has_string_value())
- return Value::CreateStringValue(value.string_value());
- return NULL;
- case em::GenericValue::VALUE_TYPE_DOUBLE:
- if (value.has_double_value())
- return Value::CreateDoubleValue(value.double_value());
- return NULL;
- case em::GenericValue::VALUE_TYPE_BYTES:
- if (value.has_bytes_value()) {
- std::string bytes = value.bytes_value();
- return BinaryValue::CreateWithCopiedBuffer(bytes.c_str(), bytes.size());
- }
- return NULL;
- case em::GenericValue::VALUE_TYPE_BOOL_ARRAY: {
- ListValue* list = new ListValue;
- RepeatedField<bool>::const_iterator i;
- for (i = value.bool_array().begin(); i != value.bool_array().end(); ++i)
- list->Append(Value::CreateBooleanValue(*i));
- return list;
- }
- case em::GenericValue::VALUE_TYPE_INT64_ARRAY: {
- ListValue* list = new ListValue;
- RepeatedField<google::protobuf::int64>::const_iterator i;
- for (i = value.int64_array().begin();
- i != value.int64_array().end(); ++i) {
- Value* int_value = DecodeIntegerValue(*i);
- if (int_value)
- list->Append(int_value);
- }
- return list;
- }
- case em::GenericValue::VALUE_TYPE_STRING_ARRAY: {
- ListValue* list = new ListValue;
- RepeatedPtrField<std::string>::const_iterator i;
- for (i = value.string_array().begin();
- i != value.string_array().end(); ++i)
- list->Append(Value::CreateStringValue(*i));
- return list;
- }
- case em::GenericValue::VALUE_TYPE_DOUBLE_ARRAY: {
- ListValue* list = new ListValue;
- RepeatedField<double>::const_iterator i;
- for (i = value.double_array().begin();
- i != value.double_array().end(); ++i)
- list->Append(Value::CreateDoubleValue(*i));
- return list;
- }
- default:
- NOTREACHED() << "Unhandled value type";
- }
-
- return NULL;
-}
-
-// static
-DictionaryValue* CloudPolicyCache::DecodeDevicePolicy(
- const em::DevicePolicyResponse& policy) {
- DictionaryValue* result = new DictionaryValue;
- RepeatedPtrField<em::DevicePolicySetting>::const_iterator setting;
- for (setting = policy.setting().begin();
- setting != policy.setting().end();
- ++setting) {
- // Wrong policy key? Skip.
- if (setting->policy_key().compare(kChromeDevicePolicySettingKey) != 0)
- continue;
-
- // No policy value? Skip.
- if (!setting->has_policy_value())
- continue;
-
- // Iterate through all the name-value pairs wrapped in |setting|.
- const em::GenericSetting& policy_value(setting->policy_value());
- RepeatedPtrField<em::GenericNamedValue>::const_iterator named_value;
- for (named_value = policy_value.named_value().begin();
- named_value != policy_value.named_value().end();
- ++named_value) {
- if (named_value->has_value()) {
- Value* decoded_value =
- CloudPolicyCache::DecodeValue(named_value->value());
- if (decoded_value)
- result->Set(named_value->name(), decoded_value);
- }
- }
- }
- return result;
-}
-
-} // namespace policy
diff --git a/chrome/browser/policy/cloud_policy_cache.h b/chrome/browser/policy/cloud_policy_cache.h
deleted file mode 100644
index 3f303b1..0000000
--- a/chrome/browser/policy/cloud_policy_cache.h
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_
-#define CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_
-
-#include <string>
-
-#include "base/file_path.h"
-#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/observer_list.h"
-#include "base/threading/non_thread_safe.h"
-#include "base/time.h"
-#include "chrome/browser/policy/configuration_policy_provider.h"
-#include "chrome/browser/policy/policy_map.h"
-#include "chrome/browser/policy/proto/device_management_backend.pb.h"
-#include "policy/configuration_policy_type.h"
-
-class DictionaryValue;
-class ListValue;
-class Value;
-
-using google::protobuf::RepeatedPtrField;
-
-namespace policy {
-
-namespace em = enterprise_management;
-
-// Keeps the authoritative copy of cloud policy information as read from the
-// persistence file or determined by the policy backend. The cache doesn't talk
-// to the service directly, but receives updated policy information through
-// SetPolicy() calls, which is then persisted and decoded into the internal
-// Value representation chrome uses.
-class CloudPolicyCache : public base::NonThreadSafe {
- public:
- // Used to distinguish mandatory from recommended policies.
- enum PolicyLevel {
- // Policy is forced upon the user and should always take effect.
- POLICY_LEVEL_MANDATORY,
- // The value is just a recommendation that the user may override.
- POLICY_LEVEL_RECOMMENDED,
- };
-
- explicit CloudPolicyCache(const FilePath& backing_file_path);
- ~CloudPolicyCache();
-
- // Loads policy information from the backing file. Non-existing or erroneous
- // cache files are ignored.
- void LoadFromFile();
-
- // Resets the policy information.
- void SetPolicy(const em::PolicyFetchResponse& policy);
- void SetDevicePolicy(const em::DevicePolicyResponse& policy);
-
- ConfigurationPolicyProvider* GetManagedPolicyProvider();
- ConfigurationPolicyProvider* GetRecommendedPolicyProvider();
-
- void SetUnmanaged();
- bool is_unmanaged() const {
- return is_unmanaged_;
- }
-
- // Returns the time at which the policy was last fetched.
- base::Time last_policy_refresh_time() const {
- return last_policy_refresh_time_;
- }
-
- // Returns true if this cache holds (old-style) device policy that should be
- // given preference over (new-style) mandatory/recommended policy.
- bool has_device_policy() const {
- return has_device_policy_;
- }
-
- private:
- class CloudPolicyProvider;
-
- friend class CloudPolicyCacheTest;
- friend class DeviceManagementPolicyCacheTest;
- friend class DeviceManagementPolicyCacheDecodeTest;
-
- // Decodes a CloudPolicyResponse into two (ConfigurationPolicyType -> Value*)
- // maps and a timestamp. Also performs verification, returns NULL if any
- // check fails.
- static bool DecodePolicyResponse(
- const em::PolicyFetchResponse& policy_response,
- PolicyMap* mandatory,
- PolicyMap* recommended,
- base::Time* timestamp);
-
- // Returns true if |certificate_chain| is trusted and a |signature| created
- // from it matches |data|.
- static bool VerifySignature(
- const std::string& signature,
- const std::string& data,
- const RepeatedPtrField<std::string>& certificate_chain);
-
- // Decodes an int64 value. Checks whether the passed value fits the numeric
- // limits of the value representation. Returns a value (ownership is
- // transferred to the caller) on success, NULL on failure.
- static Value* DecodeIntegerValue(google::protobuf::int64 value);
-
- // Decode a GenericValue message to the Value representation used internally.
- // Returns NULL if |value| is invalid (i.e. contains no actual value).
- static Value* DecodeValue(const em::GenericValue& value);
-
- // Decodes a policy message and returns it in Value representation. Ownership
- // of the returned dictionary is transferred to the caller.
- static DictionaryValue* DecodeDevicePolicy(
- const em::DevicePolicyResponse& response);
-
- // The file in which we store a cached version of the policy information.
- const FilePath backing_file_path_;
-
- // Policy key-value information.
- PolicyMap mandatory_policy_;
- PolicyMap recommended_policy_;
- scoped_ptr<DictionaryValue> device_policy_;
-
- // Whether initialization has been completed. This is the case when we have
- // valid policy, learned that the device is unmanaged or ran into
- // unrecoverable errors.
- bool initialization_complete_;
-
- // Whether the the server has indicated this device is unmanaged.
- bool is_unmanaged_;
-
- // Tracks whether the cache currently stores |device_policy_| that should be
- // given preference over |mandatory_policy_| and |recommended_policy_|.
- bool has_device_policy_;
-
- // The time at which the policy was last refreshed.
- base::Time last_policy_refresh_time_;
-
- // Policy providers.
- scoped_ptr<ConfigurationPolicyProvider> managed_policy_provider_;
- scoped_ptr<ConfigurationPolicyProvider> recommended_policy_provider_;
-
- // Provider observers that are registered with this cache's providers.
- ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_;
-
- DISALLOW_COPY_AND_ASSIGN(CloudPolicyCache);
-};
-
-} // namespace policy
-
-#endif // CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_
diff --git a/chrome/browser/policy/cloud_policy_cache_base.cc b/chrome/browser/policy/cloud_policy_cache_base.cc
new file mode 100644
index 0000000..8af7533
--- /dev/null
+++ b/chrome/browser/policy/cloud_policy_cache_base.cc
@@ -0,0 +1,155 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/cloud_policy_cache_base.h"
+
+#include <string>
+
+#include "base/logging.h"
+#include "base/values.h"
+#include "chrome/browser/policy/configuration_policy_pref_store.h"
+
+namespace policy {
+
+// A thin ConfigurationPolicyProvider implementation sitting on top of
+// CloudPolicyCacheBase for hooking up with ConfigurationPolicyPrefStore.
+class CloudPolicyCacheBase::CloudPolicyProvider
+ : public ConfigurationPolicyProvider {
+ public:
+ CloudPolicyProvider(const PolicyDefinitionList* policy_list,
+ CloudPolicyCacheBase* cache,
+ CloudPolicyCacheBase::PolicyLevel level)
+ : ConfigurationPolicyProvider(policy_list),
+ cache_(cache),
+ level_(level) {}
+ virtual ~CloudPolicyProvider() {}
+
+ virtual bool Provide(ConfigurationPolicyStoreInterface* store) {
+ if (level_ == POLICY_LEVEL_MANDATORY)
+ ApplyPolicyMap(&cache_->mandatory_policy_, store);
+ else if (level_ == POLICY_LEVEL_RECOMMENDED)
+ ApplyPolicyMap(&cache_->recommended_policy_, store);
+ return true;
+ }
+
+ virtual bool IsInitializationComplete() const {
+ return cache_->initialization_complete_;
+ }
+
+ virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) {
+ cache_->observer_list_.AddObserver(observer);
+ }
+ virtual void RemoveObserver(ConfigurationPolicyProvider::Observer* observer) {
+ cache_->observer_list_.RemoveObserver(observer);
+ }
+
+ private:
+ // The underlying policy cache.
+ CloudPolicyCacheBase* cache_;
+ // Policy level this provider will handle.
+ CloudPolicyCacheBase::PolicyLevel level_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloudPolicyProvider);
+};
+
+CloudPolicyCacheBase::CloudPolicyCacheBase()
+ : initialization_complete_(false),
+ is_unmanaged_(false) {
+ managed_policy_provider_.reset(
+ new CloudPolicyProvider(
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
+ this,
+ POLICY_LEVEL_MANDATORY));
+ recommended_policy_provider_.reset(
+ new CloudPolicyProvider(
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
+ this,
+ POLICY_LEVEL_RECOMMENDED));
+}
+
+CloudPolicyCacheBase::~CloudPolicyCacheBase() {
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
+ observer_list_, OnProviderGoingAway());
+}
+
+bool CloudPolicyCacheBase::SetPolicyInternal(
+ const em::PolicyFetchResponse& policy,
+ base::Time* timestamp,
+ bool check_for_timestamp_validity) {
+ DCHECK(CalledOnValidThread());
+ bool initialization_was_not_complete = !initialization_complete_;
+ is_unmanaged_ = false;
+ PolicyMap mandatory_policy;
+ PolicyMap recommended_policy;
+ base::Time temp_timestamp;
+ bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy,
+ &temp_timestamp);
+ if (!ok) {
+ LOG(WARNING) << "Decoding policy data failed.";
+ return false;
+ }
+ if (timestamp) {
+ *timestamp = temp_timestamp;
+ }
+ if (check_for_timestamp_validity &&
+ temp_timestamp > base::Time::NowFromSystemTime()) {
+ LOG(WARNING) << "Rejected policy data, file is from the future.";
+ return false;
+ }
+
+ const bool new_policy_differs =
+ !mandatory_policy_.Equals(mandatory_policy) ||
+ !recommended_policy_.Equals(recommended_policy);
+ mandatory_policy_.Swap(&mandatory_policy);
+ recommended_policy_.Swap(&recommended_policy);
+ initialization_complete_ = true;
+
+ if (new_policy_differs || initialization_was_not_complete) {
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
+ observer_list_, OnUpdatePolicy());
+ }
+ return true;
+}
+
+void CloudPolicyCacheBase::SetUnmanagedInternal(const base::Time& timestamp) {
+ is_unmanaged_ = true;
+ initialization_complete_ = true;
+ mandatory_policy_.Clear();
+ recommended_policy_.Clear();
+ last_policy_refresh_time_ = timestamp;
+
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
+ observer_list_, OnUpdatePolicy());
+}
+
+ConfigurationPolicyProvider* CloudPolicyCacheBase::GetManagedPolicyProvider() {
+ DCHECK(CalledOnValidThread());
+ return managed_policy_provider_.get();
+}
+
+ConfigurationPolicyProvider*
+ CloudPolicyCacheBase::GetRecommendedPolicyProvider() {
+ DCHECK(CalledOnValidThread());
+ return recommended_policy_provider_.get();
+}
+
+bool CloudPolicyCacheBase::DecodePolicyResponse(
+ const em::PolicyFetchResponse& policy_response,
+ PolicyMap* mandatory,
+ PolicyMap* recommended,
+ base::Time* timestamp) {
+ std::string data = policy_response.policy_data();
+ em::PolicyData policy_data;
+ if (!policy_data.ParseFromString(data)) {
+ LOG(WARNING) << "Failed to parse PolicyData protobuf.";
+ return false;
+ }
+ if (timestamp) {
+ *timestamp = base::Time::UnixEpoch() +
+ base::TimeDelta::FromMilliseconds(policy_data.timestamp());
+ }
+ return DecodePolicyData(policy_data, mandatory, recommended);
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/cloud_policy_cache_base.h b/chrome/browser/policy/cloud_policy_cache_base.h
new file mode 100644
index 0000000..44cfd87
--- /dev/null
+++ b/chrome/browser/policy/cloud_policy_cache_base.h
@@ -0,0 +1,128 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_BASE_H_
+#define CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_BASE_H_
+#pragma once
+
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+#include "base/threading/non_thread_safe.h"
+#include "base/time.h"
+#include "chrome/browser/policy/configuration_policy_provider.h"
+#include "chrome/browser/policy/policy_map.h"
+#include "chrome/browser/policy/proto/device_management_backend.pb.h"
+
+namespace policy {
+
+class PolicyMap;
+
+namespace em = enterprise_management;
+
+// Caches policy information, as set by calls to |SetPolicy()|, persists
+// it to disk or session_manager (depending on subclass implementation),
+// and makes it available via policy providers.
+class CloudPolicyCacheBase : public base::NonThreadSafe {
+ public:
+ // Used to distinguish mandatory from recommended policies.
+ enum PolicyLevel {
+ // Policy is forced upon the user and should always take effect.
+ POLICY_LEVEL_MANDATORY,
+ // The value is just a recommendation that the user may override.
+ POLICY_LEVEL_RECOMMENDED,
+ };
+
+ CloudPolicyCacheBase();
+ virtual ~CloudPolicyCacheBase();
+
+ // Loads persisted policy information.
+ virtual void Load() = 0;
+
+ // Resets the policy information.
+ virtual void SetPolicy(const em::PolicyFetchResponse& policy) = 0;
+
+ ConfigurationPolicyProvider* GetManagedPolicyProvider();
+ ConfigurationPolicyProvider* GetRecommendedPolicyProvider();
+
+ virtual void SetUnmanaged() = 0;
+ bool is_unmanaged() const {
+ return is_unmanaged_;
+ }
+
+ // Returns the time at which the policy was last fetched.
+ base::Time last_policy_refresh_time() const {
+ return last_policy_refresh_time_;
+ }
+
+ protected:
+ // Decodes the given |policy| using |DecodePolicyResponse()|, applies the
+ // contents to |{mandatory,recommended}_policy_|, and notifies observers.
+ // |timestamp| returns the timestamp embedded in |policy|, callers can pass
+ // NULL if they don't care. |check_for_timestamp_validity| tells this method
+ // to discard policy data with a timestamp from the future.
+ // Returns true upon success.
+ bool SetPolicyInternal(const em::PolicyFetchResponse& policy,
+ base::Time* timestamp,
+ bool check_for_timestamp_validity);
+
+ void SetUnmanagedInternal(const base::Time& timestamp);
+
+ // Decodes |policy_data|, populating |mandatory| and |recommended| with
+ // the results.
+ virtual bool DecodePolicyData(const em::PolicyData& policy_data,
+ PolicyMap* mandatory,
+ PolicyMap* recommended) = 0;
+
+ // Decodes a PolicyFetchResponse into two PolicyMaps and a timestamp.
+ // Also performs verification, returns NULL if any check fails.
+ bool DecodePolicyResponse(const em::PolicyFetchResponse& policy_response,
+ PolicyMap* mandatory,
+ PolicyMap* recommended,
+ base::Time* timestamp);
+
+ // See comment for |initialization_complete_|.
+ bool initialization_complete() {
+ return initialization_complete_;
+ }
+
+ void set_last_policy_refresh_time(base::Time timestamp) {
+ last_policy_refresh_time_ = timestamp;
+ }
+
+ private:
+ class CloudPolicyProvider;
+
+ friend class DevicePolicyCacheTest;
+ friend class UserPolicyCacheTest;
+
+ // Policy key-value information.
+ PolicyMap mandatory_policy_;
+ PolicyMap recommended_policy_;
+
+ // Policy providers.
+ scoped_ptr<ConfigurationPolicyProvider> managed_policy_provider_;
+ scoped_ptr<ConfigurationPolicyProvider> recommended_policy_provider_;
+
+ // The time at which the policy was last refreshed. Is updated both upon
+ // successful and unsuccessful refresh attempts.
+ base::Time last_policy_refresh_time_;
+
+ // Whether initialization has been completed. This is the case when we have
+ // valid policy, learned that the device is unmanaged or ran into
+ // unrecoverable errors.
+ bool initialization_complete_;
+
+ // Whether the the server has indicated this device is unmanaged.
+ bool is_unmanaged_;
+
+ // Provider observers that are registered with this cache's providers.
+ ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloudPolicyCacheBase);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_BASE_H_
diff --git a/chrome/browser/policy/cloud_policy_cache_unittest.cc b/chrome/browser/policy/cloud_policy_cache_unittest.cc
deleted file mode 100644
index d0bf31a..0000000
--- a/chrome/browser/policy/cloud_policy_cache_unittest.cc
+++ /dev/null
@@ -1,651 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/policy/cloud_policy_cache.h"
-
-#include <limits>
-#include <string>
-
-#include "base/file_util.h"
-#include "base/memory/scoped_temp_dir.h"
-#include "base/message_loop.h"
-#include "base/values.h"
-#include "chrome/browser/policy/configuration_policy_provider.h"
-#include "chrome/browser/policy/proto/cloud_policy.pb.h"
-#include "chrome/browser/policy/proto/device_management_backend.pb.h"
-// TODO(jkummerow): remove this import when removing old DMPC test cases.
-#include "chrome/browser/policy/proto/device_management_constants.h"
-#include "chrome/browser/policy/proto/device_management_local.pb.h"
-#include "content/browser/browser_thread.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace policy {
-
-// Decodes a CloudPolicySettings object into two maps with mandatory and
-// recommended settings, respectively. The implementation is generated code
-// in policy/cloud_policy_generated.cc.
-void DecodePolicy(const em::CloudPolicySettings& policy,
- PolicyMap* mandatory, PolicyMap* recommended);
-
-// The implementations of these methods are in cloud_policy_generated.cc.
-Value* DecodeIntegerValue(google::protobuf::int64 value);
-ListValue* DecodeStringList(const em::StringList& string_list);
-
-class MockConfigurationPolicyProviderObserver
- : public ConfigurationPolicyProvider::Observer {
- public:
- MockConfigurationPolicyProviderObserver() {}
- virtual ~MockConfigurationPolicyProviderObserver() {}
- MOCK_METHOD0(OnUpdatePolicy, void());
- void OnProviderGoingAway() {}
-};
-
-// Tests the device management policy cache.
-class CloudPolicyCacheTest : public testing::Test {
- protected:
- CloudPolicyCacheTest()
- : loop_(MessageLoop::TYPE_UI),
- ui_thread_(BrowserThread::UI, &loop_),
- file_thread_(BrowserThread::FILE, &loop_) {}
-
- void SetUp() {
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- }
-
- void TearDown() {
- loop_.RunAllPending();
- }
-
- // Creates a (signed) PolicyFetchResponse setting the given |homepage| and
- // featuring the given |timestamp| (as issued by the server).
- // Mildly hacky special feature: pass an empty string as |homepage| to get
- // a completely empty policy.
- em::PolicyFetchResponse* CreateHomepagePolicy(
- const std::string& homepage,
- const base::Time& timestamp,
- const em::PolicyOptions::PolicyMode policy_mode) {
- em::PolicyData signed_response;
- if (homepage != "") {
- em::CloudPolicySettings settings;
- em::HomepageLocationProto* homepagelocation_proto =
- settings.mutable_homepagelocation();
- homepagelocation_proto->set_homepagelocation(homepage);
- homepagelocation_proto->mutable_policy_options()->set_mode(policy_mode);
- EXPECT_TRUE(
- settings.SerializeToString(signed_response.mutable_policy_value()));
- }
- signed_response.set_timestamp(
- (timestamp - base::Time::UnixEpoch()).InMilliseconds());
- std::string serialized_signed_response;
- EXPECT_TRUE(signed_response.SerializeToString(&serialized_signed_response));
-
- em::PolicyFetchResponse* response = new em::PolicyFetchResponse;
- response->set_policy_data(serialized_signed_response);
- // TODO(jkummerow): Set proper new_public_key and signature (when
- // implementing support for signature verification).
- response->set_policy_data_signature("TODO");
- response->set_new_public_key("TODO");
- return response;
- }
-
- void WritePolicy(const em::PolicyFetchResponse& policy) {
- std::string data;
- em::CachedCloudPolicyResponse cached_policy;
- cached_policy.mutable_cloud_policy()->CopyFrom(policy);
- EXPECT_TRUE(cached_policy.SerializeToString(&data));
- int size = static_cast<int>(data.size());
- EXPECT_EQ(size, file_util::WriteFile(test_file(), data.c_str(), size));
- }
-
- // Takes ownership of |policy_response|.
- void SetPolicy(CloudPolicyCache* cache,
- em::PolicyFetchResponse* policy_response,
- bool expect_changed_policy) {
- scoped_ptr<em::PolicyFetchResponse> policy(policy_response);
- ConfigurationPolicyObserverRegistrar registrar;
- registrar.Init(cache->GetManagedPolicyProvider(), &observer);
- if (expect_changed_policy)
- EXPECT_CALL(observer, OnUpdatePolicy()).Times(1);
- else
- EXPECT_CALL(observer, OnUpdatePolicy()).Times(0);
- cache->SetPolicy(*policy);
- testing::Mock::VerifyAndClearExpectations(&observer);
- }
-
- FilePath test_file() {
- return temp_dir_.path().AppendASCII("CloudPolicyCacheTest");
- }
-
- const PolicyMap& mandatory_policy(const CloudPolicyCache& cache) {
- return cache.mandatory_policy_;
- }
-
- const PolicyMap& recommended_policy(const CloudPolicyCache& cache) {
- return cache.recommended_policy_;
- }
-
- MessageLoop loop_;
- MockConfigurationPolicyProviderObserver observer;
-
- private:
- ScopedTempDir temp_dir_;
- BrowserThread ui_thread_;
- BrowserThread file_thread_;
-};
-
-TEST_F(CloudPolicyCacheTest, DecodePolicy) {
- em::CloudPolicySettings settings;
- settings.mutable_homepagelocation()->set_homepagelocation("chromium.org");
- settings.mutable_javascriptenabled()->set_javascriptenabled(true);
- settings.mutable_javascriptenabled()->mutable_policy_options()->set_mode(
- em::PolicyOptions::MANDATORY);
- settings.mutable_policyrefreshrate()->set_policyrefreshrate(5);
- settings.mutable_policyrefreshrate()->mutable_policy_options()->set_mode(
- em::PolicyOptions::RECOMMENDED);
- PolicyMap mandatory_policy;
- PolicyMap recommended_policy;
- DecodePolicy(settings, &mandatory_policy, &recommended_policy);
- PolicyMap mandatory;
- mandatory.Set(kPolicyHomepageLocation,
- Value::CreateStringValue("chromium.org"));
- mandatory.Set(kPolicyJavascriptEnabled, Value::CreateBooleanValue(true));
- PolicyMap recommended;
- recommended.Set(kPolicyPolicyRefreshRate, Value::CreateIntegerValue(5));
- EXPECT_TRUE(mandatory.Equals(mandatory_policy));
- EXPECT_TRUE(recommended.Equals(recommended_policy));
-}
-
-TEST_F(CloudPolicyCacheTest, DecodeIntegerValue) {
- const int min = std::numeric_limits<int>::min();
- const int max = std::numeric_limits<int>::max();
- scoped_ptr<Value> value(
- DecodeIntegerValue(static_cast<google::protobuf::int64>(42)));
- ASSERT_TRUE(value.get());
- FundamentalValue expected_42(42);
- EXPECT_TRUE(value->Equals(&expected_42));
- value.reset(
- DecodeIntegerValue(static_cast<google::protobuf::int64>(min - 1LL)));
- EXPECT_EQ(NULL, value.get());
- value.reset(DecodeIntegerValue(static_cast<google::protobuf::int64>(min)));
- ASSERT_TRUE(value.get());
- FundamentalValue expected_min(min);
- EXPECT_TRUE(value->Equals(&expected_min));
- value.reset(
- DecodeIntegerValue(static_cast<google::protobuf::int64>(max + 1LL)));
- EXPECT_EQ(NULL, value.get());
- value.reset(DecodeIntegerValue(static_cast<google::protobuf::int64>(max)));
- ASSERT_TRUE(value.get());
- FundamentalValue expected_max(max);
- EXPECT_TRUE(value->Equals(&expected_max));
-}
-
-TEST_F(CloudPolicyCacheTest, DecodeStringList) {
- em::StringList string_list;
- string_list.add_entries("ponies");
- string_list.add_entries("more ponies");
- scoped_ptr<ListValue> decoded(DecodeStringList(string_list));
- ListValue expected;
- expected.Append(Value::CreateStringValue("ponies"));
- expected.Append(Value::CreateStringValue("more ponies"));
- EXPECT_TRUE(decoded->Equals(&expected));
-}
-
-TEST_F(CloudPolicyCacheTest, Empty) {
- CloudPolicyCache cache(test_file());
- PolicyMap empty;
- EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
- EXPECT_TRUE(empty.Equals(recommended_policy(cache)));
- EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
-}
-
-TEST_F(CloudPolicyCacheTest, LoadNoFile) {
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- PolicyMap empty;
- EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
- EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
-}
-
-TEST_F(CloudPolicyCacheTest, RejectFuture) {
- scoped_ptr<em::PolicyFetchResponse> policy_response(
- CreateHomepagePolicy("", base::Time::NowFromSystemTime() +
- base::TimeDelta::FromMinutes(5),
- em::PolicyOptions::MANDATORY));
- WritePolicy(*policy_response);
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- PolicyMap empty;
- EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
- EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
-}
-
-TEST_F(CloudPolicyCacheTest, LoadWithFile) {
- scoped_ptr<em::PolicyFetchResponse> policy_response(
- CreateHomepagePolicy("", base::Time::NowFromSystemTime(),
- em::PolicyOptions::MANDATORY));
- WritePolicy(*policy_response);
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- PolicyMap empty;
- EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
- EXPECT_NE(base::Time(), cache.last_policy_refresh_time());
- EXPECT_GE(base::Time::Now(), cache.last_policy_refresh_time());
-}
-
-TEST_F(CloudPolicyCacheTest, LoadWithData) {
- scoped_ptr<em::PolicyFetchResponse> policy(
- CreateHomepagePolicy("http://www.example.com",
- base::Time::NowFromSystemTime(),
- em::PolicyOptions::MANDATORY));
- WritePolicy(*policy);
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- PolicyMap expected;
- expected.Set(kPolicyHomepageLocation,
- Value::CreateStringValue("http://www.example.com"));
- EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
-}
-
-TEST_F(CloudPolicyCacheTest, SetPolicy) {
- CloudPolicyCache cache(test_file());
- em::PolicyFetchResponse* policy =
- CreateHomepagePolicy("http://www.example.com",
- base::Time::NowFromSystemTime(),
- em::PolicyOptions::MANDATORY);
- SetPolicy(&cache, policy, true);
- em::PolicyFetchResponse* policy2 =
- CreateHomepagePolicy("http://www.example.com",
- base::Time::NowFromSystemTime(),
- em::PolicyOptions::MANDATORY);
- SetPolicy(&cache, policy2, false);
- PolicyMap expected;
- expected.Set(kPolicyHomepageLocation,
- Value::CreateStringValue("http://www.example.com"));
- PolicyMap empty;
- EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
- EXPECT_TRUE(empty.Equals(recommended_policy(cache)));
- policy = CreateHomepagePolicy("http://www.example.com",
- base::Time::NowFromSystemTime(),
- em::PolicyOptions::RECOMMENDED);
- SetPolicy(&cache, policy, true);
- EXPECT_TRUE(expected.Equals(recommended_policy(cache)));
- EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
-}
-
-TEST_F(CloudPolicyCacheTest, ResetPolicy) {
- CloudPolicyCache cache(test_file());
-
- em::PolicyFetchResponse* policy =
- CreateHomepagePolicy("http://www.example.com",
- base::Time::NowFromSystemTime(),
- em::PolicyOptions::MANDATORY);
- SetPolicy(&cache, policy, true);
- PolicyMap expected;
- expected.Set(kPolicyHomepageLocation,
- Value::CreateStringValue("http://www.example.com"));
- EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
-
- em::PolicyFetchResponse* empty_policy =
- CreateHomepagePolicy("", base::Time::NowFromSystemTime(),
- em::PolicyOptions::MANDATORY);
- SetPolicy(&cache, empty_policy, true);
- PolicyMap empty;
- EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
-}
-
-TEST_F(CloudPolicyCacheTest, PersistPolicy) {
- {
- CloudPolicyCache cache(test_file());
- scoped_ptr<em::PolicyFetchResponse> policy(
- CreateHomepagePolicy("http://www.example.com",
- base::Time::NowFromSystemTime(),
- em::PolicyOptions::MANDATORY));
- cache.SetPolicy(*policy);
- }
-
- loop_.RunAllPending();
-
- EXPECT_TRUE(file_util::PathExists(test_file()));
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- PolicyMap expected;
- expected.Set(kPolicyHomepageLocation,
- Value::CreateStringValue("http://www.example.com"));
- EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
-}
-
-TEST_F(CloudPolicyCacheTest, FreshPolicyOverride) {
- scoped_ptr<em::PolicyFetchResponse> policy(
- CreateHomepagePolicy("http://www.example.com",
- base::Time::NowFromSystemTime(),
- em::PolicyOptions::MANDATORY));
- WritePolicy(*policy);
-
- CloudPolicyCache cache(test_file());
- em::PolicyFetchResponse* updated_policy =
- CreateHomepagePolicy("http://www.chromium.org",
- base::Time::NowFromSystemTime(),
- em::PolicyOptions::MANDATORY);
- SetPolicy(&cache, updated_policy, true);
-
- cache.LoadFromFile();
- PolicyMap expected;
- expected.Set(kPolicyHomepageLocation,
- Value::CreateStringValue("http://www.chromium.org"));
- EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
-}
-
-} // namespace policy
-
-// ==================================================================
-// Everything below this line can go when we phase out support for
-// the old (trusted testing/pilot program) policy format.
-
-// This is a (slightly updated) copy of the old
-// device_management_policy_cache_unittest.cc. The new CloudPolicyCache
-// supports the old DMPC's interface for now (until it is phased out), so for
-// this transitional period, we keep these old test cases but apply them to the
-// new implementation (CPC).
-
-namespace policy {
-
-// Wraps base functionaly for the test cases.
-class DeviceManagementPolicyCacheTestBase : public testing::Test {
- protected:
- // Add a string policy setting to a policy response message.
- void AddStringPolicy(em::DevicePolicyResponse* policy,
- const std::string& name,
- const std::string& value) {
- em::DevicePolicySetting* setting = policy->add_setting();
- setting->set_policy_key(kChromeDevicePolicySettingKey);
- em::GenericSetting* policy_value = setting->mutable_policy_value();
- em::GenericNamedValue* named_value = policy_value->add_named_value();
- named_value->set_name(name);
- em::GenericValue* value_container = named_value->mutable_value();
- value_container->set_value_type(em::GenericValue::VALUE_TYPE_STRING);
- value_container->set_string_value(value);
- }
-};
-
-// Tests the device management policy cache.
-class DeviceManagementPolicyCacheTest
- : public DeviceManagementPolicyCacheTestBase {
- protected:
- DeviceManagementPolicyCacheTest()
- : loop_(MessageLoop::TYPE_UI),
- ui_thread_(BrowserThread::UI, &loop_),
- file_thread_(BrowserThread::FILE, &loop_) {}
-
- void SetUp() {
- ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
- }
-
- void TearDown() {
- loop_.RunAllPending();
- }
-
- void WritePolicy(const em::DevicePolicyResponse& policy,
- const base::Time& timestamp) {
- std::string data;
- em::CachedCloudPolicyResponse cached_policy;
- cached_policy.mutable_device_policy()->CopyFrom(policy);
- cached_policy.set_timestamp(timestamp.ToTimeT());
- EXPECT_TRUE(cached_policy.SerializeToString(&data));
- int size = static_cast<int>(data.size());
- EXPECT_EQ(size, file_util::WriteFile(test_file(), data.c_str(), size));
- }
-
- FilePath test_file() {
- return temp_dir_.path().AppendASCII("DeviceManagementPolicyCacheTest");
- }
-
- const DictionaryValue* device_policy(const CloudPolicyCache& cache) {
- return cache.device_policy_.get();
- }
-
- MessageLoop loop_;
-
- private:
- ScopedTempDir temp_dir_;
- BrowserThread ui_thread_;
- BrowserThread file_thread_;
-};
-
-TEST_F(DeviceManagementPolicyCacheTest, Empty) {
- CloudPolicyCache cache(test_file());
- DictionaryValue empty;
- EXPECT_TRUE(empty.Equals(device_policy(cache)));
- EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, LoadNoFile) {
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- DictionaryValue empty;
- EXPECT_TRUE(empty.Equals(device_policy(cache)));
- EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, RejectFuture) {
- em::DevicePolicyResponse policy_response;
- WritePolicy(policy_response, base::Time::NowFromSystemTime() +
- base::TimeDelta::FromMinutes(5));
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- DictionaryValue empty;
- EXPECT_TRUE(empty.Equals(device_policy(cache)));
- EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, LoadWithFile) {
- em::DevicePolicyResponse policy_response;
- WritePolicy(policy_response, base::Time::NowFromSystemTime());
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- DictionaryValue empty;
- EXPECT_TRUE(empty.Equals(device_policy(cache)));
- EXPECT_NE(base::Time(), cache.last_policy_refresh_time());
- EXPECT_GE(base::Time::Now(), cache.last_policy_refresh_time());
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, LoadWithData) {
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- WritePolicy(policy, base::Time::NowFromSystemTime());
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.example.com"));
- EXPECT_TRUE(expected.Equals(device_policy(cache)));
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, SetDevicePolicy) {
- CloudPolicyCache cache(test_file());
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- cache.SetDevicePolicy(policy);
- em::DevicePolicyResponse policy2;
- AddStringPolicy(&policy2, "HomepageLocation", "http://www.example.com");
- cache.SetDevicePolicy(policy2); // Does not notify observers.
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.example.com"));
- EXPECT_TRUE(expected.Equals(device_policy(cache)));
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, ResetPolicy) {
- CloudPolicyCache cache(test_file());
-
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- cache.SetDevicePolicy(policy);
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.example.com"));
- EXPECT_TRUE(expected.Equals(device_policy(cache)));
-
- cache.SetDevicePolicy(em::DevicePolicyResponse());
- DictionaryValue empty;
- EXPECT_TRUE(empty.Equals(device_policy(cache)));
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, PersistPolicy) {
- {
- CloudPolicyCache cache(test_file());
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- cache.SetDevicePolicy(policy);
- }
-
- loop_.RunAllPending();
-
- EXPECT_TRUE(file_util::PathExists(test_file()));
- CloudPolicyCache cache(test_file());
- cache.LoadFromFile();
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.example.com"));
- EXPECT_TRUE(expected.Equals(device_policy(cache)));
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, FreshPolicyOverride) {
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- WritePolicy(policy, base::Time::NowFromSystemTime());
-
- CloudPolicyCache cache(test_file());
- em::DevicePolicyResponse updated_policy;
- AddStringPolicy(&updated_policy, "HomepageLocation",
- "http://www.chromium.org");
- cache.SetDevicePolicy(updated_policy);
-
- cache.LoadFromFile();
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.chromium.org"));
- EXPECT_TRUE(expected.Equals(device_policy(cache)));
-}
-
-// Tests proper decoding of policy values.
-class DeviceManagementPolicyCacheDecodeTest
- : public DeviceManagementPolicyCacheTestBase {
- protected:
- void DecodeAndCheck(Value* expected_value_ptr) {
- scoped_ptr<Value> expected_value(expected_value_ptr);
- scoped_ptr<Value> decoded_value(
- CloudPolicyCache::DecodeValue(value_));
- if (expected_value_ptr) {
- ASSERT_TRUE(decoded_value.get());
- EXPECT_TRUE(decoded_value->Equals(expected_value.get()));
- } else {
- ASSERT_FALSE(decoded_value.get());
- }
- }
-
- DictionaryValue* DecodeDevicePolicy(const em::DevicePolicyResponse policy) {
- return CloudPolicyCache::DecodeDevicePolicy(policy);
- }
-
- em::GenericValue value_;
-};
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, Bool) {
- value_.set_value_type(em::GenericValue::VALUE_TYPE_BOOL);
- value_.set_bool_value(true);
- DecodeAndCheck(Value::CreateBooleanValue(true));
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, Int64) {
- value_.set_value_type(em::GenericValue::VALUE_TYPE_INT64);
- value_.set_int64_value(42);
- DecodeAndCheck(Value::CreateIntegerValue(42));
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, Int64Overflow) {
- const int min = std::numeric_limits<int>::min();
- const int max = std::numeric_limits<int>::max();
- value_.set_value_type(em::GenericValue::VALUE_TYPE_INT64);
- value_.set_int64_value(min - 1LL);
- DecodeAndCheck(NULL);
- value_.set_int64_value(max + 1LL);
- DecodeAndCheck(NULL);
- value_.set_int64_value(min);
- DecodeAndCheck(Value::CreateIntegerValue(min));
- value_.set_int64_value(max);
- DecodeAndCheck(Value::CreateIntegerValue(max));
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, String) {
- value_.set_value_type(em::GenericValue::VALUE_TYPE_STRING);
- value_.set_string_value("ponies!");
- DecodeAndCheck(Value::CreateStringValue("ponies!"));
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, Double) {
- value_.set_value_type(em::GenericValue::VALUE_TYPE_DOUBLE);
- value_.set_double_value(0.42L);
- DecodeAndCheck(Value::CreateDoubleValue(0.42L));
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, Bytes) {
- std::string data("binary ponies.");
- value_.set_value_type(em::GenericValue::VALUE_TYPE_BYTES);
- value_.set_bytes_value(data);
- DecodeAndCheck(
- BinaryValue::CreateWithCopiedBuffer(data.c_str(), data.size()));
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, BoolArray) {
- value_.set_value_type(em::GenericValue::VALUE_TYPE_BOOL_ARRAY);
- value_.add_bool_array(false);
- value_.add_bool_array(true);
- ListValue* list = new ListValue;
- list->Append(Value::CreateBooleanValue(false));
- list->Append(Value::CreateBooleanValue(true));
- DecodeAndCheck(list);
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, Int64Array) {
- value_.set_value_type(em::GenericValue::VALUE_TYPE_INT64_ARRAY);
- value_.add_int64_array(42);
- value_.add_int64_array(17);
- ListValue* list = new ListValue;
- list->Append(Value::CreateIntegerValue(42));
- list->Append(Value::CreateIntegerValue(17));
- DecodeAndCheck(list);
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, StringArray) {
- value_.set_value_type(em::GenericValue::VALUE_TYPE_STRING_ARRAY);
- value_.add_string_array("ponies");
- value_.add_string_array("more ponies");
- ListValue* list = new ListValue;
- list->Append(Value::CreateStringValue("ponies"));
- list->Append(Value::CreateStringValue("more ponies"));
- DecodeAndCheck(list);
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, DoubleArray) {
- value_.set_value_type(em::GenericValue::VALUE_TYPE_DOUBLE_ARRAY);
- value_.add_double_array(0.42L);
- value_.add_double_array(0.17L);
- ListValue* list = new ListValue;
- list->Append(Value::CreateDoubleValue(0.42L));
- list->Append(Value::CreateDoubleValue(0.17L));
- DecodeAndCheck(list);
-}
-
-TEST_F(DeviceManagementPolicyCacheDecodeTest, DecodePolicy) {
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- scoped_ptr<Value> decoded(DecodeDevicePolicy(policy));
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.example.com"));
- EXPECT_TRUE(expected.Equals(decoded.get()));
-}
-
-} // namespace policy
diff --git a/chrome/browser/policy/cloud_policy_controller.cc b/chrome/browser/policy/cloud_policy_controller.cc
index e3cd3c8..9337b02 100644
--- a/chrome/browser/policy/cloud_policy_controller.cc
+++ b/chrome/browser/policy/cloud_policy_controller.cc
@@ -6,10 +6,11 @@
#include <algorithm>
+#include "base/logging.h"
#include "base/message_loop.h"
#include "base/rand_util.h"
#include "base/string_util.h"
-#include "chrome/browser/policy/cloud_policy_cache.h"
+#include "chrome/browser/policy/cloud_policy_cache_base.h"
#include "chrome/browser/policy/cloud_policy_subsystem.h"
#include "chrome/browser/policy/device_management_backend.h"
#include "chrome/browser/policy/proto/device_management_constants.h"
@@ -59,7 +60,7 @@ static const int kPolicyRefreshRateInMilliseconds =
3 * 60 * 60 * 1000; // 3 hours.
CloudPolicyController::CloudPolicyController(
- CloudPolicyCache* cache,
+ CloudPolicyCacheBase* cache,
DeviceManagementBackend* backend,
DeviceTokenFetcher* token_fetcher,
CloudPolicyIdentityStrategy* identity_strategy)
@@ -176,7 +177,7 @@ void CloudPolicyController::OnCredentialsChanged() {
}
CloudPolicyController::CloudPolicyController(
- CloudPolicyCache* cache,
+ CloudPolicyCacheBase* cache,
DeviceManagementBackend* backend,
DeviceTokenFetcher* token_fetcher,
CloudPolicyIdentityStrategy* identity_strategy,
@@ -196,7 +197,7 @@ CloudPolicyController::CloudPolicyController(
}
void CloudPolicyController::Initialize(
- CloudPolicyCache* cache,
+ CloudPolicyCacheBase* cache,
DeviceManagementBackend* backend,
DeviceTokenFetcher* token_fetcher,
CloudPolicyIdentityStrategy* identity_strategy,
diff --git a/chrome/browser/policy/cloud_policy_controller.h b/chrome/browser/policy/cloud_policy_controller.h
index 4a75a85..1bc316b 100644
--- a/chrome/browser/policy/cloud_policy_controller.h
+++ b/chrome/browser/policy/cloud_policy_controller.h
@@ -23,7 +23,7 @@ class TokenService;
namespace policy {
-class CloudPolicyCache;
+class CloudPolicyCacheBase;
class DeviceManagementBackend;
// Coordinates the actions of DeviceTokenFetcher, CloudPolicyIdentityStrategy,
@@ -35,7 +35,7 @@ class CloudPolicyController
public CloudPolicyIdentityStrategy::Observer {
public:
// Takes ownership of |backend|; the other parameters are weak pointers.
- CloudPolicyController(CloudPolicyCache* cache,
+ CloudPolicyController(CloudPolicyCacheBase* cache,
DeviceManagementBackend* backend,
DeviceTokenFetcher* token_fetcher,
CloudPolicyIdentityStrategy* identity_strategy);
@@ -78,7 +78,7 @@ class CloudPolicyController
friend class CloudPolicyControllerTest;
// More configurable constructor for use by test cases.
- CloudPolicyController(CloudPolicyCache* cache,
+ CloudPolicyController(CloudPolicyCacheBase* cache,
DeviceManagementBackend* backend,
DeviceTokenFetcher* token_fetcher,
CloudPolicyIdentityStrategy* identity_strategy,
@@ -88,7 +88,7 @@ class CloudPolicyController
int64 policy_refresh_error_delay_ms);
// Called by constructors to perform shared initialization.
- void Initialize(CloudPolicyCache* cache,
+ void Initialize(CloudPolicyCacheBase* cache,
DeviceManagementBackend* backend,
DeviceTokenFetcher* token_fetcher,
CloudPolicyIdentityStrategy* identity_strategy,
@@ -117,7 +117,7 @@ class CloudPolicyController
// Computes the policy refresh delay to use.
int64 GetRefreshDelay();
- CloudPolicyCache* cache_;
+ CloudPolicyCacheBase* cache_;
scoped_ptr<DeviceManagementBackend> backend_;
CloudPolicyIdentityStrategy* identity_strategy_;
DeviceTokenFetcher* token_fetcher_;
diff --git a/chrome/browser/policy/cloud_policy_controller_unittest.cc b/chrome/browser/policy/cloud_policy_controller_unittest.cc
index b3adc97..6419521 100644
--- a/chrome/browser/policy/cloud_policy_controller_unittest.cc
+++ b/chrome/browser/policy/cloud_policy_controller_unittest.cc
@@ -6,11 +6,11 @@
#include "base/memory/scoped_temp_dir.h"
#include "base/message_loop.h"
-#include "chrome/browser/policy/cloud_policy_cache.h"
#include "chrome/browser/policy/device_token_fetcher.h"
-#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "chrome/browser/policy/mock_configuration_policy_store.h"
#include "chrome/browser/policy/mock_device_management_backend.h"
+#include "chrome/browser/policy/proto/device_management_backend.pb.h"
+#include "chrome/browser/policy/user_policy_cache.h"
#include "content/browser/browser_thread.h"
#include "policy/policy_constants.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -54,7 +54,7 @@ ACTION_P2(MockCloudPolicyIdentityStrategyGetCredentials, username, auth_token) {
class MockDeviceTokenFetcher : public DeviceTokenFetcher {
public:
- explicit MockDeviceTokenFetcher(CloudPolicyCache* cache)
+ explicit MockDeviceTokenFetcher(CloudPolicyCacheBase* cache)
: DeviceTokenFetcher(NULL, cache) {}
virtual ~MockDeviceTokenFetcher() {}
@@ -78,7 +78,7 @@ class CloudPolicyControllerTest : public testing::Test {
virtual void SetUp() {
ASSERT_TRUE(temp_user_data_dir_.CreateUniqueTempDir());
- cache_.reset(new CloudPolicyCache(
+ cache_.reset(new UserPolicyCache(
temp_user_data_dir_.path().AppendASCII("CloudPolicyControllerTest")));
token_fetcher_.reset(new MockDeviceTokenFetcher(cache_.get()));
}
@@ -140,7 +140,7 @@ class CloudPolicyControllerTest : public testing::Test {
}
protected:
- scoped_ptr<CloudPolicyCache> cache_;
+ scoped_ptr<CloudPolicyCacheBase> cache_;
scoped_ptr<CloudPolicyController> controller_;
scoped_ptr<MockDeviceTokenFetcher> token_fetcher_;
MockCloudPolicyIdentityStrategy identity_strategy_;
diff --git a/chrome/browser/policy/cloud_policy_subsystem.cc b/chrome/browser/policy/cloud_policy_subsystem.cc
index aad81ad..0cc1ed9 100644
--- a/chrome/browser/policy/cloud_policy_subsystem.cc
+++ b/chrome/browser/policy/cloud_policy_subsystem.cc
@@ -8,7 +8,7 @@
#include <string>
#include "base/command_line.h"
-#include "chrome/browser/policy/cloud_policy_cache.h"
+#include "chrome/browser/policy/cloud_policy_cache_base.h"
#include "chrome/browser/policy/cloud_policy_controller.h"
#include "chrome/browser/policy/cloud_policy_identity_strategy.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
@@ -30,15 +30,15 @@ const int64 kPolicyRefreshRateMaxMs = 24 * 60 * 60 * 1000; // 1 day
namespace policy {
CloudPolicySubsystem::CloudPolicySubsystem(
- const FilePath& policy_cache_file,
- CloudPolicyIdentityStrategy* identity_strategy)
+ CloudPolicyIdentityStrategy* identity_strategy,
+ CloudPolicyCacheBase* policy_cache)
: prefs_(NULL) {
CommandLine* command_line = CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kDeviceManagementUrl)) {
device_management_service_.reset(new DeviceManagementService(
command_line->GetSwitchValueASCII(switches::kDeviceManagementUrl)));
- cloud_policy_cache_.reset(new CloudPolicyCache(policy_cache_file));
- cloud_policy_cache_->LoadFromFile();
+ cloud_policy_cache_.reset(policy_cache);
+ cloud_policy_cache_->Load();
device_token_fetcher_.reset(
new DeviceTokenFetcher(device_management_service_.get(),
diff --git a/chrome/browser/policy/cloud_policy_subsystem.h b/chrome/browser/policy/cloud_policy_subsystem.h
index 398c997..9275476 100644
--- a/chrome/browser/policy/cloud_policy_subsystem.h
+++ b/chrome/browser/policy/cloud_policy_subsystem.h
@@ -10,13 +10,12 @@
#include "chrome/browser/prefs/pref_member.h"
#include "content/common/notification_observer.h"
-class FilePath;
class PrefService;
class URLRequestContextGetter;
namespace policy {
-class CloudPolicyCache;
+class CloudPolicyCacheBase;
class CloudPolicyController;
class CloudPolicyIdentityStrategy;
class ConfigurationPolicyProvider;
@@ -28,8 +27,8 @@ class DeviceTokenFetcher;
// life cycle of the policy providers.
class CloudPolicySubsystem : public NotificationObserver {
public:
- CloudPolicySubsystem(const FilePath& policy_cache_file,
- CloudPolicyIdentityStrategy* identity_strategy);
+ CloudPolicySubsystem(CloudPolicyIdentityStrategy* identity_strategy,
+ CloudPolicyCacheBase* policy_cache);
virtual ~CloudPolicySubsystem();
// Initializes the subsystem.
@@ -62,7 +61,7 @@ class CloudPolicySubsystem : public NotificationObserver {
// Cloud policy infrastructure stuff.
scoped_ptr<DeviceManagementService> device_management_service_;
scoped_ptr<DeviceTokenFetcher> device_token_fetcher_;
- scoped_ptr<CloudPolicyCache> cloud_policy_cache_;
+ scoped_ptr<CloudPolicyCacheBase> cloud_policy_cache_;
scoped_ptr<CloudPolicyController> cloud_policy_controller_;
DISALLOW_COPY_AND_ASSIGN(CloudPolicySubsystem);
diff --git a/chrome/browser/policy/device_policy_cache.cc b/chrome/browser/policy/device_policy_cache.cc
new file mode 100644
index 0000000..39381dc
--- /dev/null
+++ b/chrome/browser/policy/device_policy_cache.cc
@@ -0,0 +1,97 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/device_policy_cache.h"
+
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/task.h"
+#include "base/values.h"
+#include "chrome/browser/policy/configuration_policy_pref_store.h"
+#include "chrome/browser/policy/policy_map.h"
+#include "chrome/browser/policy/proto/cloud_policy.pb.h"
+#include "chrome/browser/policy/proto/device_management_constants.h"
+#include "chrome/browser/policy/proto/device_management_local.pb.h"
+#include "content/browser/browser_thread.h"
+#include "policy/configuration_policy_type.h"
+
+using google::protobuf::RepeatedPtrField;
+
+namespace policy {
+
+DevicePolicyCache::DevicePolicyCache()
+ : signed_settings_helper_(chromeos::SignedSettingsHelper::Get()) {
+}
+
+DevicePolicyCache::DevicePolicyCache(
+ chromeos::SignedSettingsHelper* signed_settings_helper)
+ : signed_settings_helper_(signed_settings_helper) {
+}
+
+DevicePolicyCache::~DevicePolicyCache() {
+ signed_settings_helper_->CancelCallback(this);
+}
+
+void DevicePolicyCache::Load() {
+ // TODO(jkummerow): check if we're unmanaged; if so, set is_unmanaged_ = true
+ // and return immediately.
+
+ signed_settings_helper_->StartRetrievePolicyOp(this);
+}
+
+void DevicePolicyCache::SetPolicy(const em::PolicyFetchResponse& policy) {
+ set_last_policy_refresh_time(base::Time::NowFromSystemTime());
+ signed_settings_helper_->StartStorePolicyOp(policy, this);
+}
+
+void DevicePolicyCache::SetUnmanaged() {
+ LOG(WARNING) << "Tried to set DevicePolicyCache to 'unmanaged'!";
+ // This is not supported for DevicePolicyCache.
+}
+
+void DevicePolicyCache::OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::ReturnCode code,
+ const em::PolicyFetchResponse& policy) {
+ DCHECK(CalledOnValidThread());
+ if (code != chromeos::SignedSettings::SUCCESS) {
+ // TODO(jkummerow): We can't really do anything about this error, but
+ // we may want to notify the user that something is wrong.
+ return;
+ }
+ SetPolicyInternal(policy, NULL, false);
+}
+
+void DevicePolicyCache::OnStorePolicyCompleted(
+ chromeos::SignedSettings::ReturnCode code) {
+ DCHECK(CalledOnValidThread());
+ if (code != chromeos::SignedSettings::SUCCESS) {
+ // TODO(jkummerow): We can't really do anything about this error, but
+ // we may want to notify the user that something is wrong.
+ return;
+ }
+ Load();
+}
+
+bool DevicePolicyCache::DecodePolicyData(const em::PolicyData& policy_data,
+ PolicyMap* mandatory,
+ PolicyMap* recommended) {
+ em::ChromeDeviceSettingsProto policy;
+ if (!policy.ParseFromString(policy_data.policy_value())) {
+ LOG(WARNING) << "Failed to parse ChromeDeviceSettingsProto.";
+ return false;
+ }
+ DecodeDevicePolicy(policy, mandatory, recommended);
+ return true;
+}
+
+// static
+void DevicePolicyCache::DecodeDevicePolicy(
+ const em::ChromeDeviceSettingsProto& policy,
+ PolicyMap* mandatory,
+ PolicyMap* recommended) {
+ // TODO(jkummerow): Implement this when there are consumers for
+ // device-policy-set values in g_browser_process->local_state().
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/device_policy_cache.h b/chrome/browser/policy/device_policy_cache.h
new file mode 100644
index 0000000..f6a9514
--- /dev/null
+++ b/chrome/browser/policy/device_policy_cache.h
@@ -0,0 +1,66 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_DEVICE_POLICY_CACHE_H_
+#define CHROME_BROWSER_POLICY_DEVICE_POLICY_CACHE_H_
+#pragma once
+
+#include <string>
+
+#include "chrome/browser/chromeos/login/signed_settings.h"
+#include "chrome/browser/chromeos/login/signed_settings_helper.h"
+#include "chrome/browser/policy/cloud_policy_cache_base.h"
+#include "chrome/browser/policy/proto/chrome_device_policy.pb.h"
+
+namespace policy {
+
+class PolicyMap;
+
+namespace em = enterprise_management;
+
+// CloudPolicyCacheBase implementation that persists policy information
+// to ChromeOS' session manager (via SignedSettingsHelper).
+class DevicePolicyCache : public CloudPolicyCacheBase,
+ public chromeos::SignedSettingsHelper::Callback {
+ public:
+ DevicePolicyCache();
+ virtual ~DevicePolicyCache();
+
+ // CloudPolicyCacheBase implementation:
+ virtual void Load() OVERRIDE;
+ virtual void SetPolicy(const em::PolicyFetchResponse& policy) OVERRIDE;
+ virtual void SetUnmanaged() OVERRIDE;
+
+ // SignedSettingsHelper::Callback implementation:
+ virtual void OnStorePolicyCompleted(
+ chromeos::SignedSettings::ReturnCode code) OVERRIDE;
+ virtual void OnRetrievePolicyCompleted(
+ chromeos::SignedSettings::ReturnCode code,
+ const em::PolicyFetchResponse& policy) OVERRIDE;
+
+ private:
+ friend class DevicePolicyCacheTest;
+
+ // Alternate c'tor allowing tests to mock out the SignedSettingsHelper
+ // singleton.
+ explicit DevicePolicyCache(
+ chromeos::SignedSettingsHelper* signed_settings_helper);
+
+ // CloudPolicyCacheBase implementation:
+ virtual bool DecodePolicyData(const em::PolicyData& policy_data,
+ PolicyMap* mandatory,
+ PolicyMap* recommended) OVERRIDE;
+
+ static void DecodeDevicePolicy(const em::ChromeDeviceSettingsProto& policy,
+ PolicyMap* mandatory,
+ PolicyMap* recommended);
+
+ chromeos::SignedSettingsHelper* signed_settings_helper_;
+
+ DISALLOW_COPY_AND_ASSIGN(DevicePolicyCache);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_DEVICE_POLICY_CACHE_H_
diff --git a/chrome/browser/policy/device_policy_cache_unittest.cc b/chrome/browser/policy/device_policy_cache_unittest.cc
new file mode 100644
index 0000000..79c2c82
--- /dev/null
+++ b/chrome/browser/policy/device_policy_cache_unittest.cc
@@ -0,0 +1,142 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/device_policy_cache.h"
+
+#include "policy/configuration_policy_type.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+namespace {
+
+using ::chromeos::SignedSettings;
+using ::chromeos::SignedSettingsHelper;
+using ::testing::_;
+using ::testing::InSequence;
+
+class MockSignedSettingsHelper : public SignedSettingsHelper {
+ public:
+ MockSignedSettingsHelper() {}
+ virtual ~MockSignedSettingsHelper() {}
+
+ MOCK_METHOD2(StartStorePolicyOp, void(const em::PolicyFetchResponse&,
+ SignedSettingsHelper::Callback*));
+ MOCK_METHOD1(StartRetrievePolicyOp, void(SignedSettingsHelper::Callback*));
+ MOCK_METHOD1(CancelCallback, void(SignedSettingsHelper::Callback*));
+
+ // This test doesn't need these methods, but since they're pure virtual in
+ // SignedSettingsHelper, they must be implemented:
+ MOCK_METHOD2(StartCheckWhitelistOp, void(const std::string&,
+ SignedSettingsHelper::Callback*));
+ MOCK_METHOD3(StartWhitelistOp, void(const std::string&, bool,
+ SignedSettingsHelper::Callback*));
+ MOCK_METHOD3(StartStorePropertyOp, void(const std::string&,
+ const std::string&,
+ SignedSettingsHelper::Callback*));
+ MOCK_METHOD2(StartRetrieveProperty, void(const std::string&,
+ SignedSettingsHelper::Callback*));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockSignedSettingsHelper);
+};
+
+ACTION_P(MockSignedSettingsHelperStorePolicy, status_code) {
+ arg1->OnStorePolicyCompleted(status_code);
+}
+
+ACTION_P2(MockSignedSettingsHelperRetrievePolicy, status_code, policy) {
+ arg0->OnRetrievePolicyCompleted(status_code, policy);
+}
+
+em::PolicyFetchResponse* CreateProxyPolicy(const std::string& proxy) {
+ // This method omits a few fields which currently aren't needed by tests:
+ // timestamp, machine_name, request_token, policy_type, public key info.
+ em::PolicyData signed_response;
+ em::ChromeDeviceSettingsProto settings;
+ em::DeviceProxySettingsProto* proxy_proto =
+ settings.mutable_device_proxy_settings();
+ proxy_proto->set_proxy_server(proxy);
+ proxy_proto->set_proxy_mode("fixed_servers");
+ EXPECT_TRUE(
+ settings.SerializeToString(signed_response.mutable_policy_value()));
+ std::string serialized_signed_response;
+ EXPECT_TRUE(signed_response.SerializeToString(&serialized_signed_response));
+ em::PolicyFetchResponse* response = new em::PolicyFetchResponse;
+ response->set_policy_data(serialized_signed_response);
+ return response;
+}
+
+} // namespace
+
+class DevicePolicyCacheTest : public testing::Test {
+ protected:
+ DevicePolicyCacheTest() {
+ }
+
+ virtual void SetUp() {
+ cache_.reset(new DevicePolicyCache(&signed_settings_helper_));
+ }
+
+ virtual void TearDown() {
+ EXPECT_CALL(signed_settings_helper_, CancelCallback(_));
+ cache_.reset();
+ }
+
+ const PolicyMap& mandatory_policy(const DevicePolicyCache& cache) {
+ return cache.mandatory_policy_;
+ }
+
+ scoped_ptr<DevicePolicyCache> cache_;
+ MockSignedSettingsHelper signed_settings_helper_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DevicePolicyCacheTest);
+};
+
+TEST_F(DevicePolicyCacheTest, Startup) {
+ scoped_ptr<em::PolicyFetchResponse> policy_response(
+ CreateProxyPolicy("proxy.server"));
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ *policy_response));
+ cache_->Load();
+ // TODO(jkummerow): This will be EXPECT_GT once policy decoding is
+ // implemented in DevicePolicyCache::DecodeDevicePolicy(...).
+ EXPECT_EQ(mandatory_policy(*cache_).size(), 0U);
+}
+
+TEST_F(DevicePolicyCacheTest, SetPolicy) {
+ InSequence s;
+ // Startup.
+ scoped_ptr<em::PolicyFetchResponse> policy_response(
+ CreateProxyPolicy("proxy.server.old"));
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ *policy_response));
+ cache_->Load();
+ scoped_ptr<Value> expected(Value::CreateStringValue("proxy.server.old"));
+ // TODO(jkummerow): This will be EXPECT_TRUE once policy decoding is
+ // implemented in DevicePolicyCache::DecodeDevicePolicy(...).
+ EXPECT_FALSE(Value::Equals(
+ mandatory_policy(*cache_).Get(kPolicyProxyServer), expected.get()));
+ testing::Mock::VerifyAndClearExpectations(&signed_settings_helper_);
+ // Set new policy information.
+ scoped_ptr<em::PolicyFetchResponse> new_policy_response(
+ CreateProxyPolicy("proxy.server.new"));
+ EXPECT_CALL(signed_settings_helper_, StartStorePolicyOp(_, _)).WillOnce(
+ MockSignedSettingsHelperStorePolicy(chromeos::SignedSettings::SUCCESS));
+ EXPECT_CALL(signed_settings_helper_, StartRetrievePolicyOp(_)).WillOnce(
+ MockSignedSettingsHelperRetrievePolicy(SignedSettings::SUCCESS,
+ *new_policy_response));
+ cache_->SetPolicy(*new_policy_response);
+ expected.reset(Value::CreateStringValue("proxy.server.new"));
+ // TODO(jkummerow): This will be EXPECT_TRUE once policy decoding is
+ // implemented in DevicePolicyCache::DecodeDevicePolicy(...).
+ EXPECT_FALSE(Value::Equals(
+ mandatory_policy(*cache_).Get(kPolicyProxyServer), expected.get()));
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/device_token_fetcher.cc b/chrome/browser/policy/device_token_fetcher.cc
index f3f8ff4..9fe7cff 100644
--- a/chrome/browser/policy/device_token_fetcher.cc
+++ b/chrome/browser/policy/device_token_fetcher.cc
@@ -7,7 +7,7 @@
#include <algorithm>
#include "base/message_loop.h"
-#include "chrome/browser/policy/cloud_policy_cache.h"
+#include "chrome/browser/policy/cloud_policy_cache_base.h"
#include "chrome/browser/policy/device_management_service.h"
#include "chrome/browser/policy/proto/device_management_constants.h"
#include "chrome/browser/policy/proto/device_management_local.pb.h"
@@ -29,7 +29,7 @@ namespace em = enterprise_management;
DeviceTokenFetcher::DeviceTokenFetcher(
DeviceManagementService* service,
- CloudPolicyCache* cache)
+ CloudPolicyCacheBase* cache)
: ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
Initialize(service,
cache,
@@ -40,7 +40,7 @@ DeviceTokenFetcher::DeviceTokenFetcher(
DeviceTokenFetcher::DeviceTokenFetcher(
DeviceManagementService* service,
- CloudPolicyCache* cache,
+ CloudPolicyCacheBase* cache,
int64 token_fetch_error_delay_ms,
int64 token_fetch_error_max_delay_ms,
int64 unmanaged_device_refresh_rate_ms)
@@ -136,7 +136,7 @@ void DeviceTokenFetcher::OnError(DeviceManagementBackend::ErrorCode code) {
}
void DeviceTokenFetcher::Initialize(DeviceManagementService* service,
- CloudPolicyCache* cache,
+ CloudPolicyCacheBase* cache,
int64 token_fetch_error_delay_ms,
int64 token_fetch_error_max_delay_ms,
int64 unmanaged_device_refresh_rate_ms) {
diff --git a/chrome/browser/policy/device_token_fetcher.h b/chrome/browser/policy/device_token_fetcher.h
index f0daba7..e010de8 100644
--- a/chrome/browser/policy/device_token_fetcher.h
+++ b/chrome/browser/policy/device_token_fetcher.h
@@ -16,7 +16,7 @@
namespace policy {
-class CloudPolicyCache;
+class CloudPolicyCacheBase;
class DeviceManagementService;
namespace em = enterprise_management;
@@ -38,10 +38,10 @@ class DeviceTokenFetcher
// |service| is used to talk to the device management service and |cache| is
// used to persist whether the device is unmanaged.
DeviceTokenFetcher(DeviceManagementService* service,
- CloudPolicyCache* cache);
+ CloudPolicyCacheBase* cache);
// Version for tests that allows to set timing paramters.
DeviceTokenFetcher(DeviceManagementService* service,
- CloudPolicyCache* cache,
+ CloudPolicyCacheBase* cache,
int64 token_fetch_error_delay_ms,
int64 token_fetch_error_max_delay_ms,
int64 unmanaged_device_refresh_rate_ms);
@@ -93,7 +93,7 @@ class DeviceTokenFetcher
// Common initialization helper.
void Initialize(DeviceManagementService* service,
- CloudPolicyCache* cache,
+ CloudPolicyCacheBase* cache,
int64 token_fetch_error_delay_ms,
int64 token_fetch_error_max_delay_ms,
int64 unmanaged_device_refresh_rate_ms);
@@ -117,7 +117,7 @@ class DeviceTokenFetcher
scoped_ptr<DeviceManagementBackend> backend_;
// Reference to the cache. Used to persist and read unmanaged state.
- CloudPolicyCache* cache_;
+ CloudPolicyCacheBase* cache_;
// Refresh parameters.
int64 token_fetch_error_delay_ms_;
diff --git a/chrome/browser/policy/device_token_fetcher_unittest.cc b/chrome/browser/policy/device_token_fetcher_unittest.cc
index 4d01c29..2a7f9bc 100644
--- a/chrome/browser/policy/device_token_fetcher_unittest.cc
+++ b/chrome/browser/policy/device_token_fetcher_unittest.cc
@@ -8,10 +8,10 @@
#include "base/memory/scoped_temp_dir.h"
#include "base/message_loop.h"
#include "chrome/browser/net/gaia/token_service.h"
-#include "chrome/browser/policy/cloud_policy_cache.h"
#include "chrome/browser/policy/device_management_service.h"
#include "chrome/browser/policy/proto/device_management_backend.pb.h"
#include "chrome/browser/policy/mock_device_management_backend.h"
+#include "chrome/browser/policy/user_policy_cache.h"
#include "chrome/common/net/gaia/gaia_constants.h"
#include "chrome/test/testing_profile.h"
#include "content/browser/browser_thread.h"
@@ -106,7 +106,7 @@ class DeviceTokenFetcherTest : public testing::Test {
}
virtual void SetUp() {
- cache_.reset(new CloudPolicyCache(
+ cache_.reset(new UserPolicyCache(
temp_user_data_dir_.path().AppendASCII("DeviceTokenFetcherTest")));
service_.set_backend(&backend_);
}
@@ -118,7 +118,7 @@ class DeviceTokenFetcherTest : public testing::Test {
MessageLoop loop_;
MockDeviceManagementBackend backend_;
MockDeviceManagementService service_;
- scoped_ptr<CloudPolicyCache> cache_;
+ scoped_ptr<CloudPolicyCacheBase> cache_;
ScopedTempDir temp_user_data_dir_;
private:
diff --git a/chrome/browser/policy/profile_policy_connector.cc b/chrome/browser/policy/profile_policy_connector.cc
index ac22603..aba4fbb 100644
--- a/chrome/browser/policy/profile_policy_connector.cc
+++ b/chrome/browser/policy/profile_policy_connector.cc
@@ -9,6 +9,7 @@
#include "base/file_util.h"
#include "chrome/browser/policy/cloud_policy_subsystem.h"
#include "chrome/browser/policy/profile_policy_connector.h"
+#include "chrome/browser/policy/user_policy_cache.h"
#include "chrome/browser/policy/user_policy_identity_strategy.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
@@ -51,8 +52,8 @@ ProfilePolicyConnector::ProfilePolicyConnector(Profile* profile)
profile_,
policy_cache_dir.Append(kTokenCacheFile)));
cloud_policy_subsystem_.reset(new CloudPolicySubsystem(
- policy_cache_dir.Append(kPolicyCacheFile),
- identity_strategy_.get()));
+ identity_strategy_.get(),
+ new UserPolicyCache(policy_cache_dir.Append(kPolicyCacheFile))));
}
}
diff --git a/chrome/browser/policy/user_policy_cache.cc b/chrome/browser/policy/user_policy_cache.cc
new file mode 100644
index 0000000..12845f0
--- /dev/null
+++ b/chrome/browser/policy/user_policy_cache.cc
@@ -0,0 +1,153 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/user_policy_cache.h"
+
+#include <string>
+
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/task.h"
+#include "chrome/browser/policy/policy_map.h"
+#include "chrome/browser/policy/proto/cloud_policy.pb.h"
+#include "chrome/browser/policy/proto/device_management_local.pb.h"
+#include "content/browser/browser_thread.h"
+#include "policy/configuration_policy_type.h"
+
+namespace policy {
+
+// Decodes a CloudPolicySettings object into two maps with mandatory and
+// recommended settings, respectively. The implementation is generated code
+// in policy/cloud_policy_generated.cc.
+void DecodePolicy(const em::CloudPolicySettings& policy,
+ PolicyMap* mandatory, PolicyMap* recommended);
+
+// Saves policy information to a file.
+class PersistPolicyTask : public Task {
+ public:
+ PersistPolicyTask(const FilePath& path,
+ const em::PolicyFetchResponse* cloud_policy_response,
+ const bool is_unmanaged)
+ : path_(path),
+ cloud_policy_response_(cloud_policy_response),
+ is_unmanaged_(is_unmanaged) {}
+
+ private:
+ // Task override.
+ virtual void Run();
+
+ const FilePath path_;
+ scoped_ptr<const em::PolicyFetchResponse> cloud_policy_response_;
+ const bool is_unmanaged_;
+};
+
+void PersistPolicyTask::Run() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+ std::string data;
+ em::CachedCloudPolicyResponse cached_policy;
+ if (cloud_policy_response_.get()) {
+ cached_policy.mutable_cloud_policy()->CopyFrom(*cloud_policy_response_);
+ }
+ if (is_unmanaged_) {
+ cached_policy.set_unmanaged(true);
+ cached_policy.set_timestamp(base::Time::NowFromSystemTime().ToTimeT());
+ }
+ if (!cached_policy.SerializeToString(&data)) {
+ LOG(WARNING) << "Failed to serialize policy data";
+ return;
+ }
+
+ int size = data.size();
+ if (file_util::WriteFile(path_, data.c_str(), size) != size) {
+ LOG(WARNING) << "Failed to write " << path_.value();
+ return;
+ }
+}
+
+UserPolicyCache::UserPolicyCache(const FilePath& backing_file_path)
+ : backing_file_path_(backing_file_path) {
+}
+
+UserPolicyCache::~UserPolicyCache() {
+}
+
+void UserPolicyCache::Load() {
+ // TODO(jkummerow): This method is doing file IO during browser startup. In
+ // the long run it would be better to delay this until the FILE thread exists.
+ if (!file_util::PathExists(backing_file_path_) || initialization_complete()) {
+ return;
+ }
+
+ // Read the protobuf from the file.
+ std::string data;
+ if (!file_util::ReadFileToString(backing_file_path_, &data)) {
+ LOG(WARNING) << "Failed to read policy data from "
+ << backing_file_path_.value();
+ return;
+ }
+
+ em::CachedCloudPolicyResponse cached_response;
+ if (!cached_response.ParseFromArray(data.c_str(), data.size())) {
+ LOG(WARNING) << "Failed to parse policy data read from "
+ << backing_file_path_.value();
+ return;
+ }
+
+ if (cached_response.unmanaged()) {
+ SetUnmanagedInternal(base::Time::FromTimeT(cached_response.timestamp()));
+ } else if (cached_response.has_cloud_policy()) {
+ base::Time timestamp;
+ if (SetPolicyInternal(cached_response.cloud_policy(), &timestamp, true))
+ set_last_policy_refresh_time(timestamp);
+ }
+}
+
+void UserPolicyCache::SetPolicy(const em::PolicyFetchResponse& policy) {
+ base::Time now = base::Time::NowFromSystemTime();
+ set_last_policy_refresh_time(now);
+ bool ok = SetPolicyInternal(policy, NULL, false);
+ if (ok)
+ PersistPolicy(policy, now);
+}
+
+void UserPolicyCache::SetUnmanaged() {
+ DCHECK(CalledOnValidThread());
+ SetUnmanagedInternal(base::Time::NowFromSystemTime());
+ BrowserThread::PostTask(
+ BrowserThread::FILE,
+ FROM_HERE,
+ new PersistPolicyTask(backing_file_path_, NULL, true));
+}
+
+void UserPolicyCache::PersistPolicy(const em::PolicyFetchResponse& policy,
+ const base::Time& timestamp) {
+ if (timestamp > base::Time::NowFromSystemTime() +
+ base::TimeDelta::FromMinutes(1)) {
+ LOG(WARNING) << "Server returned policy with timestamp from the future, "
+ "not persisting to disk.";
+ } else {
+ em::PolicyFetchResponse* policy_copy = new em::PolicyFetchResponse;
+ policy_copy->CopyFrom(policy);
+ BrowserThread::PostTask(
+ BrowserThread::FILE,
+ FROM_HERE,
+ new PersistPolicyTask(backing_file_path_, policy_copy, false));
+ }
+}
+
+bool UserPolicyCache::DecodePolicyData(const em::PolicyData& policy_data,
+ PolicyMap* mandatory,
+ PolicyMap* recommended) {
+ // TODO(jkummerow): Verify policy_data.device_token(). Needs final
+ // specification which token we're actually sending / expecting to get back.
+ em::CloudPolicySettings policy;
+ if (!policy.ParseFromString(policy_data.policy_value())) {
+ LOG(WARNING) << "Failed to parse CloudPolicySettings protobuf.";
+ return false;
+ }
+ DecodePolicy(policy, mandatory, recommended);
+ return true;
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/user_policy_cache.h b/chrome/browser/policy/user_policy_cache.h
new file mode 100644
index 0000000..316497f
--- /dev/null
+++ b/chrome/browser/policy/user_policy_cache.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_POLICY_USER_POLICY_CACHE_H_
+#define CHROME_BROWSER_POLICY_USER_POLICY_CACHE_H_
+#pragma once
+
+#include "base/file_path.h"
+#include "chrome/browser/policy/cloud_policy_cache_base.h"
+
+namespace policy {
+
+// CloudPolicyCacheBase implementation that persists policy information
+// into the file specified by the c'tor parameter |backing_file_path|.
+class UserPolicyCache : public CloudPolicyCacheBase {
+ public:
+ explicit UserPolicyCache(const FilePath& backing_file_path);
+ virtual ~UserPolicyCache();
+
+ // CloudPolicyCacheBase implementation:
+ virtual void Load() OVERRIDE;
+ virtual void SetPolicy(const em::PolicyFetchResponse& policy) OVERRIDE;
+ virtual void SetUnmanaged() OVERRIDE;
+
+ private:
+ void PersistPolicy(const em::PolicyFetchResponse& policy,
+ const base::Time& timestamp);
+
+ // CloudPolicyCacheBase implementation:
+ virtual bool DecodePolicyData(const em::PolicyData& policy_data,
+ PolicyMap* mandatory,
+ PolicyMap* recommended) OVERRIDE;
+
+ // The file in which we store a cached version of the policy information.
+ const FilePath backing_file_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(UserPolicyCache);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_USER_POLICY_CACHE_H_
diff --git a/chrome/browser/policy/user_policy_cache_unittest.cc b/chrome/browser/policy/user_policy_cache_unittest.cc
new file mode 100644
index 0000000..8e74535
--- /dev/null
+++ b/chrome/browser/policy/user_policy_cache_unittest.cc
@@ -0,0 +1,338 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/policy/user_policy_cache.h"
+
+#include <limits>
+#include <string>
+
+#include "base/file_util.h"
+#include "base/memory/scoped_temp_dir.h"
+#include "base/message_loop.h"
+#include "base/values.h"
+#include "chrome/browser/policy/configuration_policy_provider.h"
+#include "chrome/browser/policy/proto/cloud_policy.pb.h"
+#include "chrome/browser/policy/proto/device_management_backend.pb.h"
+#include "chrome/browser/policy/proto/device_management_local.pb.h"
+#include "content/browser/browser_thread.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+// Decodes a CloudPolicySettings object into two maps with mandatory and
+// recommended settings, respectively. The implementation is generated code
+// in policy/cloud_policy_generated.cc.
+void DecodePolicy(const em::CloudPolicySettings& policy,
+ PolicyMap* mandatory, PolicyMap* recommended);
+
+// The implementations of these methods are in cloud_policy_generated.cc.
+Value* DecodeIntegerValue(google::protobuf::int64 value);
+ListValue* DecodeStringList(const em::StringList& string_list);
+
+class MockConfigurationPolicyProviderObserver
+ : public ConfigurationPolicyProvider::Observer {
+ public:
+ MockConfigurationPolicyProviderObserver() {}
+ virtual ~MockConfigurationPolicyProviderObserver() {}
+ MOCK_METHOD0(OnUpdatePolicy, void());
+ void OnProviderGoingAway() {}
+};
+
+// Tests the device management policy cache.
+class UserPolicyCacheTest : public testing::Test {
+ protected:
+ UserPolicyCacheTest()
+ : loop_(MessageLoop::TYPE_UI),
+ ui_thread_(BrowserThread::UI, &loop_),
+ file_thread_(BrowserThread::FILE, &loop_) {}
+
+ void SetUp() {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ }
+
+ void TearDown() {
+ loop_.RunAllPending();
+ }
+
+ // Creates a (signed) PolicyFetchResponse setting the given |homepage| and
+ // featuring the given |timestamp| (as issued by the server).
+ // Mildly hacky special feature: pass an empty string as |homepage| to get
+ // a completely empty policy.
+ em::PolicyFetchResponse* CreateHomepagePolicy(
+ const std::string& homepage,
+ const base::Time& timestamp,
+ const em::PolicyOptions::PolicyMode policy_mode) {
+ em::PolicyData signed_response;
+ if (homepage != "") {
+ em::CloudPolicySettings settings;
+ em::HomepageLocationProto* homepagelocation_proto =
+ settings.mutable_homepagelocation();
+ homepagelocation_proto->set_homepagelocation(homepage);
+ homepagelocation_proto->mutable_policy_options()->set_mode(policy_mode);
+ EXPECT_TRUE(
+ settings.SerializeToString(signed_response.mutable_policy_value()));
+ }
+ signed_response.set_timestamp(
+ (timestamp - base::Time::UnixEpoch()).InMilliseconds());
+ std::string serialized_signed_response;
+ EXPECT_TRUE(signed_response.SerializeToString(&serialized_signed_response));
+
+ em::PolicyFetchResponse* response = new em::PolicyFetchResponse;
+ response->set_policy_data(serialized_signed_response);
+ // TODO(jkummerow): Set proper new_public_key and signature (when
+ // implementing support for signature verification).
+ response->set_policy_data_signature("TODO");
+ response->set_new_public_key("TODO");
+ return response;
+ }
+
+ void WritePolicy(const em::PolicyFetchResponse& policy) {
+ std::string data;
+ em::CachedCloudPolicyResponse cached_policy;
+ cached_policy.mutable_cloud_policy()->CopyFrom(policy);
+ EXPECT_TRUE(cached_policy.SerializeToString(&data));
+ int size = static_cast<int>(data.size());
+ EXPECT_EQ(size, file_util::WriteFile(test_file(), data.c_str(), size));
+ }
+
+ // Takes ownership of |policy_response|.
+ void SetPolicy(UserPolicyCache* cache,
+ em::PolicyFetchResponse* policy_response,
+ bool expect_changed_policy) {
+ scoped_ptr<em::PolicyFetchResponse> policy(policy_response);
+ ConfigurationPolicyObserverRegistrar registrar;
+ registrar.Init(cache->GetManagedPolicyProvider(), &observer);
+ if (expect_changed_policy)
+ EXPECT_CALL(observer, OnUpdatePolicy()).Times(1);
+ else
+ EXPECT_CALL(observer, OnUpdatePolicy()).Times(0);
+ cache->SetPolicy(*policy);
+ testing::Mock::VerifyAndClearExpectations(&observer);
+ }
+
+ FilePath test_file() {
+ return temp_dir_.path().AppendASCII("UserPolicyCacheTest");
+ }
+
+ const PolicyMap& mandatory_policy(const UserPolicyCache& cache) {
+ return cache.mandatory_policy_;
+ }
+
+ const PolicyMap& recommended_policy(const UserPolicyCache& cache) {
+ return cache.recommended_policy_;
+ }
+
+ MessageLoop loop_;
+ MockConfigurationPolicyProviderObserver observer;
+
+ private:
+ ScopedTempDir temp_dir_;
+ BrowserThread ui_thread_;
+ BrowserThread file_thread_;
+};
+
+TEST_F(UserPolicyCacheTest, DecodePolicy) {
+ em::CloudPolicySettings settings;
+ settings.mutable_homepagelocation()->set_homepagelocation("chromium.org");
+ settings.mutable_javascriptenabled()->set_javascriptenabled(true);
+ settings.mutable_javascriptenabled()->mutable_policy_options()->set_mode(
+ em::PolicyOptions::MANDATORY);
+ settings.mutable_policyrefreshrate()->set_policyrefreshrate(5);
+ settings.mutable_policyrefreshrate()->mutable_policy_options()->set_mode(
+ em::PolicyOptions::RECOMMENDED);
+ PolicyMap mandatory_policy;
+ PolicyMap recommended_policy;
+ DecodePolicy(settings, &mandatory_policy, &recommended_policy);
+ PolicyMap mandatory;
+ mandatory.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("chromium.org"));
+ mandatory.Set(kPolicyJavascriptEnabled, Value::CreateBooleanValue(true));
+ PolicyMap recommended;
+ recommended.Set(kPolicyPolicyRefreshRate, Value::CreateIntegerValue(5));
+ EXPECT_TRUE(mandatory.Equals(mandatory_policy));
+ EXPECT_TRUE(recommended.Equals(recommended_policy));
+}
+
+TEST_F(UserPolicyCacheTest, DecodeIntegerValue) {
+ const int min = std::numeric_limits<int>::min();
+ const int max = std::numeric_limits<int>::max();
+ scoped_ptr<Value> value(
+ DecodeIntegerValue(static_cast<google::protobuf::int64>(42)));
+ ASSERT_TRUE(value.get());
+ FundamentalValue expected_42(42);
+ EXPECT_TRUE(value->Equals(&expected_42));
+ value.reset(
+ DecodeIntegerValue(static_cast<google::protobuf::int64>(min - 1LL)));
+ EXPECT_EQ(NULL, value.get());
+ value.reset(DecodeIntegerValue(static_cast<google::protobuf::int64>(min)));
+ ASSERT_TRUE(value.get());
+ FundamentalValue expected_min(min);
+ EXPECT_TRUE(value->Equals(&expected_min));
+ value.reset(
+ DecodeIntegerValue(static_cast<google::protobuf::int64>(max + 1LL)));
+ EXPECT_EQ(NULL, value.get());
+ value.reset(DecodeIntegerValue(static_cast<google::protobuf::int64>(max)));
+ ASSERT_TRUE(value.get());
+ FundamentalValue expected_max(max);
+ EXPECT_TRUE(value->Equals(&expected_max));
+}
+
+TEST_F(UserPolicyCacheTest, DecodeStringList) {
+ em::StringList string_list;
+ string_list.add_entries("ponies");
+ string_list.add_entries("more ponies");
+ scoped_ptr<ListValue> decoded(DecodeStringList(string_list));
+ ListValue expected;
+ expected.Append(Value::CreateStringValue("ponies"));
+ expected.Append(Value::CreateStringValue("more ponies"));
+ EXPECT_TRUE(decoded->Equals(&expected));
+}
+
+TEST_F(UserPolicyCacheTest, Empty) {
+ UserPolicyCache cache(test_file());
+ PolicyMap empty;
+ EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
+ EXPECT_TRUE(empty.Equals(recommended_policy(cache)));
+ EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
+}
+
+TEST_F(UserPolicyCacheTest, LoadNoFile) {
+ UserPolicyCache cache(test_file());
+ cache.Load();
+ PolicyMap empty;
+ EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
+ EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
+}
+
+TEST_F(UserPolicyCacheTest, RejectFuture) {
+ scoped_ptr<em::PolicyFetchResponse> policy_response(
+ CreateHomepagePolicy("", base::Time::NowFromSystemTime() +
+ base::TimeDelta::FromMinutes(5),
+ em::PolicyOptions::MANDATORY));
+ WritePolicy(*policy_response);
+ UserPolicyCache cache(test_file());
+ cache.Load();
+ PolicyMap empty;
+ EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
+ EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
+}
+
+TEST_F(UserPolicyCacheTest, LoadWithFile) {
+ scoped_ptr<em::PolicyFetchResponse> policy_response(
+ CreateHomepagePolicy("", base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ WritePolicy(*policy_response);
+ UserPolicyCache cache(test_file());
+ cache.Load();
+ PolicyMap empty;
+ EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
+ EXPECT_NE(base::Time(), cache.last_policy_refresh_time());
+ EXPECT_GE(base::Time::Now(), cache.last_policy_refresh_time());
+}
+
+TEST_F(UserPolicyCacheTest, LoadWithData) {
+ scoped_ptr<em::PolicyFetchResponse> policy(
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ WritePolicy(*policy);
+ UserPolicyCache cache(test_file());
+ cache.Load();
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.example.com"));
+ EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
+}
+
+TEST_F(UserPolicyCacheTest, SetPolicy) {
+ UserPolicyCache cache(test_file());
+ em::PolicyFetchResponse* policy =
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY);
+ SetPolicy(&cache, policy, true);
+ em::PolicyFetchResponse* policy2 =
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY);
+ SetPolicy(&cache, policy2, false);
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.example.com"));
+ PolicyMap empty;
+ EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
+ EXPECT_TRUE(empty.Equals(recommended_policy(cache)));
+ policy = CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::RECOMMENDED);
+ SetPolicy(&cache, policy, true);
+ EXPECT_TRUE(expected.Equals(recommended_policy(cache)));
+ EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
+}
+
+TEST_F(UserPolicyCacheTest, ResetPolicy) {
+ UserPolicyCache cache(test_file());
+
+ em::PolicyFetchResponse* policy =
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY);
+ SetPolicy(&cache, policy, true);
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.example.com"));
+ EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
+
+ em::PolicyFetchResponse* empty_policy =
+ CreateHomepagePolicy("", base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY);
+ SetPolicy(&cache, empty_policy, true);
+ PolicyMap empty;
+ EXPECT_TRUE(empty.Equals(mandatory_policy(cache)));
+}
+
+TEST_F(UserPolicyCacheTest, PersistPolicy) {
+ {
+ UserPolicyCache cache(test_file());
+ scoped_ptr<em::PolicyFetchResponse> policy(
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ cache.SetPolicy(*policy);
+ }
+
+ loop_.RunAllPending();
+
+ EXPECT_TRUE(file_util::PathExists(test_file()));
+ UserPolicyCache cache(test_file());
+ cache.Load();
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.example.com"));
+ EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
+}
+
+TEST_F(UserPolicyCacheTest, FreshPolicyOverride) {
+ scoped_ptr<em::PolicyFetchResponse> policy(
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ WritePolicy(*policy);
+
+ UserPolicyCache cache(test_file());
+ em::PolicyFetchResponse* updated_policy =
+ CreateHomepagePolicy("http://www.chromium.org",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY);
+ SetPolicy(&cache, updated_policy, true);
+
+ cache.Load();
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.chromium.org"));
+ EXPECT_TRUE(expected.Equals(mandatory_policy(cache)));
+}
+
+} // namespace policy
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index d5000e7..3b1c6d8 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1463,8 +1463,8 @@
'browser/policy/asynchronous_policy_provider.h',
'browser/policy/browser_policy_connector.cc',
'browser/policy/browser_policy_connector.h',
- 'browser/policy/cloud_policy_cache.cc',
- 'browser/policy/cloud_policy_cache.h',
+ 'browser/policy/cloud_policy_cache_base.cc',
+ 'browser/policy/cloud_policy_cache_base.h',
'browser/policy/cloud_policy_controller.cc',
'browser/policy/cloud_policy_controller.h',
'browser/policy/cloud_policy_identity_strategy.cc',
@@ -1491,6 +1491,8 @@
'browser/policy/device_management_backend_impl.h',
'browser/policy/device_management_service.cc',
'browser/policy/device_management_service.h',
+ 'browser/policy/device_policy_cache.cc',
+ 'browser/policy/device_policy_cache.h',
'browser/policy/device_policy_identity_strategy.cc',
'browser/policy/device_policy_identity_strategy.h',
'browser/policy/device_token_fetcher.cc',
@@ -1509,6 +1511,8 @@
'browser/policy/policy_path_parser_win.cc',
'browser/policy/profile_policy_connector.cc',
'browser/policy/profile_policy_connector.h',
+ 'browser/policy/user_policy_cache.cc',
+ 'browser/policy/user_policy_cache.h',
'browser/policy/user_policy_identity_strategy.cc',
'browser/policy/user_policy_identity_strategy.h',
# TODO(danno): Find a better way to include these files
@@ -3317,6 +3321,7 @@
['exclude', 'browser/extensions/extension_tts_api_chromeos.cc'],
['exclude', 'browser/oom_priority_manager.cc'],
['exclude', 'browser/oom_priority_manager.h'],
+ ['exclude', 'browser/policy/device_policy_cache\\.(h|cc)'],
['exclude', 'browser/policy/device_policy_identity_strategy.cc'],
['exclude', 'browser/policy/device_policy_identity_strategy.h'],
['exclude', 'browser/policy/proto/chrome_device_policy\\.pb\\.(h|cc)'],
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index f3465dd..e62a921 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1390,12 +1390,12 @@
'browser/policy/asynchronous_policy_provider_unittest.cc',
'browser/policy/asynchronous_policy_test_base.cc',
'browser/policy/asynchronous_policy_test_base.h',
- 'browser/policy/cloud_policy_cache_unittest.cc',
'browser/policy/cloud_policy_controller_unittest.cc',
'browser/policy/config_dir_policy_provider_unittest.cc',
'browser/policy/configuration_policy_pref_store_unittest.cc',
'browser/policy/configuration_policy_provider_mac_unittest.cc',
'browser/policy/configuration_policy_provider_win_unittest.cc',
+ 'browser/policy/device_policy_cache_unittest.cc',
'browser/policy/device_token_fetcher_unittest.cc',
'browser/policy/file_based_policy_provider_unittest.cc',
'browser/policy/device_management_backend_mock.cc',
@@ -1410,6 +1410,7 @@
'browser/policy/mock_device_management_backend.h',
'browser/policy/policy_map_unittest.cc',
'browser/policy/policy_path_parser_unittest.cc',
+ 'browser/policy/user_policy_cache_unittest.cc',
'browser/preferences_mock_mac.cc',
'browser/preferences_mock_mac.h',
'browser/prefs/command_line_pref_store_unittest.cc',
@@ -1890,6 +1891,7 @@
}, { # else: chromeos == 0
'sources/': [
['exclude', '^browser/chromeos/'],
+ ['exclude', '^browser/policy/device_policy_cache_unittest.cc'],
['exclude', '^browser/ui/webui/chromeos/login'],
],
}],
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 7fcece0..ddf5bf29 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -148,10 +148,6 @@ const char kDebugPrint[] = "debug-print";
// device management backend.
const char kDeviceManagementUrl[] = "device-management-url";
-// Specifies the directory in which to store the shared device policy cache
-// file. If not specified, device policy will be disabled.
-const char kDevicePolicyCacheDir[] = "device-policy-cache-dir";
-
// Triggers a pletora of diagnostic modes.
const char kDiagnostics[] = "diagnostics";
@@ -1068,6 +1064,9 @@ const char kVersion[] = "version";
const char kWinHttpProxyResolver[] = "winhttp-proxy-resolver";
#if defined(OS_CHROMEOS)
+// Enables device policy support on ChromeOS.
+const char kEnableDevicePolicy[] = "enable-device-policy";
+
// Enable the redirection of viewable document requests to the Google
// Document Viewer.
const char kEnableGView[] = "enable-gview";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index d667e19..430f9f2 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -56,7 +56,6 @@ extern const char kCountry[];
extern const char kDebugDevTools[];
extern const char kDebugPrint[];
extern const char kDeviceManagementUrl[];
-extern const char kDevicePolicyCacheDir[];
extern const char kDiagnostics[];
extern const char kDisableAcceleratedCompositing[];
extern const char kDisableAcceleratedLayers[];
@@ -297,6 +296,7 @@ extern const char kVersion[];
extern const char kWinHttpProxyResolver[];
#if defined(OS_CHROMEOS)
+extern const char kEnableDevicePolicy[];
extern const char kEnableGView[];
extern const char kEnableLoginImages[];
extern const char kLoginManager[];