summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjkummerow@chromium.org <jkummerow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-17 13:25:23 +0000
committerjkummerow@chromium.org <jkummerow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-17 13:25:23 +0000
commitf8636972b3e1d3a9bbf7f86b6708c0f5d66571ae (patch)
tree1cc358fe9fc57efd09b612b261d484ad359bf1fe /chrome/browser
parentd20e0b986707dd49ae7a2cad347f4e50140ec86e (diff)
downloadchromium_src-f8636972b3e1d3a9bbf7f86b6708c0f5d66571ae.zip
chromium_src-f8636972b3e1d3a9bbf7f86b6708c0f5d66571ae.tar.gz
chromium_src-f8636972b3e1d3a9bbf7f86b6708c0f5d66571ae.tar.bz2
New policy protobuf protocol.
(Third attempt to land http://codereview.chromium.org/6409040/ -- now without memory leaks) - cloud_policy.proto autogenerated from policy_templates.json - C++ method decoding the protobuf also autogenerated from policy_templates.json - changed policy fetching mechanism to fetch new-style policy protobufs BUG=68309, chromium-os:11253, chromium-os:11255 TEST=CloudPolicyCacheTest.*; also manual test against python testserver Review URL: http://codereview.chromium.org/6532019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75259 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/policy/asynchronous_policy_provider.cc2
-rw-r--r--chrome/browser/policy/cloud_policy_cache.cc417
-rw-r--r--chrome/browser/policy/cloud_policy_cache.h (renamed from chrome/browser/policy/device_management_policy_cache.h)76
-rw-r--r--chrome/browser/policy/cloud_policy_cache_unittest.cc620
-rw-r--r--chrome/browser/policy/configuration_policy_provider.cc15
-rw-r--r--chrome/browser/policy/configuration_policy_provider.h11
-rw-r--r--chrome/browser/policy/configuration_policy_store_interface.h2
-rw-r--r--chrome/browser/policy/device_management_backend.h10
-rw-r--r--chrome/browser/policy/device_management_backend_impl.cc134
-rw-r--r--chrome/browser/policy/device_management_backend_impl.h10
-rw-r--r--chrome/browser/policy/device_management_backend_mock.h1
-rw-r--r--chrome/browser/policy/device_management_policy_cache.cc270
-rw-r--r--chrome/browser/policy/device_management_policy_cache_unittest.cc321
-rw-r--r--chrome/browser/policy/device_management_policy_provider.cc64
-rw-r--r--chrome/browser/policy/device_management_policy_provider.h9
-rw-r--r--chrome/browser/policy/device_management_policy_provider_unittest.cc107
-rw-r--r--chrome/browser/policy/mock_configuration_policy_provider.cc15
-rw-r--r--chrome/browser/policy/mock_configuration_policy_provider.h3
-rw-r--r--chrome/browser/policy/mock_configuration_policy_store.cc10
-rw-r--r--chrome/browser/policy/mock_configuration_policy_store.h3
-rw-r--r--chrome/browser/policy/mock_device_management_backend.h25
-rw-r--r--chrome/browser/policy/policy_map.cc73
-rw-r--r--chrome/browser/policy/policy_map.h58
-rw-r--r--chrome/browser/policy/policy_map_unittest.cc68
-rw-r--r--chrome/browser/policy/profile_policy_context.cc5
-rw-r--r--chrome/browser/policy/proto/cloud_policy.proto221
-rw-r--r--chrome/browser/policy/proto/device_management_backend.proto132
-rw-r--r--chrome/browser/policy/proto/device_management_local.proto12
-rw-r--r--chrome/browser/policy/proto/device_management_proto.gyp81
29 files changed, 1669 insertions, 1106 deletions
diff --git a/chrome/browser/policy/asynchronous_policy_provider.cc b/chrome/browser/policy/asynchronous_policy_provider.cc
index e697b05..9b050ad 100644
--- a/chrome/browser/policy/asynchronous_policy_provider.cc
+++ b/chrome/browser/policy/asynchronous_policy_provider.cc
@@ -25,7 +25,7 @@ bool AsynchronousPolicyProvider::Provide(
ConfigurationPolicyStoreInterface* store) {
DCHECK(CalledOnValidThread());
DCHECK(loader_->policy());
- DecodePolicyValueTree(loader_->policy(), store);
+ ApplyPolicyValueTree(loader_->policy(), store);
return true;
}
diff --git a/chrome/browser/policy/cloud_policy_cache.cc b/chrome/browser/policy/cloud_policy_cache.cc
new file mode 100644
index 0000000..b81fb81
--- /dev/null
+++ b/chrome/browser/policy/cloud_policy_cache.cc
@@ -0,0 +1,417 @@
+// 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/browser_thread.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_constants.h"
+#include "chrome/browser/policy/proto/device_management_local.pb.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);
+
+// Saves policy information to a file.
+class PersistPolicyTask : public Task {
+ public:
+ PersistPolicyTask(const FilePath& path,
+ const em::CloudPolicyResponse* 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::CloudPolicyResponse> 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),
+ fresh_policy_(false),
+ is_unmanaged_(false),
+ has_device_policy_(false) {
+}
+
+CloudPolicyCache::~CloudPolicyCache() {}
+
+void CloudPolicyCache::LoadPolicyFromFile() {
+ // 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_) || fresh_policy_) {
+ return;
+ }
+
+ // Read the protobuf from the file.
+ std::string data;
+ if (!file_util::ReadFileToString(backing_file_path_, &data)) {
+ LOG(WARNING) << "Failed to read policy data from "
+ << backing_file_path_.value();
+ return;
+ }
+
+ em::CachedCloudPolicyResponse cached_response;
+ if (!cached_response.ParseFromArray(data.c_str(), data.size())) {
+ LOG(WARNING) << "Failed to parse policy data read from "
+ << backing_file_path_.value();
+ return;
+ }
+ base::Time timestamp;
+ PolicyMap mandatory_policy;
+ PolicyMap recommended_policy;
+ is_unmanaged_ = cached_response.unmanaged();
+ if (is_unmanaged_ || cached_response.has_device_policy())
+ timestamp = base::Time::FromTimeT(cached_response.timestamp());
+ if (cached_response.has_cloud_policy()) {
+ DCHECK(!is_unmanaged_);
+ bool ok = DecodePolicyResponse(cached_response.cloud_policy(),
+ &mandatory_policy,
+ &recommended_policy,
+ &timestamp);
+ if (!ok) {
+ LOG(WARNING) << "Decoding policy data failed.";
+ return;
+ }
+ }
+ if (timestamp > base::Time::NowFromSystemTime()) {
+ LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value()
+ << ", file is from the future.";
+ return;
+ }
+ // Swap in the new policy information.
+ if (is_unmanaged_) {
+ base::AutoLock lock(lock_);
+ last_policy_refresh_time_ = timestamp;
+ return;
+ } else if (cached_response.has_cloud_policy()) {
+ if (!fresh_policy_) {
+ base::AutoLock lock(lock_);
+ // The use of |Swap()| here makes sure that the old value in
+ // |mandatory_policy_| is deleted when |mandatory_policy| goes out of
+ // scope. (The same applies to |SetPolicy()| below.)
+ mandatory_policy_.Swap(&mandatory_policy);
+ recommended_policy_.Swap(&recommended_policy);
+ last_policy_refresh_time_ = timestamp;
+ has_device_policy_ = false;
+ }
+ } else if (cached_response.has_device_policy()) {
+ scoped_ptr<DictionaryValue> value(
+ DecodeDevicePolicy(cached_response.device_policy()));
+ if (!fresh_policy_) {
+ base::AutoLock lock(lock_);
+ device_policy_.reset(value.release());
+ last_policy_refresh_time_ = timestamp;
+ has_device_policy_ = true;
+ }
+ }
+}
+
+bool CloudPolicyCache::SetPolicy(const em::CloudPolicyResponse& policy) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ is_unmanaged_ = false;
+ base::Time timestamp;
+ PolicyMap mandatory_policy;
+ PolicyMap recommended_policy;
+ bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy,
+ &timestamp);
+ if (!ok) {
+ // TODO(jkummerow): Signal error to PolicyProvider.
+ return false;
+ }
+ const bool new_policy_differs =
+ !mandatory_policy.Equals(mandatory_policy_) ||
+ !recommended_policy.Equals(recommended_policy_);
+ {
+ base::AutoLock lock(lock_);
+ mandatory_policy_.Swap(&mandatory_policy);
+ recommended_policy_.Swap(&recommended_policy);
+ fresh_policy_ = true;
+ last_policy_refresh_time_ = timestamp;
+ has_device_policy_ = false;
+ }
+
+ 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::CloudPolicyResponse* policy_copy = new em::CloudPolicyResponse;
+ policy_copy->CopyFrom(policy);
+ BrowserThread::PostTask(
+ BrowserThread::FILE,
+ FROM_HERE,
+ new PersistPolicyTask(backing_file_path_, policy_copy, NULL, false));
+ }
+ return new_policy_differs;
+}
+
+bool CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ is_unmanaged_ = false;
+ DictionaryValue* value = DecodeDevicePolicy(policy);
+ const bool new_policy_differs = !(value->Equals(device_policy_.get()));
+ base::Time now(base::Time::NowFromSystemTime());
+ {
+ base::AutoLock lock(lock_);
+ device_policy_.reset(value);
+ fresh_policy_ = true;
+ last_policy_refresh_time_ = now;
+ has_device_policy_ = true;
+ }
+
+ 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));
+ return new_policy_differs;
+}
+
+DictionaryValue* CloudPolicyCache::GetDevicePolicy() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ base::AutoLock lock(lock_);
+ return device_policy_->DeepCopy();
+}
+
+const PolicyMap* CloudPolicyCache::GetMandatoryPolicy() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return &mandatory_policy_;
+}
+
+const PolicyMap* CloudPolicyCache::GetRecommendedPolicy() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return &recommended_policy_;
+}
+
+void CloudPolicyCache::SetUnmanaged() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ is_unmanaged_ = true;
+ {
+ base::AutoLock lock(lock_);
+ mandatory_policy_.Clear();
+ recommended_policy_.Clear();
+ device_policy_.reset(new DictionaryValue);
+ last_policy_refresh_time_ = base::Time::NowFromSystemTime();
+ }
+ BrowserThread::PostTask(
+ BrowserThread::FILE,
+ FROM_HERE,
+ new PersistPolicyTask(backing_file_path_, NULL, NULL, true));
+}
+
+// static
+bool CloudPolicyCache::DecodePolicyResponse(
+ const em::CloudPolicyResponse& policy_response,
+ PolicyMap* mandatory,
+ PolicyMap* recommended,
+ base::Time* timestamp) {
+ std::string data = policy_response.signed_response();
+
+ if (!VerifySignature(policy_response.signature(), data,
+ policy_response.certificate_chain())) {
+ LOG(WARNING) << "Failed to verify signature.";
+ return false;
+ }
+
+ em::SignedCloudPolicyResponse response;
+ if (!response.ParseFromArray(data.c_str(), data.size())) {
+ LOG(WARNING) << "Failed to parse SignedCloudPolicyResponse protobuf.";
+ return false;
+ }
+
+ // TODO(jkummerow): Verify response.device_token(). Needs final specification
+ // which token we're actually sending / expecting to get back.
+
+ // TODO(jkummerow): Store response.device_name(), if we decide to transfer
+ // it from the server to the client.
+
+ DCHECK(timestamp);
+ *timestamp = base::Time::FromTimeT(response.timestamp());
+ DecodePolicy(response.settings(), 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/device_management_policy_cache.h b/chrome/browser/policy/cloud_policy_cache.h
index 50441eb..518e3f0 100644
--- a/chrome/browser/policy/device_management_policy_cache.h
+++ b/chrome/browser/policy/cloud_policy_cache.h
@@ -1,9 +1,11 @@
-// 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.
-#ifndef CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_POLICY_CACHE_H_
-#define CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_POLICY_CACHE_H_
+#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"
@@ -11,11 +13,17 @@
#include "base/scoped_ptr.h"
#include "base/synchronization/lock.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;
@@ -25,10 +33,10 @@ namespace em = enterprise_management;
// 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 DeviceManagementPolicyCache {
+class CloudPolicyCache {
public:
- explicit DeviceManagementPolicyCache(const FilePath& backing_file_path);
- ~DeviceManagementPolicyCache();
+ explicit CloudPolicyCache(const FilePath& backing_file_path);
+ ~CloudPolicyCache();
// Loads policy information from the backing file. Non-existing or erroneous
// cache files are ignored.
@@ -36,25 +44,50 @@ class DeviceManagementPolicyCache {
// Resets the policy information. Returns true if the new policy is different
// from the previously stored policy.
- bool SetPolicy(const em::DevicePolicyResponse& policy);
+ bool SetPolicy(const em::CloudPolicyResponse& policy);
+ bool SetDevicePolicy(const em::DevicePolicyResponse& policy);
// Gets the policy information. Ownership of the return value is transferred
// to the caller.
- DictionaryValue* GetPolicy();
+ DictionaryValue* GetDevicePolicy();
+ const PolicyMap* GetMandatoryPolicy() const;
+ const PolicyMap* GetRecommendedPolicy() const;
- void SetDeviceUnmanaged();
- bool is_device_unmanaged() const {
- return is_device_unmanaged_;
+ void SetUnmanaged();
+ bool is_unmanaged() const {
+ return is_unmanaged_;
}
- // Returns the time as which the policy was last fetched.
+ // 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:
+ friend class CloudPolicyCacheTest;
friend class DeviceManagementPolicyCacheDecodeTest;
- FRIEND_TEST_ALL_PREFIXES(DeviceManagementPolicyCacheDecodeTest, DecodePolicy);
+
+ // 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::CloudPolicyResponse& 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
@@ -67,23 +100,30 @@ class DeviceManagementPolicyCache {
// Decodes a policy message and returns it in Value representation. Ownership
// of the returned dictionary is transferred to the caller.
- static DictionaryValue* DecodePolicy(
+ 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_;
- // Protects |policy_|.
+ // Protects both |mandatory_policy_| and |recommended_policy_| as well as
+ // |device_policy_|.
base::Lock lock_;
// Policy key-value information.
- scoped_ptr<DictionaryValue> policy_;
+ PolicyMap mandatory_policy_;
+ PolicyMap recommended_policy_;
+ scoped_ptr<DictionaryValue> device_policy_;
// Tracks whether the store received a SetPolicy() call, which overrides any
// information loaded from the file.
bool fresh_policy_;
- bool is_device_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_;
@@ -91,4 +131,4 @@ class DeviceManagementPolicyCache {
} // namespace policy
-#endif // CHROME_BROWSER_POLICY_DEVICE_MANAGEMENT_POLICY_CACHE_H_
+#endif // CHROME_BROWSER_POLICY_CLOUD_POLICY_CACHE_H_
diff --git a/chrome/browser/policy/cloud_policy_cache_unittest.cc b/chrome/browser/policy/cloud_policy_cache_unittest.cc
new file mode 100644
index 0000000..d9fc768
--- /dev/null
+++ b/chrome/browser/policy/cloud_policy_cache_unittest.cc
@@ -0,0 +1,620 @@
+// 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/message_loop.h"
+#include "base/scoped_temp_dir.h"
+#include "base/values.h"
+#include "chrome/browser/browser_thread.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 "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);
+
+// 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) CloudPolicyResponse 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::CloudPolicyResponse* CreateHomepagePolicy(
+ const std::string& homepage,
+ const base::Time& timestamp,
+ const em::PolicyOptions::PolicyMode policy_mode) {
+ em::SignedCloudPolicyResponse signed_response;
+ if (homepage != "") {
+ em::CloudPolicySettings* settings = signed_response.mutable_settings();
+ em::HomepageLocationProto* homepagelocation_proto =
+ settings->mutable_homepagelocation();
+ homepagelocation_proto->set_homepagelocation(homepage);
+ homepagelocation_proto->mutable_policy_options()->set_mode(policy_mode);
+ }
+ signed_response.set_timestamp(timestamp.ToTimeT());
+ std::string serialized_signed_response;
+ EXPECT_TRUE(signed_response.SerializeToString(&serialized_signed_response));
+
+ em::CloudPolicyResponse* response = new em::CloudPolicyResponse;
+ response->set_signed_response(serialized_signed_response);
+ // TODO(jkummerow): Set proper certificate_chain and signature (when
+ // implementing support for signature verification).
+ response->set_signature("TODO");
+ response->add_certificate_chain("TODO");
+ return response;
+ }
+
+ void WritePolicy(const em::CloudPolicyResponse& 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));
+ }
+
+ FilePath test_file() {
+ return temp_dir_.path().AppendASCII("CloudPolicyCacheTest");
+ }
+
+ MessageLoop loop_;
+
+ 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(*cache.GetMandatoryPolicy()));
+ EXPECT_TRUE(empty.Equals(*cache.GetRecommendedPolicy()));
+ EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
+}
+
+TEST_F(CloudPolicyCacheTest, LoadNoFile) {
+ CloudPolicyCache cache(test_file());
+ cache.LoadPolicyFromFile();
+ PolicyMap empty;
+ EXPECT_TRUE(empty.Equals(*cache.GetMandatoryPolicy()));
+ EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
+}
+
+TEST_F(CloudPolicyCacheTest, RejectFuture) {
+ scoped_ptr<em::CloudPolicyResponse> policy_response(
+ CreateHomepagePolicy("", base::Time::NowFromSystemTime() +
+ base::TimeDelta::FromMinutes(5),
+ em::PolicyOptions::MANDATORY));
+ WritePolicy(*policy_response);
+ CloudPolicyCache cache(test_file());
+ cache.LoadPolicyFromFile();
+ PolicyMap empty;
+ EXPECT_TRUE(empty.Equals(*cache.GetMandatoryPolicy()));
+ EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
+}
+
+TEST_F(CloudPolicyCacheTest, LoadWithFile) {
+ scoped_ptr<em::CloudPolicyResponse> policy_response(
+ CreateHomepagePolicy("", base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ WritePolicy(*policy_response);
+ CloudPolicyCache cache(test_file());
+ cache.LoadPolicyFromFile();
+ PolicyMap empty;
+ EXPECT_TRUE(empty.Equals(*cache.GetMandatoryPolicy()));
+ 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::CloudPolicyResponse> policy(
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ WritePolicy(*policy);
+ CloudPolicyCache cache(test_file());
+ cache.LoadPolicyFromFile();
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.example.com"));
+ EXPECT_TRUE(expected.Equals(*cache.GetMandatoryPolicy()));
+}
+
+TEST_F(CloudPolicyCacheTest, SetPolicy) {
+ CloudPolicyCache cache(test_file());
+ scoped_ptr<em::CloudPolicyResponse> policy(
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ EXPECT_TRUE(cache.SetPolicy(*policy));
+ scoped_ptr<em::CloudPolicyResponse> policy2(
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ EXPECT_FALSE(cache.SetPolicy(*policy2));
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.example.com"));
+ PolicyMap empty;
+ EXPECT_TRUE(expected.Equals(*cache.GetMandatoryPolicy()));
+ EXPECT_TRUE(empty.Equals(*cache.GetRecommendedPolicy()));
+ policy.reset(CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::RECOMMENDED));
+ EXPECT_TRUE(cache.SetPolicy(*policy));
+ EXPECT_TRUE(expected.Equals(*cache.GetRecommendedPolicy()));
+ EXPECT_TRUE(empty.Equals(*cache.GetMandatoryPolicy()));
+}
+
+TEST_F(CloudPolicyCacheTest, ResetPolicy) {
+ CloudPolicyCache cache(test_file());
+
+ scoped_ptr<em::CloudPolicyResponse> policy(
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ EXPECT_TRUE(cache.SetPolicy(*policy));
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.example.com"));
+ EXPECT_TRUE(expected.Equals(*cache.GetMandatoryPolicy()));
+
+ scoped_ptr<em::CloudPolicyResponse> empty_policy(
+ CreateHomepagePolicy("", base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ EXPECT_TRUE(cache.SetPolicy(*empty_policy));
+ PolicyMap empty;
+ EXPECT_TRUE(empty.Equals(*cache.GetMandatoryPolicy()));
+}
+
+TEST_F(CloudPolicyCacheTest, PersistPolicy) {
+ {
+ CloudPolicyCache cache(test_file());
+ scoped_ptr<em::CloudPolicyResponse> 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.LoadPolicyFromFile();
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.example.com"));
+ EXPECT_TRUE(expected.Equals(*cache.GetMandatoryPolicy()));
+}
+
+TEST_F(CloudPolicyCacheTest, FreshPolicyOverride) {
+ scoped_ptr<em::CloudPolicyResponse> policy(
+ CreateHomepagePolicy("http://www.example.com",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ WritePolicy(*policy);
+
+ CloudPolicyCache cache(test_file());
+ scoped_ptr<em::CloudPolicyResponse> updated_policy(
+ CreateHomepagePolicy("http://www.chromium.org",
+ base::Time::NowFromSystemTime(),
+ em::PolicyOptions::MANDATORY));
+ EXPECT_TRUE(cache.SetPolicy(*updated_policy));
+
+ cache.LoadPolicyFromFile();
+ PolicyMap expected;
+ expected.Set(kPolicyHomepageLocation,
+ Value::CreateStringValue("http://www.chromium.org"));
+ EXPECT_TRUE(expected.Equals(*cache.GetMandatoryPolicy()));
+}
+
+} // 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");
+ }
+
+ protected:
+ MessageLoop loop_;
+
+ private:
+ ScopedTempDir temp_dir_;
+ BrowserThread ui_thread_;
+ BrowserThread file_thread_;
+};
+
+TEST_F(DeviceManagementPolicyCacheTest, Empty) {
+ CloudPolicyCache cache(test_file());
+ DictionaryValue empty;
+ scoped_ptr<Value> policy(cache.GetDevicePolicy());
+ EXPECT_TRUE(empty.Equals(policy.get()));
+ EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
+}
+
+TEST_F(DeviceManagementPolicyCacheTest, LoadNoFile) {
+ CloudPolicyCache cache(test_file());
+ cache.LoadPolicyFromFile();
+ DictionaryValue empty;
+ scoped_ptr<Value> policy(cache.GetDevicePolicy());
+ EXPECT_TRUE(empty.Equals(policy.get()));
+ 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.LoadPolicyFromFile();
+ DictionaryValue empty;
+ scoped_ptr<Value> policy(cache.GetDevicePolicy());
+ EXPECT_TRUE(empty.Equals(policy.get()));
+ 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.LoadPolicyFromFile();
+ DictionaryValue empty;
+ scoped_ptr<Value> policy(cache.GetDevicePolicy());
+ EXPECT_TRUE(empty.Equals(policy.get()));
+ 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.LoadPolicyFromFile();
+ DictionaryValue expected;
+ expected.Set("HomepageLocation",
+ Value::CreateStringValue("http://www.example.com"));
+ scoped_ptr<Value> policy_value(cache.GetDevicePolicy());
+ EXPECT_TRUE(expected.Equals(policy_value.get()));
+}
+
+TEST_F(DeviceManagementPolicyCacheTest, SetDevicePolicy) {
+ CloudPolicyCache cache(test_file());
+ em::DevicePolicyResponse policy;
+ AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
+ EXPECT_TRUE(cache.SetDevicePolicy(policy));
+ em::DevicePolicyResponse policy2;
+ AddStringPolicy(&policy2, "HomepageLocation", "http://www.example.com");
+ EXPECT_FALSE(cache.SetDevicePolicy(policy2));
+ DictionaryValue expected;
+ expected.Set("HomepageLocation",
+ Value::CreateStringValue("http://www.example.com"));
+ scoped_ptr<Value> policy_value(cache.GetDevicePolicy());
+ EXPECT_TRUE(expected.Equals(policy_value.get()));
+}
+
+TEST_F(DeviceManagementPolicyCacheTest, ResetPolicy) {
+ CloudPolicyCache cache(test_file());
+
+ em::DevicePolicyResponse policy;
+ AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
+ EXPECT_TRUE(cache.SetDevicePolicy(policy));
+ DictionaryValue expected;
+ expected.Set("HomepageLocation",
+ Value::CreateStringValue("http://www.example.com"));
+ scoped_ptr<Value> policy_value(cache.GetDevicePolicy());
+ EXPECT_TRUE(expected.Equals(policy_value.get()));
+
+ EXPECT_TRUE(cache.SetDevicePolicy(em::DevicePolicyResponse()));
+ policy_value.reset(cache.GetDevicePolicy());
+ DictionaryValue empty;
+ EXPECT_TRUE(empty.Equals(policy_value.get()));
+}
+
+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.LoadPolicyFromFile();
+ DictionaryValue expected;
+ expected.Set("HomepageLocation",
+ Value::CreateStringValue("http://www.example.com"));
+ scoped_ptr<Value> policy_value(cache.GetDevicePolicy());
+ EXPECT_TRUE(expected.Equals(policy_value.get()));
+}
+
+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");
+ EXPECT_TRUE(cache.SetDevicePolicy(updated_policy));
+
+ cache.LoadPolicyFromFile();
+ DictionaryValue expected;
+ expected.Set("HomepageLocation",
+ Value::CreateStringValue("http://www.chromium.org"));
+ scoped_ptr<Value> policy_value(cache.GetDevicePolicy());
+ EXPECT_TRUE(expected.Equals(policy_value.get()));
+}
+
+// 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/configuration_policy_provider.cc b/chrome/browser/policy/configuration_policy_provider.cc
index 82ca864..3f8e3fd 100644
--- a/chrome/browser/policy/configuration_policy_provider.cc
+++ b/chrome/browser/policy/configuration_policy_provider.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/policy/configuration_policy_provider.h"
#include "base/values.h"
+#include "chrome/browser/policy/policy_map.h"
namespace policy {
@@ -21,7 +22,7 @@ bool ConfigurationPolicyProvider::IsInitializationComplete() const {
return true;
}
-void ConfigurationPolicyProvider::DecodePolicyValueTree(
+void ConfigurationPolicyProvider::ApplyPolicyValueTree(
const DictionaryValue* policies,
ConfigurationPolicyStoreInterface* store) {
const PolicyDefinitionList* policy_list(policy_definition_list());
@@ -36,6 +37,18 @@ void ConfigurationPolicyProvider::DecodePolicyValueTree(
// supports it.
}
+void ConfigurationPolicyProvider::ApplyPolicyMap(
+ const PolicyMap* policies,
+ ConfigurationPolicyStoreInterface* store) {
+ const PolicyDefinitionList* policy_list(policy_definition_list());
+ for (const PolicyDefinitionList::Entry* i = policy_list->begin;
+ i != policy_list->end; ++i) {
+ const Value* value = policies->Get(i->policy_type);
+ if (value && value->IsType(i->value_type))
+ store->Apply(i->policy_type, value->DeepCopy());
+ }
+}
+
// Class ConfigurationPolicyObserverRegistrar.
ConfigurationPolicyObserverRegistrar::ConfigurationPolicyObserverRegistrar()
diff --git a/chrome/browser/policy/configuration_policy_provider.h b/chrome/browser/policy/configuration_policy_provider.h
index af2cddf..32fc885 100644
--- a/chrome/browser/policy/configuration_policy_provider.h
+++ b/chrome/browser/policy/configuration_policy_provider.h
@@ -6,15 +6,19 @@
#define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_PROVIDER_H_
#pragma once
+#include <map>
#include <string>
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/policy/configuration_policy_store_interface.h"
+#include "policy/configuration_policy_type.h"
namespace policy {
+class PolicyMap;
+
// A mostly-abstract super class for platform-specific policy providers.
// Platform-specific policy providers (Windows Group Policy, gconf,
// etc.) should implement a subclass of this class.
@@ -59,9 +63,14 @@ class ConfigurationPolicyProvider {
protected:
// Decodes the value tree and writes the configuration to the given |store|.
- void DecodePolicyValueTree(const DictionaryValue* policies,
+ void ApplyPolicyValueTree(const DictionaryValue* policies,
ConfigurationPolicyStoreInterface* store);
+ // Writes the configuration found in the already-decoded map |policies| to
+ // the given |store|.
+ void ApplyPolicyMap(const PolicyMap* policies,
+ ConfigurationPolicyStoreInterface* store);
+
const PolicyDefinitionList* policy_definition_list() const {
return policy_definition_list_;
}
diff --git a/chrome/browser/policy/configuration_policy_store_interface.h b/chrome/browser/policy/configuration_policy_store_interface.h
index d3261a3..1d3bf43 100644
--- a/chrome/browser/policy/configuration_policy_store_interface.h
+++ b/chrome/browser/policy/configuration_policy_store_interface.h
@@ -7,8 +7,6 @@
#pragma once
#include "base/basictypes.h"
-// configuration_policy_type.h is generated. See policy_template.json for
-// policy definitions.
#include "policy/configuration_policy_type.h"
class Value;
diff --git a/chrome/browser/policy/device_management_backend.h b/chrome/browser/policy/device_management_backend.h
index 114c7b7..f2fec0d 100644
--- a/chrome/browser/policy/device_management_backend.h
+++ b/chrome/browser/policy/device_management_backend.h
@@ -75,8 +75,12 @@ class DeviceManagementBackend : base::NonThreadSafe {
public:
virtual ~DevicePolicyResponseDelegate() {}
+ // Deprecated in favor of HandleCloudPolicyResponse. To be removed once
+ // DMServer supports the new protocol.
virtual void HandlePolicyResponse(
const em::DevicePolicyResponse& response) = 0;
+ virtual void HandleCloudPolicyResponse(
+ const em::CloudPolicyResponse& response) = 0;
virtual void OnError(ErrorCode code) = 0;
protected:
@@ -106,6 +110,12 @@ class DeviceManagementBackend : base::NonThreadSafe {
const em::DevicePolicyRequest& request,
DevicePolicyResponseDelegate* delegate) = 0;
+ virtual void ProcessCloudPolicyRequest(
+ const std::string& device_management_token,
+ const std::string& device_id,
+ const em::CloudPolicyRequest& request,
+ DevicePolicyResponseDelegate* delegate) = 0;
+
protected:
DeviceManagementBackend() {}
diff --git a/chrome/browser/policy/device_management_backend_impl.cc b/chrome/browser/policy/device_management_backend_impl.cc
index ed75f3f..b01cbf8 100644
--- a/chrome/browser/policy/device_management_backend_impl.cc
+++ b/chrome/browser/policy/device_management_backend_impl.cc
@@ -27,6 +27,8 @@ const char DeviceManagementBackendImpl::kValueRequestRegister[] = "register";
const char DeviceManagementBackendImpl::kValueRequestUnregister[] =
"unregister";
const char DeviceManagementBackendImpl::kValueRequestPolicy[] = "policy";
+const char DeviceManagementBackendImpl::kValueRequestCloudPolicy[] =
+ "cloud_policy";
const char DeviceManagementBackendImpl::kValueDeviceType[] = "Chrome OS";
const char DeviceManagementBackendImpl::kValueAppType[] = "Chrome";
@@ -170,7 +172,10 @@ void DeviceManagementJobBase::HandleResponse(
}
if (response_code != 200) {
- OnError(DeviceManagementBackend::kErrorHttpStatus);
+ if (response_code == 400)
+ OnError(DeviceManagementBackend::kErrorRequestInvalid);
+ else
+ OnError(DeviceManagementBackend::kErrorHttpStatus);
return;
}
@@ -230,7 +235,17 @@ class DeviceManagementRegisterJob : public DeviceManagementJobBase {
const std::string& auth_token,
const std::string& device_id,
const em::DeviceRegisterRequest& request,
- DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate);
+ DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate)
+ : DeviceManagementJobBase(
+ backend_impl,
+ DeviceManagementBackendImpl::kValueRequestRegister,
+ device_id),
+ delegate_(delegate) {
+ SetAuthToken(auth_token);
+ em::DeviceManagementRequest request_wrapper;
+ request_wrapper.mutable_register_request()->CopyFrom(request);
+ SetPayload(request_wrapper);
+ }
virtual ~DeviceManagementRegisterJob() {}
private:
@@ -247,32 +262,25 @@ class DeviceManagementRegisterJob : public DeviceManagementJobBase {
DISALLOW_COPY_AND_ASSIGN(DeviceManagementRegisterJob);
};
-DeviceManagementRegisterJob::DeviceManagementRegisterJob(
- DeviceManagementBackendImpl* backend_impl,
- const std::string& auth_token,
- const std::string& device_id,
- const em::DeviceRegisterRequest& request,
- DeviceManagementBackend::DeviceRegisterResponseDelegate* delegate)
- : DeviceManagementJobBase(
- backend_impl,
- DeviceManagementBackendImpl::kValueRequestRegister,
- device_id),
- delegate_(delegate) {
- SetAuthToken(auth_token);
- em::DeviceManagementRequest request_wrapper;
- request_wrapper.mutable_register_request()->CopyFrom(request);
- SetPayload(request_wrapper);
-}
-
// Handles device unregistration jobs.
class DeviceManagementUnregisterJob : public DeviceManagementJobBase {
public:
DeviceManagementUnregisterJob(
DeviceManagementBackendImpl* backend_impl,
- const std::string& device_id,
const std::string& device_management_token,
+ const std::string& device_id,
const em::DeviceUnregisterRequest& request,
- DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate);
+ DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate)
+ : DeviceManagementJobBase(
+ backend_impl,
+ DeviceManagementBackendImpl::kValueRequestUnregister,
+ device_id),
+ delegate_(delegate) {
+ SetDeviceManagementToken(device_management_token);
+ em::DeviceManagementRequest request_wrapper;
+ request_wrapper.mutable_unregister_request()->CopyFrom(request);
+ SetPayload(request_wrapper);
+ }
virtual ~DeviceManagementUnregisterJob() {}
private:
@@ -289,23 +297,6 @@ class DeviceManagementUnregisterJob : public DeviceManagementJobBase {
DISALLOW_COPY_AND_ASSIGN(DeviceManagementUnregisterJob);
};
-DeviceManagementUnregisterJob::DeviceManagementUnregisterJob(
- DeviceManagementBackendImpl* backend_impl,
- const std::string& device_management_token,
- const std::string& device_id,
- const em::DeviceUnregisterRequest& request,
- DeviceManagementBackend::DeviceUnregisterResponseDelegate* delegate)
- : DeviceManagementJobBase(
- backend_impl,
- DeviceManagementBackendImpl::kValueRequestUnregister,
- device_id),
- delegate_(delegate) {
- SetDeviceManagementToken(device_management_token);
- em::DeviceManagementRequest request_wrapper;
- request_wrapper.mutable_unregister_request()->CopyFrom(request);
- SetPayload(request_wrapper);
-}
-
// Handles policy request jobs.
class DeviceManagementPolicyJob : public DeviceManagementJobBase {
public:
@@ -314,7 +305,17 @@ class DeviceManagementPolicyJob : public DeviceManagementJobBase {
const std::string& device_management_token,
const std::string& device_id,
const em::DevicePolicyRequest& request,
- DeviceManagementBackend::DevicePolicyResponseDelegate* delegate);
+ DeviceManagementBackend::DevicePolicyResponseDelegate* delegate)
+ : DeviceManagementJobBase(
+ backend_impl,
+ DeviceManagementBackendImpl::kValueRequestPolicy,
+ device_id),
+ delegate_(delegate) {
+ SetDeviceManagementToken(device_management_token);
+ em::DeviceManagementRequest request_wrapper;
+ request_wrapper.mutable_policy_request()->CopyFrom(request);
+ SetPayload(request_wrapper);
+ }
virtual ~DeviceManagementPolicyJob() {}
private:
@@ -331,22 +332,40 @@ class DeviceManagementPolicyJob : public DeviceManagementJobBase {
DISALLOW_COPY_AND_ASSIGN(DeviceManagementPolicyJob);
};
-DeviceManagementPolicyJob::DeviceManagementPolicyJob(
- DeviceManagementBackendImpl* backend_impl,
- const std::string& device_management_token,
- const std::string& device_id,
- const em::DevicePolicyRequest& request,
- DeviceManagementBackend::DevicePolicyResponseDelegate* delegate)
- : DeviceManagementJobBase(
+// Handles cloud policy request jobs.
+class CloudPolicyJob : public DeviceManagementJobBase {
+ public:
+ CloudPolicyJob(
+ DeviceManagementBackendImpl* backend_impl,
+ const std::string& device_management_token,
+ const std::string& device_id,
+ const em::CloudPolicyRequest& request,
+ DeviceManagementBackend::DevicePolicyResponseDelegate* delegate)
+ : DeviceManagementJobBase(
backend_impl,
- DeviceManagementBackendImpl::kValueRequestPolicy,
+ DeviceManagementBackendImpl::kValueRequestCloudPolicy,
device_id),
- delegate_(delegate) {
- SetDeviceManagementToken(device_management_token);
- em::DeviceManagementRequest request_wrapper;
- request_wrapper.mutable_policy_request()->CopyFrom(request);
- SetPayload(request_wrapper);
-}
+ delegate_(delegate) {
+ SetDeviceManagementToken(device_management_token);
+ em::DeviceManagementRequest request_wrapper;
+ request_wrapper.mutable_cloud_policy_request()->CopyFrom(request);
+ SetPayload(request_wrapper);
+ }
+ virtual ~CloudPolicyJob() {}
+
+ private:
+ // DeviceManagementJobBase overrides.
+ virtual void OnError(DeviceManagementBackend::ErrorCode error) {
+ delegate_->OnError(error);
+ }
+ virtual void OnResponse(const em::DeviceManagementResponse& response) {
+ delegate_->HandleCloudPolicyResponse(response.cloud_policy_response());
+ }
+
+ DeviceManagementBackend::DevicePolicyResponseDelegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(CloudPolicyJob);
+};
DeviceManagementBackendImpl::DeviceManagementBackendImpl(
DeviceManagementService* service)
@@ -409,4 +428,13 @@ void DeviceManagementBackendImpl::ProcessPolicyRequest(
request, delegate));
}
+void DeviceManagementBackendImpl::ProcessCloudPolicyRequest(
+ const std::string& device_management_token,
+ const std::string& device_id,
+ const em::CloudPolicyRequest& request,
+ DevicePolicyResponseDelegate* delegate) {
+ AddJob(new CloudPolicyJob(this, device_management_token, device_id,
+ request, delegate));
+}
+
} // namespace policy
diff --git a/chrome/browser/policy/device_management_backend_impl.h b/chrome/browser/policy/device_management_backend_impl.h
index d818b4d..40c7e11 100644
--- a/chrome/browser/policy/device_management_backend_impl.h
+++ b/chrome/browser/policy/device_management_backend_impl.h
@@ -36,7 +36,10 @@ class DeviceManagementBackendImpl : public DeviceManagementBackend {
// String constants for the device and app type we report to the server.
static const char kValueRequestRegister[];
static const char kValueRequestUnregister[];
+ // Deprecated in favor of kValueRequestCloudPolicy.
+ // See DevicePolicyResponseDelegate::HandlePolicyResponse.
static const char kValueRequestPolicy[];
+ static const char kValueRequestCloudPolicy[];
static const char kValueDeviceType[];
static const char kValueAppType[];
@@ -63,11 +66,18 @@ class DeviceManagementBackendImpl : public DeviceManagementBackend {
const std::string& device_id,
const em::DeviceUnregisterRequest& request,
DeviceUnregisterResponseDelegate* response_delegate);
+ // Deprecated in favor of ProcessCloudPolicyRequest.
+ // See DevicePolicyResponseDelegate::HandlePolicyResponse.
virtual void ProcessPolicyRequest(
const std::string& device_management_token,
const std::string& device_id,
const em::DevicePolicyRequest& request,
DevicePolicyResponseDelegate* response_delegate);
+ virtual void ProcessCloudPolicyRequest(
+ const std::string& device_management_token,
+ const std::string& device_id,
+ const em::CloudPolicyRequest& request,
+ DevicePolicyResponseDelegate* delegate);
// Keeps track of the jobs currently in flight.
JobSet pending_jobs_;
diff --git a/chrome/browser/policy/device_management_backend_mock.h b/chrome/browser/policy/device_management_backend_mock.h
index 0533efc..01ac14d 100644
--- a/chrome/browser/policy/device_management_backend_mock.h
+++ b/chrome/browser/policy/device_management_backend_mock.h
@@ -40,6 +40,7 @@ class DevicePolicyResponseDelegateMock
virtual ~DevicePolicyResponseDelegateMock();
MOCK_METHOD1(HandlePolicyResponse, void(const em::DevicePolicyResponse&));
+ MOCK_METHOD1(HandleCloudPolicyResponse, void(const em::CloudPolicyResponse&));
MOCK_METHOD1(OnError, void(DeviceManagementBackend::ErrorCode error));
};
diff --git a/chrome/browser/policy/device_management_policy_cache.cc b/chrome/browser/policy/device_management_policy_cache.cc
deleted file mode 100644
index ef8e6e1..0000000
--- a/chrome/browser/policy/device_management_policy_cache.cc
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright (c) 2010 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_management_policy_cache.h"
-
-#include <limits>
-#include <string>
-
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "base/task.h"
-#include "base/values.h"
-#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/policy/proto/device_management_constants.h"
-#include "chrome/browser/policy/proto/device_management_local.pb.h"
-
-using google::protobuf::RepeatedField;
-using google::protobuf::RepeatedPtrField;
-
-namespace policy {
-
-// Saves policy information to a file.
-class PersistPolicyTask : public Task {
- public:
- PersistPolicyTask(const FilePath& path,
- const em::DevicePolicyResponse* policy,
- const base::Time& timestamp,
- const bool is_device_unmanaged)
- : path_(path),
- policy_(policy),
- timestamp_(timestamp),
- is_device_unmanaged_(is_device_unmanaged) {}
-
- private:
- // Task override.
- virtual void Run();
-
- const FilePath path_;
- scoped_ptr<const em::DevicePolicyResponse> policy_;
- const base::Time timestamp_;
- const bool is_device_unmanaged_;
-};
-
-void PersistPolicyTask::Run() {
- std::string data;
- em::CachedDevicePolicyResponse cached_policy;
- if (policy_.get())
- cached_policy.mutable_policy()->CopyFrom(*policy_);
- if (is_device_unmanaged_)
- cached_policy.set_unmanaged(true);
- cached_policy.set_timestamp(timestamp_.ToInternalValue());
- 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;
- }
-}
-
-DeviceManagementPolicyCache::DeviceManagementPolicyCache(
- const FilePath& backing_file_path)
- : backing_file_path_(backing_file_path),
- policy_(new DictionaryValue),
- fresh_policy_(false),
- is_device_unmanaged_(false) {
-}
-
-DeviceManagementPolicyCache::~DeviceManagementPolicyCache() {}
-
-void DeviceManagementPolicyCache::LoadPolicyFromFile() {
- if (!file_util::PathExists(backing_file_path_) || fresh_policy_)
- 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::CachedDevicePolicyResponse cached_policy;
- if (!cached_policy.ParseFromArray(data.c_str(), data.size())) {
- LOG(WARNING) << "Failed to parse policy data read from "
- << backing_file_path_.value();
- return;
- }
-
- // Reject files that claim to be from the future.
- base::Time timestamp = base::Time::FromInternalValue(
- cached_policy.timestamp());
- if (timestamp > base::Time::NowFromSystemTime()) {
- LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value()
- << ", file is from the future.";
- return;
- }
- is_device_unmanaged_ = cached_policy.unmanaged();
-
- // Decode and swap in the new policy information.
- scoped_ptr<DictionaryValue> value(DecodePolicy(cached_policy.policy()));
- {
- base::AutoLock lock(lock_);
- if (!fresh_policy_)
- policy_.reset(value.release());
- last_policy_refresh_time_ = timestamp;
- }
-}
-
-bool DeviceManagementPolicyCache::SetPolicy(
- const em::DevicePolicyResponse& policy) {
- is_device_unmanaged_ = false;
- DictionaryValue* value = DeviceManagementPolicyCache::DecodePolicy(policy);
- const bool new_policy_differs = !(value->Equals(policy_.get()));
- base::Time now(base::Time::NowFromSystemTime());
- {
- base::AutoLock lock(lock_);
- policy_.reset(value);
- fresh_policy_ = true;
- last_policy_refresh_time_ = now;
- }
-
- em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse;
- policy_copy->CopyFrom(policy);
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- new PersistPolicyTask(backing_file_path_, policy_copy, now, false));
- return new_policy_differs;
-}
-
-DictionaryValue* DeviceManagementPolicyCache::GetPolicy() {
- base::AutoLock lock(lock_);
- return policy_->DeepCopy();
-}
-
-void DeviceManagementPolicyCache::SetDeviceUnmanaged() {
- is_device_unmanaged_ = true;
- base::Time now(base::Time::NowFromSystemTime());
- {
- base::AutoLock lock(lock_);
- policy_.reset(new DictionaryValue);
- last_policy_refresh_time_ = now;
- }
- BrowserThread::PostTask(
- BrowserThread::FILE,
- FROM_HERE,
- new PersistPolicyTask(backing_file_path_, NULL, now, true));
-}
-
-// static
-Value* DeviceManagementPolicyCache::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* DeviceManagementPolicyCache::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* DeviceManagementPolicyCache::DecodePolicy(
- 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 =
- DeviceManagementPolicyCache::DecodeValue(named_value->value());
- if (decoded_value)
- result->Set(named_value->name(), decoded_value);
- }
- }
- }
- return result;
-}
-
-} // namespace policy
diff --git a/chrome/browser/policy/device_management_policy_cache_unittest.cc b/chrome/browser/policy/device_management_policy_cache_unittest.cc
deleted file mode 100644
index 1fe98c8..0000000
--- a/chrome/browser/policy/device_management_policy_cache_unittest.cc
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright (c) 2010 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_management_policy_cache.h"
-
-#include <limits>
-#include <string>
-
-#include "base/file_util.h"
-#include "base/message_loop.h"
-#include "base/scoped_temp_dir.h"
-#include "base/values.h"
-#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/policy/proto/device_management_constants.h"
-#include "chrome/browser/policy/proto/device_management_local.pb.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-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::CachedDevicePolicyResponse cached_policy;
- cached_policy.mutable_policy()->CopyFrom(policy);
- cached_policy.set_timestamp(timestamp.ToInternalValue());
- 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");
- }
-
- protected:
- MessageLoop loop_;
-
- private:
- ScopedTempDir temp_dir_;
- BrowserThread ui_thread_;
- BrowserThread file_thread_;
-};
-
-TEST_F(DeviceManagementPolicyCacheTest, Empty) {
- DeviceManagementPolicyCache cache(test_file());
- DictionaryValue empty;
- scoped_ptr<Value> policy(cache.GetPolicy());
- EXPECT_TRUE(empty.Equals(policy.get()));
- EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, LoadNoFile) {
- DeviceManagementPolicyCache cache(test_file());
- cache.LoadPolicyFromFile();
- DictionaryValue empty;
- scoped_ptr<Value> policy(cache.GetPolicy());
- EXPECT_TRUE(empty.Equals(policy.get()));
- 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));
- DeviceManagementPolicyCache cache(test_file());
- cache.LoadPolicyFromFile();
- DictionaryValue empty;
- scoped_ptr<Value> policy(cache.GetPolicy());
- EXPECT_TRUE(empty.Equals(policy.get()));
- EXPECT_EQ(base::Time(), cache.last_policy_refresh_time());
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, LoadWithFile) {
- em::DevicePolicyResponse policy_response;
- WritePolicy(policy_response, base::Time::NowFromSystemTime());
- DeviceManagementPolicyCache cache(test_file());
- cache.LoadPolicyFromFile();
- DictionaryValue empty;
- scoped_ptr<Value> policy(cache.GetPolicy());
- EXPECT_TRUE(empty.Equals(policy.get()));
- 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());
- DeviceManagementPolicyCache cache(test_file());
- cache.LoadPolicyFromFile();
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.example.com"));
- scoped_ptr<Value> policy_value(cache.GetPolicy());
- EXPECT_TRUE(expected.Equals(policy_value.get()));
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, SetPolicy) {
- DeviceManagementPolicyCache cache(test_file());
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- EXPECT_TRUE(cache.SetPolicy(policy));
- em::DevicePolicyResponse policy2;
- AddStringPolicy(&policy2, "HomepageLocation", "http://www.example.com");
- EXPECT_FALSE(cache.SetPolicy(policy2));
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.example.com"));
- scoped_ptr<Value> policy_value(cache.GetPolicy());
- EXPECT_TRUE(expected.Equals(policy_value.get()));
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, ResetPolicy) {
- DeviceManagementPolicyCache cache(test_file());
-
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- EXPECT_TRUE(cache.SetPolicy(policy));
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.example.com"));
- scoped_ptr<Value> policy_value(cache.GetPolicy());
- EXPECT_TRUE(expected.Equals(policy_value.get()));
-
- EXPECT_TRUE(cache.SetPolicy(em::DevicePolicyResponse()));
- policy_value.reset(cache.GetPolicy());
- DictionaryValue empty;
- EXPECT_TRUE(empty.Equals(policy_value.get()));
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, PersistPolicy) {
- {
- DeviceManagementPolicyCache cache(test_file());
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- cache.SetPolicy(policy);
- }
-
- loop_.RunAllPending();
-
- EXPECT_TRUE(file_util::PathExists(test_file()));
- DeviceManagementPolicyCache cache(test_file());
- cache.LoadPolicyFromFile();
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.example.com"));
- scoped_ptr<Value> policy_value(cache.GetPolicy());
- EXPECT_TRUE(expected.Equals(policy_value.get()));
-}
-
-TEST_F(DeviceManagementPolicyCacheTest, FreshPolicyOverride) {
- em::DevicePolicyResponse policy;
- AddStringPolicy(&policy, "HomepageLocation", "http://www.example.com");
- WritePolicy(policy, base::Time::NowFromSystemTime());
-
- DeviceManagementPolicyCache cache(test_file());
- em::DevicePolicyResponse updated_policy;
- AddStringPolicy(&updated_policy, "HomepageLocation",
- "http://www.chromium.org");
- EXPECT_TRUE(cache.SetPolicy(updated_policy));
-
- cache.LoadPolicyFromFile();
- DictionaryValue expected;
- expected.Set("HomepageLocation",
- Value::CreateStringValue("http://www.chromium.org"));
- scoped_ptr<Value> policy_value(cache.GetPolicy());
- EXPECT_TRUE(expected.Equals(policy_value.get()));
-}
-
-// 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(
- DeviceManagementPolicyCache::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());
- }
- }
-
- 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(DeviceManagementPolicyCache::DecodePolicy(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/device_management_policy_provider.cc b/chrome/browser/policy/device_management_policy_provider.cc
index 315a6d2..eaaf4d4 100644
--- a/chrome/browser/policy/device_management_policy_provider.cc
+++ b/chrome/browser/policy/device_management_policy_provider.cc
@@ -4,14 +4,16 @@
#include "chrome/browser/policy/device_management_policy_provider.h"
+#include <algorithm>
+
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/rand_util.h"
#include "base/task.h"
#include "chrome/browser/browser_thread.h"
+#include "chrome/browser/policy/cloud_policy_cache.h"
#include "chrome/browser/policy/device_management_backend.h"
-#include "chrome/browser/policy/device_management_policy_cache.h"
#include "chrome/browser/policy/profile_policy_context.h"
#include "chrome/browser/policy/proto/device_management_constants.h"
#include "chrome/browser/profiles/profile.h"
@@ -86,8 +88,13 @@ DeviceManagementPolicyProvider::~DeviceManagementPolicyProvider() {
bool DeviceManagementPolicyProvider::Provide(
ConfigurationPolicyStoreInterface* policy_store) {
- scoped_ptr<DictionaryValue> policies(cache_->GetPolicy());
- DecodePolicyValueTree(policies.get(), policy_store);
+ if (cache_->has_device_policy()) {
+ scoped_ptr<DictionaryValue> policies(cache_->GetDevicePolicy());
+ ApplyPolicyValueTree(policies.get(), policy_store);
+ } else {
+ ApplyPolicyMap(cache_->GetMandatoryPolicy(), policy_store);
+ // TODO(jkummerow, mnissler): provide recommended policy.
+ }
return true;
}
@@ -98,13 +105,23 @@ bool DeviceManagementPolicyProvider::IsInitializationComplete() const {
void DeviceManagementPolicyProvider::HandlePolicyResponse(
const em::DevicePolicyResponse& response) {
DCHECK(TokenAvailable());
- if (cache_->SetPolicy(response)) {
+ if (cache_->SetDevicePolicy(response)) {
initial_fetch_done_ = true;
NotifyCloudPolicyUpdate();
}
SetState(STATE_POLICY_VALID);
}
+void DeviceManagementPolicyProvider::HandleCloudPolicyResponse(
+ const em::CloudPolicyResponse& response) {
+ DCHECK(TokenAvailable());
+ if (cache_->SetPolicy(response)) {
+ initial_fetch_done_ = true;
+ NotifyCloudPolicyUpdate();
+ }
+ SetState(STATE_POLICY_VALID);
+}
+
void DeviceManagementPolicyProvider::OnError(
DeviceManagementBackend::ErrorCode code) {
DCHECK(TokenAvailable());
@@ -117,6 +134,12 @@ void DeviceManagementPolicyProvider::OnError(
DeviceManagementBackend::kErrorServiceManagementNotSupported) {
VLOG(1) << "The device is no longer managed, resetting device token.";
SetState(STATE_TOKEN_RESET);
+ } else if (!fallback_to_old_protocol_ &&
+ code == DeviceManagementBackend::kErrorRequestInvalid) {
+ LOG(WARNING) << "Device management server doesn't understand new protocol,"
+ << " falling back to old request.";
+ fallback_to_old_protocol_ = true;
+ SetState(STATE_TOKEN_VALID); // Triggers SendPolicyRequest() immediately.
} else {
LOG(WARNING) << "Could not provide policy from the device manager (error = "
<< code << "), will retry in "
@@ -140,7 +163,7 @@ void DeviceManagementPolicyProvider::OnTokenError() {
void DeviceManagementPolicyProvider::OnNotManaged() {
DCHECK(!TokenAvailable());
VLOG(1) << "This device is not managed.";
- cache_->SetDeviceUnmanaged();
+ cache_->SetUnmanaged();
SetState(STATE_UNMANAGED);
}
@@ -186,6 +209,7 @@ void DeviceManagementPolicyProvider::Initialize(
DCHECK(profile);
backend_.reset(backend);
profile_ = profile;
+ fallback_to_old_protocol_ = false;
storage_dir_ = GetOrCreateDeviceManagementDir(profile_->GetPath());
state_ = STATE_INITIALIZING;
initial_fetch_done_ = false;
@@ -201,13 +225,13 @@ void DeviceManagementPolicyProvider::Initialize(
unmanaged_device_refresh_rate_ms_ = unmanaged_device_refresh_rate_ms;
const FilePath policy_path = storage_dir_.Append(kPolicyFilename);
- cache_.reset(new DeviceManagementPolicyCache(policy_path));
+ cache_.reset(new CloudPolicyCache(policy_path));
cache_->LoadPolicyFromFile();
SetDeviceTokenFetcher(new DeviceTokenFetcher(backend_.get(), profile,
GetTokenPath()));
- if (cache_->is_device_unmanaged()) {
+ if (cache_->is_unmanaged()) {
// This is a non-first login on an unmanaged device.
SetState(STATE_UNMANAGED);
} else {
@@ -226,15 +250,23 @@ void DeviceManagementPolicyProvider::RemoveObserver(
}
void DeviceManagementPolicyProvider::SendPolicyRequest() {
- em::DevicePolicyRequest policy_request;
- policy_request.set_policy_scope(kChromePolicyScope);
- em::DevicePolicySettingRequest* setting =
- policy_request.add_setting_request();
- setting->set_key(kChromeDevicePolicySettingKey);
- setting->set_watermark("");
- backend_->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(),
- token_fetcher_->GetDeviceID(),
- policy_request, this);
+ if (!fallback_to_old_protocol_) {
+ em::CloudPolicyRequest policy_request;
+ policy_request.set_policy_scope(kChromePolicyScope);
+ backend_->ProcessCloudPolicyRequest(token_fetcher_->GetDeviceToken(),
+ token_fetcher_->GetDeviceID(),
+ policy_request, this);
+ } else {
+ em::DevicePolicyRequest policy_request;
+ policy_request.set_policy_scope(kChromePolicyScope);
+ em::DevicePolicySettingRequest* setting =
+ policy_request.add_setting_request();
+ setting->set_key(kChromeDevicePolicySettingKey);
+ setting->set_watermark("");
+ backend_->ProcessPolicyRequest(token_fetcher_->GetDeviceToken(),
+ token_fetcher_->GetDeviceID(),
+ policy_request, this);
+ }
}
void DeviceManagementPolicyProvider::RefreshTaskExecute() {
diff --git a/chrome/browser/policy/device_management_policy_provider.h b/chrome/browser/policy/device_management_policy_provider.h
index 592df9b..dd09628 100644
--- a/chrome/browser/policy/device_management_policy_provider.h
+++ b/chrome/browser/policy/device_management_policy_provider.h
@@ -21,8 +21,8 @@ class TokenService;
namespace policy {
+class CloudPolicyCache;
class DeviceManagementBackend;
-class DeviceManagementPolicyCache;
// Provides policy fetched from the device management server. With the exception
// of the Provide method, which can be called on the FILE thread, all public
@@ -44,7 +44,9 @@ class DeviceManagementPolicyProvider
// DevicePolicyResponseDelegate implementation:
virtual void HandlePolicyResponse(
- const em::DevicePolicyResponse& response);
+ const em::DevicePolicyResponse& response); // deprecated.
+ virtual void HandleCloudPolicyResponse(
+ const em::CloudPolicyResponse& response);
virtual void OnError(DeviceManagementBackend::ErrorCode code);
// DeviceTokenFetcher::Observer implementation:
@@ -146,7 +148,8 @@ class DeviceManagementPolicyProvider
scoped_ptr<DeviceManagementBackend> backend_;
Profile* profile_; // weak
- scoped_ptr<DeviceManagementPolicyCache> cache_;
+ scoped_ptr<CloudPolicyCache> cache_;
+ bool fallback_to_old_protocol_;
scoped_refptr<DeviceTokenFetcher> token_fetcher_;
DeviceTokenFetcher::ObserverRegistrar registrar_;
ObserverList<ConfigurationPolicyProvider::Observer, true> observer_list_;
diff --git a/chrome/browser/policy/device_management_policy_provider_unittest.cc b/chrome/browser/policy/device_management_policy_provider_unittest.cc
index d0a0eaa..8dc3bf4 100644
--- a/chrome/browser/policy/device_management_policy_provider_unittest.cc
+++ b/chrome/browser/policy/device_management_policy_provider_unittest.cc
@@ -7,9 +7,9 @@
#include "base/scoped_temp_dir.h"
#include "chrome/browser/browser_thread.h"
#include "chrome/browser/net/gaia/token_service.h"
+#include "chrome/browser/policy/cloud_policy_cache.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/policy/configuration_policy_provider.h"
-#include "chrome/browser/policy/device_management_policy_cache.h"
#include "chrome/browser/policy/device_management_policy_provider.h"
#include "chrome/browser/policy/mock_configuration_policy_store.h"
#include "chrome/browser/policy/mock_device_management_backend.h"
@@ -113,9 +113,8 @@ class DeviceManagementPolicyProviderTest : public testing::Test {
MockConfigurationPolicyStore store;
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(
- key::kDisableSpdy, true));
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
SimulateSuccessfulLoginAndRunPending();
EXPECT_FALSE(waiting_for_initial_policies());
EXPECT_CALL(store, Apply(kPolicyDisableSpdy, _)).Times(1);
@@ -138,7 +137,7 @@ class DeviceManagementPolicyProviderTest : public testing::Test {
scoped_ptr<DeviceManagementPolicyProvider> provider_;
protected:
- DeviceManagementPolicyCache* cache(DeviceManagementPolicyProvider* provider) {
+ CloudPolicyCache* cache(DeviceManagementPolicyProvider* provider) {
return provider->cache_.get();
}
@@ -193,9 +192,8 @@ TEST_F(DeviceManagementPolicyProviderTest, SecondProvide) {
// Simulate a app relaunch by constructing a new provider. Policy should be
// refreshed (since that might be the purpose of the app relaunch).
CreateNewProvider();
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(
- key::kDisableSpdy, true));
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
loop_.RunAllPending();
Mock::VerifyAndClearExpectations(backend_);
@@ -203,7 +201,7 @@ TEST_F(DeviceManagementPolicyProviderTest, SecondProvide) {
// Cached policy should still be available.
MockConfigurationPolicyStore store;
CreateNewProvider();
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendFailPolicy(
DeviceManagementBackend::kErrorRequestFailed));
SimulateSuccessfulLoginAndRunPending();
@@ -231,15 +229,14 @@ TEST_F(DeviceManagementPolicyProviderTest, ErrorCausesNewRequest) {
DeviceManagementBackend::kErrorRequestFailed));
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendFailPolicy(
DeviceManagementBackend::kErrorRequestFailed));
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendFailPolicy(
DeviceManagementBackend::kErrorRequestFailed));
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy,
- true));
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
}
SimulateSuccessfulLoginAndRunPending();
}
@@ -250,16 +247,13 @@ TEST_F(DeviceManagementPolicyProviderTest, RefreshPolicies) {
CreateNewProvider(0, 0, 0, 1000 * 1000, 1000, 0);
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy,
- true));
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy,
- true));
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy,
- true));
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendFailPolicy(
DeviceManagementBackend::kErrorRequestFailed));
}
@@ -273,14 +267,13 @@ TEST_F(DeviceManagementPolicyProviderTest, DeviceNotFound) {
InSequence s;
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendFailPolicy(
DeviceManagementBackend::kErrorServiceDeviceNotFound));
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy,
- true));
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
}
SimulateSuccessfulLoginAndRunPending();
}
@@ -292,14 +285,13 @@ TEST_F(DeviceManagementPolicyProviderTest, InvalidTokenOnPolicyRequest) {
InSequence s;
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendFailPolicy(
DeviceManagementBackend::kErrorServiceManagementTokenInvalid));
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy,
- true));
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
}
SimulateSuccessfulLoginAndRunPending();
}
@@ -312,13 +304,11 @@ TEST_F(DeviceManagementPolicyProviderTest, DeviceNoLongerManaged) {
CreateNewProvider(0, 0, 0, 0, 0, 1000 * 1000);
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy,
- true));
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy,
- true));
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendFailPolicy(
DeviceManagementBackend::kErrorServiceManagementNotSupported));
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
@@ -341,7 +331,7 @@ TEST_F(DeviceManagementPolicyProviderTest, UnmanagedDevice) {
SimulateSuccessfulLoginAndRunPending();
// (1) The provider's DMPolicyCache should know that the device is not
// managed.
- EXPECT_TRUE(cache(provider_.get())->is_device_unmanaged());
+ EXPECT_TRUE(cache(provider_.get())->is_unmanaged());
// (2) On restart, the provider should detect that this is not the first
// login.
CreateNewProvider(1000 * 1000, 0, 0, 0, 0, 0);
@@ -350,14 +340,43 @@ TEST_F(DeviceManagementPolicyProviderTest, UnmanagedDevice) {
InSequence s;
EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
MockDeviceManagementBackendSucceedRegister());
- EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
- MockDeviceManagementBackendSucceedBooleanPolicy(key::kDisableSpdy,
- true));
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedSpdyCloudPolicy());
}
SimulateSuccessfulLoginAndRunPending();
// (3) Since the backend call this time returned a device id, the "unmanaged"
// marker should have been deleted.
- EXPECT_FALSE(cache(provider_.get())->is_device_unmanaged());
+ EXPECT_FALSE(cache(provider_.get())->is_unmanaged());
+}
+
+TEST_F(DeviceManagementPolicyProviderTest, FallbackToOldProtocol) {
+ { // Scoping so SimulateSuccessfulLoginAndRunPending doesn't see the sequence.
+ InSequence s;
+ CreateNewProvider(0, 0, 0, 0, 0, 1000 * 1000);
+ EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedRegister());
+ // If the CloudPolicyRequest fails with kErrorRequestInvalid...
+ EXPECT_CALL(*backend_, ProcessCloudPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendFailPolicy(
+ DeviceManagementBackend::kErrorRequestInvalid));
+ // ...the client should fall back to a classic PolicyRequest...
+ EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendSucceedBooleanPolicy(
+ key::kDisableSpdy, true));
+ // ...and remember this fallback for any future request, ...
+ EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendFailPolicy(
+ DeviceManagementBackend::kErrorHttpStatus));
+ // ...both after successful fetches and after errors.
+ EXPECT_CALL(*backend_, ProcessPolicyRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendFailPolicy(
+ DeviceManagementBackend::kErrorServiceManagementNotSupported));
+ // Finally, we set the client to 'unmanaged' to stop its request stream.
+ EXPECT_CALL(*backend_, ProcessRegisterRequest(_, _, _, _)).WillOnce(
+ MockDeviceManagementBackendFailRegister(
+ DeviceManagementBackend::kErrorServiceManagementNotSupported));
+ }
+ SimulateSuccessfulLoginAndRunPending();
}
} // namespace policy
diff --git a/chrome/browser/policy/mock_configuration_policy_provider.cc b/chrome/browser/policy/mock_configuration_policy_provider.cc
index a2566b0..46f997c 100644
--- a/chrome/browser/policy/mock_configuration_policy_provider.cc
+++ b/chrome/browser/policy/mock_configuration_policy_provider.cc
@@ -15,23 +15,16 @@ MockConfigurationPolicyProvider::MockConfigurationPolicyProvider()
initialization_complete_(false) {
}
-MockConfigurationPolicyProvider::~MockConfigurationPolicyProvider() {
- STLDeleteValues(&policy_map_);
-}
+MockConfigurationPolicyProvider::~MockConfigurationPolicyProvider() {}
void MockConfigurationPolicyProvider::AddPolicy(ConfigurationPolicyType policy,
Value* value) {
- std::swap(policy_map_[policy], value);
- delete value;
+ policy_map_.Set(policy, value);
}
void MockConfigurationPolicyProvider::RemovePolicy(
ConfigurationPolicyType policy) {
- const PolicyMap::iterator entry = policy_map_.find(policy);
- if (entry != policy_map_.end()) {
- delete entry->second;
- policy_map_.erase(entry);
- }
+ policy_map_.Erase(policy);
}
void MockConfigurationPolicyProvider::SetInitializationComplete(
@@ -52,4 +45,4 @@ bool MockConfigurationPolicyProvider::IsInitializationComplete() const {
return initialization_complete_;
}
-}
+} // namespace policy
diff --git a/chrome/browser/policy/mock_configuration_policy_provider.h b/chrome/browser/policy/mock_configuration_policy_provider.h
index 5620f81..f71f8db 100644
--- a/chrome/browser/policy/mock_configuration_policy_provider.h
+++ b/chrome/browser/policy/mock_configuration_policy_provider.h
@@ -10,6 +10,7 @@
#include <utility>
#include "chrome/browser/policy/configuration_policy_provider.h"
+#include "chrome/browser/policy/policy_map.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace policy {
@@ -36,8 +37,6 @@ class MockConfigurationPolicyProvider : public ConfigurationPolicyProvider {
virtual void RemoveObserver(
ConfigurationPolicyProvider::Observer* observer) {}
- typedef std::map<ConfigurationPolicyType, Value*> PolicyMap;
-
PolicyMap policy_map_;
bool initialization_complete_;
};
diff --git a/chrome/browser/policy/mock_configuration_policy_store.cc b/chrome/browser/policy/mock_configuration_policy_store.cc
index bda4688..1cbf438 100644
--- a/chrome/browser/policy/mock_configuration_policy_store.cc
+++ b/chrome/browser/policy/mock_configuration_policy_store.cc
@@ -14,20 +14,16 @@ MockConfigurationPolicyStore::MockConfigurationPolicyStore() {
Invoke(this, &MockConfigurationPolicyStore::ApplyToMap));
}
-MockConfigurationPolicyStore::~MockConfigurationPolicyStore() {
- STLDeleteValues(&policy_map_);
-}
+MockConfigurationPolicyStore::~MockConfigurationPolicyStore() {}
const Value* MockConfigurationPolicyStore::Get(
ConfigurationPolicyType type) const {
- PolicyMap::const_iterator entry(policy_map_.find(type));
- return entry == policy_map_.end() ? NULL : entry->second;
+ return policy_map_.Get(type);
}
void MockConfigurationPolicyStore::ApplyToMap(
ConfigurationPolicyType policy, Value* value) {
- std::swap(policy_map_[policy], value);
- delete value;
+ policy_map_.Set(policy, value);
}
} // namespace policy
diff --git a/chrome/browser/policy/mock_configuration_policy_store.h b/chrome/browser/policy/mock_configuration_policy_store.h
index 472357d..14e4597 100644
--- a/chrome/browser/policy/mock_configuration_policy_store.h
+++ b/chrome/browser/policy/mock_configuration_policy_store.h
@@ -12,6 +12,7 @@
#include "base/stl_util-inl.h"
#include "base/values.h"
#include "chrome/browser/policy/configuration_policy_store_interface.h"
+#include "chrome/browser/policy/policy_map.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace policy {
@@ -20,8 +21,6 @@ namespace policy {
// settings as they get set.
class MockConfigurationPolicyStore : public ConfigurationPolicyStoreInterface {
public:
- typedef std::map<ConfigurationPolicyType, Value*> PolicyMap;
-
MockConfigurationPolicyStore();
virtual ~MockConfigurationPolicyStore();
diff --git a/chrome/browser/policy/mock_device_management_backend.h b/chrome/browser/policy/mock_device_management_backend.h
index a684e4f..54c8c8f 100644
--- a/chrome/browser/policy/mock_device_management_backend.h
+++ b/chrome/browser/policy/mock_device_management_backend.h
@@ -9,6 +9,7 @@
#include <map>
#include <string>
+#include "base/time.h"
#include "base/values.h"
#include "chrome/browser/policy/device_management_backend.h"
#include "chrome/browser/policy/proto/device_management_constants.h"
@@ -46,6 +47,12 @@ class MockDeviceManagementBackend : public DeviceManagementBackend {
const em::DevicePolicyRequest& request,
DevicePolicyResponseDelegate* delegate));
+ MOCK_METHOD4(ProcessCloudPolicyRequest, void(
+ const std::string& device_management_token,
+ const std::string& device_id,
+ const em::CloudPolicyRequest& request,
+ DevicePolicyResponseDelegate* delegate));
+
private:
DISALLOW_COPY_AND_ASSIGN(MockDeviceManagementBackend);
};
@@ -73,6 +80,24 @@ ACTION_P2(MockDeviceManagementBackendSucceedBooleanPolicy, name, value) {
arg3->HandlePolicyResponse(response);
}
+ACTION(MockDeviceManagementBackendSucceedSpdyCloudPolicy) {
+ em::SignedCloudPolicyResponse signed_response;
+ em::CloudPolicySettings* settings = signed_response.mutable_settings();
+ em::DisableSpdyProto* spdy_proto = settings->mutable_disablespdy();
+ spdy_proto->set_disablespdy(true);
+ spdy_proto->mutable_policy_options()->set_mode(em::PolicyOptions::MANDATORY);
+ signed_response.set_timestamp(base::Time::NowFromSystemTime().ToTimeT());
+ std::string serialized_signed_response;
+ EXPECT_TRUE(signed_response.SerializeToString(&serialized_signed_response));
+ em::CloudPolicyResponse response;
+ response.set_signed_response(serialized_signed_response);
+ // TODO(jkummerow): Set proper certificate_chain and signature (when
+ // implementing support for signature verification).
+ response.set_signature("TODO");
+ response.add_certificate_chain("TODO");
+ arg3->HandleCloudPolicyResponse(response);
+}
+
ACTION_P(MockDeviceManagementBackendFailRegister, error) {
arg3->OnError(error);
}
diff --git a/chrome/browser/policy/policy_map.cc b/chrome/browser/policy/policy_map.cc
new file mode 100644
index 0000000..50c8c42
--- /dev/null
+++ b/chrome/browser/policy/policy_map.cc
@@ -0,0 +1,73 @@
+// 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/policy_map.h"
+
+#include <algorithm>
+
+#include "base/stl_util-inl.h"
+
+namespace policy {
+
+PolicyMap::PolicyMap() {
+}
+
+PolicyMap::~PolicyMap() {
+ Clear();
+}
+
+const Value* PolicyMap::Get(ConfigurationPolicyType policy) const {
+ PolicyMapType::const_iterator entry = map_.find(policy);
+ return entry == map_.end() ? NULL : entry->second;
+}
+
+void PolicyMap::Set(ConfigurationPolicyType policy, Value* value) {
+ std::swap(map_[policy], value);
+ delete value;
+}
+
+void PolicyMap::Erase(ConfigurationPolicyType policy) {
+ const const_iterator entry = map_.find(policy);
+ if (entry != map_.end()) {
+ delete entry->second;
+ map_.erase(entry->first);
+ }
+}
+
+void PolicyMap::Swap(PolicyMap* other) {
+ map_.swap(other->map_);
+}
+
+bool PolicyMap::Equals(const PolicyMap& other) const {
+ return other.map_.size() == map_.size() &&
+ std::equal(map_.begin(), map_.end(), other.map_.begin(), MapEntryEquals);
+}
+
+bool PolicyMap::empty() const {
+ return map_.empty();
+}
+
+size_t PolicyMap::size() const {
+ return map_.size();
+}
+
+PolicyMap::const_iterator PolicyMap::begin() const {
+ return map_.begin();
+}
+
+PolicyMap::const_iterator PolicyMap::end() const {
+ return map_.end();
+}
+
+void PolicyMap::Clear() {
+ STLDeleteValues(&map_);
+}
+
+// static
+bool PolicyMap::MapEntryEquals(const PolicyMap::PolicyMapType::value_type& a,
+ const PolicyMap::PolicyMapType::value_type& b) {
+ return a.first == b.first && Value::Equals(a.second, b.second);
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/policy_map.h b/chrome/browser/policy/policy_map.h
new file mode 100644
index 0000000..c9e3d03
--- /dev/null
+++ b/chrome/browser/policy/policy_map.h
@@ -0,0 +1,58 @@
+// 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_POLICY_MAP_H_
+#define CHROME_BROWSER_POLICY_POLICY_MAP_H_
+
+#include <map>
+
+#include "base/values.h"
+#include "policy/configuration_policy_type.h"
+
+namespace policy {
+
+// Wrapper class around a std::map<ConfigurationPolicyType, Value*> that
+// properly cleans up after itself when going out of scope.
+// Exposes interesting methods of the underlying std::map.
+class PolicyMap {
+ public:
+ typedef std::map<ConfigurationPolicyType, Value*> PolicyMapType;
+ typedef PolicyMapType::const_iterator const_iterator;
+
+ PolicyMap();
+ virtual ~PolicyMap();
+
+ // Returns a weak reference to the value currently stored for key |policy|.
+ // Ownership is retained by PolicyMap; callers should use Value::DeepCopy
+ // if they need a copy that they own themselves.
+ // Returns NULL if the map does not contain a value for |policy|.
+ const Value* Get(ConfigurationPolicyType policy) const;
+ // Takes ownership of |value|. Overwrites any existing value stored in the
+ // map for the key |policy|.
+ void Set(ConfigurationPolicyType policy, Value* value);
+ void Erase(ConfigurationPolicyType policy);
+
+ void Swap(PolicyMap* other);
+
+ bool Equals(const PolicyMap& other) const;
+ bool empty() const;
+ size_t size() const;
+
+ const_iterator begin() const;
+ const_iterator end() const;
+ void Clear();
+
+ private:
+ // Helper function for Equals(...).
+ static bool MapEntryEquals(const PolicyMapType::value_type& a,
+ const PolicyMapType::value_type& b);
+
+ PolicyMapType map_;
+
+ DISALLOW_COPY_AND_ASSIGN(PolicyMap);
+};
+
+} // namespace policy
+
+#endif // CHROME_BROWSER_POLICY_POLICY_MAP_H_
diff --git a/chrome/browser/policy/policy_map_unittest.cc b/chrome/browser/policy/policy_map_unittest.cc
new file mode 100644
index 0000000..01aad95
--- /dev/null
+++ b/chrome/browser/policy/policy_map_unittest.cc
@@ -0,0 +1,68 @@
+// 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/policy_map.h"
+
+#include "base/scoped_ptr.h"
+#include "policy/configuration_policy_type.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace policy {
+
+TEST(PolicyMapTest, SetAndGet) {
+ PolicyMap map;
+ map.Set(kPolicyHomepageLocation, Value::CreateStringValue("aaa"));
+ StringValue expected("aaa");
+ EXPECT_TRUE(expected.Equals(map.Get(kPolicyHomepageLocation)));
+ map.Set(kPolicyHomepageLocation, Value::CreateStringValue("bbb"));
+ StringValue expected_b("bbb");
+ EXPECT_TRUE(expected_b.Equals(map.Get(kPolicyHomepageLocation)));
+}
+
+TEST(PolicyMapTest, Equals) {
+ PolicyMap a;
+ a.Set(kPolicyHomepageLocation, Value::CreateStringValue("aaa"));
+ PolicyMap a2;
+ a2.Set(kPolicyHomepageLocation, Value::CreateStringValue("aaa"));
+ PolicyMap b;
+ b.Set(kPolicyHomepageLocation, Value::CreateStringValue("bbb"));
+ PolicyMap c;
+ c.Set(kPolicyHomepageLocation, Value::CreateStringValue("aaa"));
+ c.Set(kPolicyHomepageIsNewTabPage, Value::CreateBooleanValue(true));
+ EXPECT_FALSE(a.Equals(b));
+ EXPECT_FALSE(b.Equals(a));
+ EXPECT_FALSE(a.Equals(c));
+ EXPECT_FALSE(c.Equals(a));
+ EXPECT_TRUE(a.Equals(a2));
+ EXPECT_TRUE(a2.Equals(a));
+ PolicyMap empty1;
+ PolicyMap empty2;
+ EXPECT_TRUE(empty1.Equals(empty2));
+ EXPECT_TRUE(empty2.Equals(empty1));
+ EXPECT_FALSE(empty1.Equals(a));
+ EXPECT_FALSE(a.Equals(empty1));
+}
+
+TEST(PolicyMapTest, Swap) {
+ PolicyMap a;
+ a.Set(kPolicyHomepageLocation, Value::CreateStringValue("aaa"));
+ PolicyMap b;
+ b.Set(kPolicyHomepageLocation, Value::CreateStringValue("bbb"));
+ b.Set(kPolicyHomepageIsNewTabPage, Value::CreateBooleanValue(true));
+ a.Swap(&b);
+ StringValue expected("bbb");
+ EXPECT_TRUE(expected.Equals(a.Get(kPolicyHomepageLocation)));
+ FundamentalValue expected_bool(true);
+ EXPECT_TRUE(expected_bool.Equals(a.Get(kPolicyHomepageIsNewTabPage)));
+ StringValue expected_a("aaa");
+ EXPECT_TRUE(expected_a.Equals(b.Get(kPolicyHomepageLocation)));
+
+ b.Clear();
+ a.Swap(&b);
+ PolicyMap empty;
+ EXPECT_TRUE(a.Equals(empty));
+ EXPECT_FALSE(b.Equals(empty));
+}
+
+} // namespace policy
diff --git a/chrome/browser/policy/profile_policy_context.cc b/chrome/browser/policy/profile_policy_context.cc
index 7adffd3..b8e3151a 100644
--- a/chrome/browser/policy/profile_policy_context.cc
+++ b/chrome/browser/policy/profile_policy_context.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <algorithm>
+#include <string>
+
#include "base/command_line.h"
#include "chrome/browser/policy/configuration_policy_pref_store.h"
#include "chrome/browser/policy/device_management_policy_provider.h"
@@ -20,7 +23,7 @@ namespace {
const int64 kPolicyRefreshRateMinMs = 30 * 60 * 1000; // 30 minutes
const int64 kPolicyRefreshRateMaxMs = 24 * 60 * 60 * 1000; // 1 day
-}
+} // namespace
namespace policy {
diff --git a/chrome/browser/policy/proto/cloud_policy.proto b/chrome/browser/policy/proto/cloud_policy.proto
deleted file mode 100644
index 82a1135..0000000
--- a/chrome/browser/policy/proto/cloud_policy.proto
+++ /dev/null
@@ -1,221 +0,0 @@
-//
-// DO NOT MODIFY THIS FILE DIRECTLY!
-// ITS IS GENERATED BY generate_policy_source.py
-// FROM policy_templates.json
-//
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-package enterprise_management;
-
-// PBs for individual settings.
-
-message PolicyOptions {
- enum PolicyMode {
- // The user may choose to override the given settings.
- RECOMMENDED = 1;
- // The given settings are applied regardless of user choice.
- MANDATORY = 2;
- }
- optional PolicyMode mode = 1;
-}
-
-message HomepageProto {
- optional PolicyOptions policy_options = 1;
- optional string HomepageLocation = 2;
- optional bool HomepageIsNewTabPage = 3;
-}
-
-message ApplicationLocaleValueProto {
- optional PolicyOptions policy_options = 1;
- optional string ApplicationLocaleValue = 2;
-}
-
-message AlternateErrorPagesEnabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool AlternateErrorPagesEnabled = 2;
-}
-
-message SearchSuggestEnabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool SearchSuggestEnabled = 2;
-}
-
-message DnsPrefetchingEnabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool DnsPrefetchingEnabled = 2;
-}
-
-message DisableSpdyProto {
- optional PolicyOptions policy_options = 1;
- optional bool DisableSpdy = 2;
-}
-
-message JavascriptEnabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool JavascriptEnabled = 2;
-}
-
-message SavingBrowserHistoryDisabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool SavingBrowserHistoryDisabled = 2;
-}
-
-message PrintingEnabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool PrintingEnabled = 2;
-}
-
-message SafeBrowsingEnabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool SafeBrowsingEnabled = 2;
-}
-
-message MetricsReportingEnabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool MetricsReportingEnabled = 2;
-}
-
-message PasswordManagerProto {
- optional PolicyOptions policy_options = 1;
- optional bool PasswordManagerEnabled = 2;
- optional bool PasswordManagerAllowShowPasswords = 3;
-}
-
-message AutoFillEnabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool AutoFillEnabled = 2;
-}
-
-message DisabledPluginsProto {
- optional PolicyOptions policy_options = 1;
- repeated string DisabledPlugins = 2;
-}
-
-message SyncDisabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool SyncDisabled = 2;
-}
-
-message ProxyProto {
- optional PolicyOptions policy_options = 1;
- optional string ProxyMode = 2;
- optional int64 ProxyServerMode = 3;
- optional string ProxyServer = 4;
- optional string ProxyPacUrl = 5;
- optional string ProxyBypassList = 6;
-}
-
-message HTTPAuthenticationProto {
- optional PolicyOptions policy_options = 1;
- optional string AuthSchemes = 2;
- optional bool DisableAuthNegotiateCnameLookup = 3;
- optional bool EnableAuthNegotiatePort = 4;
- optional string AuthServerWhitelist = 5;
- optional string AuthNegotiateDelegateWhitelist = 6;
- optional string GSSAPILibraryName = 7;
-}
-
-message ExtensionsProto {
- optional PolicyOptions policy_options = 1;
- repeated string ExtensionInstallBlacklist = 2;
- repeated string ExtensionInstallWhitelist = 3;
- repeated string ExtensionInstallForcelist = 4;
-}
-
-message ShowHomeButtonProto {
- optional PolicyOptions policy_options = 1;
- optional bool ShowHomeButton = 2;
-}
-
-message DeveloperToolsDisabledProto {
- optional PolicyOptions policy_options = 1;
- optional bool DeveloperToolsDisabled = 2;
-}
-
-message RestoreOnStartupGroupProto {
- optional PolicyOptions policy_options = 1;
- optional int64 RestoreOnStartup = 2;
- repeated string RestoreOnStartupURLs = 3;
-}
-
-message DefaultSearchProviderProto {
- optional PolicyOptions policy_options = 1;
- optional bool DefaultSearchProviderEnabled = 2;
- optional string DefaultSearchProviderName = 3;
- optional string DefaultSearchProviderKeyword = 4;
- optional string DefaultSearchProviderSearchURL = 5;
- optional string DefaultSearchProviderSuggestURL = 6;
- optional string DefaultSearchProviderInstantURL = 7;
- optional string DefaultSearchProviderIconURL = 8;
- repeated string DefaultSearchProviderEncodings = 9;
-}
-
-message ContentSettingsProto {
- optional PolicyOptions policy_options = 1;
- optional int64 DefaultCookiesSetting = 2;
- optional int64 DefaultImagesSetting = 3;
- optional int64 DefaultJavaScriptSetting = 4;
- optional int64 DefaultPluginsSetting = 5;
- optional int64 DefaultPopupsSetting = 6;
- optional int64 DefaultNotificationSetting = 7;
- optional int64 DefaultGeolocationSetting = 8;
-}
-
-message Disable3DAPIsProto {
- optional PolicyOptions policy_options = 1;
- optional bool Disable3DAPIs = 2;
-}
-
-message ChromeFrameRendererSettingsProto {
- optional PolicyOptions policy_options = 1;
- optional int64 ChromeFrameRendererSettings = 2;
- repeated string RenderInChromeFrameList = 3;
- repeated string RenderInHostList = 4;
-}
-
-message ChromeFrameContentTypesProto {
- optional PolicyOptions policy_options = 1;
- repeated string ChromeFrameContentTypes = 2;
-}
-
-message ChromeOsLockOnIdleSuspendProto {
- optional PolicyOptions policy_options = 1;
- optional bool ChromeOsLockOnIdleSuspend = 2;
-}
-
-
-// --------------------------------------------------
-// Wrapper PB for DMServer -> ChromeOS communication.
-
-message CloudPolicySettings {
- optional HomepageProto Homepage = 1;
- optional ApplicationLocaleValueProto ApplicationLocaleValue = 2;
- optional AlternateErrorPagesEnabledProto AlternateErrorPagesEnabled = 3;
- optional SearchSuggestEnabledProto SearchSuggestEnabled = 4;
- optional DnsPrefetchingEnabledProto DnsPrefetchingEnabled = 5;
- optional DisableSpdyProto DisableSpdy = 6;
- optional JavascriptEnabledProto JavascriptEnabled = 7;
- optional SavingBrowserHistoryDisabledProto SavingBrowserHistoryDisabled = 8;
- optional PrintingEnabledProto PrintingEnabled = 9;
- optional SafeBrowsingEnabledProto SafeBrowsingEnabled = 10;
- optional MetricsReportingEnabledProto MetricsReportingEnabled = 11;
- optional PasswordManagerProto PasswordManager = 12;
- optional AutoFillEnabledProto AutoFillEnabled = 13;
- optional DisabledPluginsProto DisabledPlugins = 14;
- optional SyncDisabledProto SyncDisabled = 15;
- optional ProxyProto Proxy = 16;
- optional HTTPAuthenticationProto HTTPAuthentication = 17;
- optional ExtensionsProto Extensions = 18;
- optional ShowHomeButtonProto ShowHomeButton = 19;
- optional DeveloperToolsDisabledProto DeveloperToolsDisabled = 20;
- optional RestoreOnStartupGroupProto RestoreOnStartupGroup = 21;
- optional DefaultSearchProviderProto DefaultSearchProvider = 22;
- optional ContentSettingsProto ContentSettings = 23;
- optional Disable3DAPIsProto Disable3DAPIs = 24;
- optional ChromeFrameRendererSettingsProto ChromeFrameRendererSettings = 25;
- optional ChromeFrameContentTypesProto ChromeFrameContentTypes = 26;
- optional ChromeOsLockOnIdleSuspendProto ChromeOsLockOnIdleSuspend = 27;
-}
diff --git a/chrome/browser/policy/proto/device_management_backend.proto b/chrome/browser/policy/proto/device_management_backend.proto
index 3187f6b..1a857b6 100644
--- a/chrome/browser/policy/proto/device_management_backend.proto
+++ b/chrome/browser/policy/proto/device_management_backend.proto
@@ -88,62 +88,94 @@ message DevicePolicyResponse {
repeated DevicePolicySetting setting = 1;
}
+// Request from device to server to register device. The response will include
+// a device token that can be used to query policies.
+message DeviceRegisterRequest {
+ // reregister device without erasing server state.
+ // it can be used to refresh dmtoken etc.
+ optional bool reregister = 1;
+}
+
+// Response from server to device register request.
+message DeviceRegisterResponse {
+ // device mangement toke for this registration.
+ required string device_management_token = 1;
+}
+
// Protocol buffers for the new protocol:
// --------------------------------------
-// Request from device to server to query if the authenticated user is in a
-// managed domain.
-message ManagedCheckRequest {
+// Request from device to server to get policies for an unregistered user.
+// These are actually "meta-policies", that control the rules for the user
+// about enrolling for real policies.
+message InitialPolicyRequest {
}
-// Response from server to device indicating if the authenticated user is in a
-// managed domain.
-message ManagedCheckResponse {
- enum Mode {
- // The device must be enrolled for policies.
+message InitialPolicySettings {
+ enum EnrollmentRule {
+ // The user must enroll its device for policies.
MANAGED = 1;
- // The device is not automatically enrolled for policies, but the user
- // may choose to try to enroll it.
+ // The users's device is not automatically enrolled for policies, but the
+ // user may choose to try to enroll it.
UNMANAGED = 2;
}
- optional Mode mode = 1;
+ optional EnrollmentRule enrollment_rule = 1;
}
-// Request from device to server to register device.
-message DeviceRegisterRequest {
- // reregister device without erasing server state.
- // it can be used to refresh dmtoken etc.
- optional bool reregister = 1;
+// Response from server to device containing the policies available before
+// registration.
+message InitialPolicyResponse {
+ optional InitialPolicySettings settings = 1;
}
-// Response from server to device register request.
-message DeviceRegisterResponse {
- // device mangement toke for this registration.
- required string device_management_token = 1;
+// Request from device to server to unregister device management token.
+message DeviceUnregisterRequest {
+}
- // The name of the device, assigned by the server.
- optional string device_name = 2;
+// Response from server to unregister request.
+message DeviceUnregisterResponse {
}
-// Request from device to server to unregister device.
-message DeviceUnregisterRequest {
+// Request from device to server to register device. The response will include
+// a device token that can be used to query policies.
+message CloudRegisterRequest {
+ enum Type {
+ // Requesting token for user policies.
+ USER = 1;
+ // Requesting token for device policies.
+ DEVICE = 2;
+ }
+ optional Type type = 1;
+ // Unique identifier of the machine. Only set if type == DEVICE.
+ // This won't be sent in later requests, the machine can be identified
+ // by its device token.
+ optional string machine_id = 2;
}
-// Response from server to device unregister request.
-message DeviceUnregisterResponse {
+// Response from server to device register request.
+message CloudRegisterResponse {
+ // Token for this registration.
+ required string device_management_token = 1;
+
+ // The name of the requesting device, assigned by the server.
+ optional string machine_name = 2;
}
message CloudPolicyRequest {
// Identify request scope: chromeos/device for device policies, chromeos/user
- // for user policies.
+ // for user policies. Only those policy scopes will be served, that are
+ // allowed by the type choice in CloudRegisterRequest.
optional string policy_scope = 1;
- // The device token of the owner of the device sending the request. In cases
- // the request was sent by the device owner or device policies were
- // requested, this is the same as the token used for authentication.
- // Otherwise (if the user policy is requested for someone else than the device
- // owner) this token is different from the token used for authentication.
- optional string device_token = 2;
+
+ // The token used to query device policies on the device sending the request.
+ // Note, that the token used for actual authentication is sent in an HTTP
+ // header. These two tokens are the same if this request is for querying
+ // device policies and they differ if this request is for querying user
+ // policies. In the second case, the server can use device_policy_token to
+ // identify the device and determine if the user is allowed to get policies
+ // on the given device.
+ optional string device_policy_token = 2;
}
// Response from server to device for reading policies.
@@ -176,20 +208,20 @@ message SignedCloudPolicyResponse {
//
// Http Query parameters:
// Query parameters contain the following information in each request:
-// request: register/unregister/policy/cloud_policy/managed_check etc.
+// request: register/unregister/policy/cloud_policy/cloud_register/
+// initial_policy
// devicetype: CrOS/Android/Iphone etc.
// apptype: CrOS/AndroidDM etc.
-// deviceid: unique id that identify the device.
// agent: identify agent on device.
//
// Authorization:
-// 1. If request is managed_check, client must pass in GoogleLogin auth
-// cookie in Authorization header:
+// 1. If request is initial_policy, client must pass in GoogleLogin
+// auth cookie in Authorization header:
// Authorization: GoogleLogin auth=<auth cookie>
-// This is the only case when the deviceid query parameter is set to empty.
-// The response will contain a flag indicating if the user is in a managed
-// domain or not. (We don't want to expose device ids of users not in
-// managed domains.)
+// The response will contain settings that a user can get without
+// registration. Currently the only such setting is a flag indicating if the
+// user is in a managed domain or not. (We don't want to expose device ids of
+// users not in managed domains.)
// 2. If request is register_request, client must pass in GoogleLogin auth
// cookie in Authorization header:
// Authorization: GoogleLogin auth=<auth cookie>
@@ -200,7 +232,7 @@ message SignedCloudPolicyResponse {
// Authorization: GoogleDMToken token=<google dm token>
//
message DeviceManagementRequest {
- // Register request.
+ // Register request (old protocol).
optional DeviceRegisterRequest register_request = 1;
// Unregister request.
@@ -212,8 +244,11 @@ message DeviceManagementRequest {
// Data request (new protocol).
optional CloudPolicyRequest cloud_policy_request = 4;
- // Request to check if a user is managed or not.
- optional ManagedCheckRequest managed_check_request = 5;
+ // Request for initial (before registration) policies.
+ optional InitialPolicyRequest initial_policy_request = 5;
+
+ // Register request (new protocol).
+ optional CloudRegisterRequest cloud_register_request = 6;
}
// Response from server to device.
@@ -241,7 +276,7 @@ message DeviceManagementResponse {
// Error message.
optional string error_message = 2;
- // Register response
+ // Register response (old protocol).
optional DeviceRegisterResponse register_response = 3;
// Unregister response
@@ -253,6 +288,9 @@ message DeviceManagementResponse {
// Policy response (new protocol).
optional CloudPolicyResponse cloud_policy_response = 6;
- // Response to managed check request.
- optional ManagedCheckResponse managed_check_response = 7;
+ // Response to initial (before registration) policy request.
+ optional InitialPolicyResponse initial_policy_response = 7;
+
+ // Register response (new protocol).
+ optional CloudRegisterResponse cloud_register_response = 8;
} \ No newline at end of file
diff --git a/chrome/browser/policy/proto/device_management_local.proto b/chrome/browser/policy/proto/device_management_local.proto
index a991551..45c2994 100644
--- a/chrome/browser/policy/proto/device_management_local.proto
+++ b/chrome/browser/policy/proto/device_management_local.proto
@@ -10,14 +10,18 @@ package enterprise_management;
import "device_management_backend.proto";
-// Wrapper around DevicePolicyResponse for caching on disk.
-message CachedDevicePolicyResponse {
+// Wrapper around CloudPolicyResponse/DevicePolicyResponse for caching on disk.
+message CachedCloudPolicyResponse {
// The DevicePolicyResponse wrapped by this message.
- optional DevicePolicyResponse policy = 1;
- // Timestamp noting when this policy was cached.
+ optional DevicePolicyResponse device_policy = 1;
+ // Timestamp noting when the |unmanaged| flag was set. The data format is
+ // a unix timestamp. When caching (deprecated) DevicePolicyResponses, this
+ // timestamp also notes when the response was cached.
optional uint64 timestamp = 2;
// Flag that is set to true if this device is not managed.
optional bool unmanaged = 3;
+ // The CloudPolicyResponse wrapped by this message.
+ optional CloudPolicyResponse cloud_policy = 4;
}
// Encapsulates a device ID and the associated device token.
diff --git a/chrome/browser/policy/proto/device_management_proto.gyp b/chrome/browser/policy/proto/device_management_proto.gyp
deleted file mode 100644
index ede0251..0000000
--- a/chrome/browser/policy/proto/device_management_proto.gyp
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright (c) 2010 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.
-
-{
- 'variables': {
- 'chromium_code': 1,
- 'protoc_out_dir': '<(SHARED_INTERMEDIATE_DIR)/protoc_out',
- },
- 'targets': [
- {
- # Protobuf compiler / generate rule for the device management protocol.
- 'target_name': 'device_management_proto',
- 'type': 'none',
- 'sources': [
- 'cloud_policy.proto',
- 'device_management_backend.proto',
- 'device_management_local.proto',
- ],
- 'rules': [
- {
- 'rule_name': 'genproto',
- 'extension': 'proto',
- 'inputs': [
- '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
- ],
- 'variables': {
- # The protoc compiler requires a proto_path argument with the
- # directory containing the .proto file. There's no generator
- # variable that corresponds to this, so fake it.
- 'rule_input_relpath': 'chrome/browser/policy/proto',
- },
- 'outputs': [
- '<(PRODUCT_DIR)/pyproto/device_management_pb/<(RULE_INPUT_ROOT)_pb2.py',
- '<(protoc_out_dir)/<(rule_input_relpath)/<(RULE_INPUT_ROOT).pb.h',
- '<(protoc_out_dir)/<(rule_input_relpath)/<(RULE_INPUT_ROOT).pb.cc',
- ],
- 'action': [
- '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
- '--proto_path=.',
- './<(RULE_INPUT_ROOT)<(RULE_INPUT_EXT)',
- '--cpp_out=<(protoc_out_dir)/<(rule_input_relpath)',
- '--python_out=<(PRODUCT_DIR)/pyproto/device_management_pb',
- ],
- 'message': 'Generating C++ and Python code from <(RULE_INPUT_PATH)',
- },
- ],
- 'dependencies': [
- '../../../../third_party/protobuf/protobuf.gyp:protoc#host',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(protoc_out_dir)',
- ]
- },
- },
- {
- 'target_name': 'device_management_proto_cpp',
- 'type': 'none',
- 'export_dependent_settings': [
- '../../../../third_party/protobuf/protobuf.gyp:protobuf_lite',
- 'device_management_proto',
- ],
- 'dependencies': [
- '../../../../third_party/protobuf/protobuf.gyp:protobuf_lite',
- 'device_management_proto',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(protoc_out_dir)',
- ]
- },
- },
- ],
-}
-
-# Local Variables:
-# tab-width:2
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=2 shiftwidth=2: