diff options
author | jkummerow@chromium.org <jkummerow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-29 14:19:27 +0000 |
---|---|---|
committer | jkummerow@chromium.org <jkummerow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-29 14:19:27 +0000 |
commit | 82e4080d97b52798c3605fa73979c0bdf0fdc597 (patch) | |
tree | 56f9ce7093b4faea11ae8528842b5b7fa5c5b72a | |
parent | 34daae316805e93a5d61faa6124e1a2f5172676e (diff) | |
download | chromium_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
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, - ×tamp); - 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, - ×tamp); - 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(), ×tamp, 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[]; |