Index: chrome/browser/policy/cloud_policy_cache_base.cc |
diff --git a/chrome/browser/policy/cloud_policy_cache_base.cc b/chrome/browser/policy/cloud_policy_cache_base.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cddbc162a830adf13f279940e41b1425cc24a327 |
--- /dev/null |
+++ b/chrome/browser/policy/cloud_policy_cache_base.cc |
@@ -0,0 +1,154 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/policy/cloud_policy_cache_base.h" |
+ |
+#include <string> |
+ |
+#include "base/logging.h" |
+#include "base/values.h" |
+#include "chrome/browser/policy/configuration_policy_pref_store.h" |
+ |
+namespace policy { |
+ |
+// A thin ConfigurationPolicyProvider implementation sitting on top of |
+// CloudPolicyCacheBase for hooking up with ConfigurationPolicyPrefStore. |
+class CloudPolicyCacheBase::CloudPolicyProvider |
+ : public ConfigurationPolicyProvider { |
+ public: |
+ CloudPolicyProvider(const PolicyDefinitionList* policy_list, |
+ CloudPolicyCacheBase* cache, |
+ CloudPolicyCacheBase::PolicyLevel level) |
+ : ConfigurationPolicyProvider(policy_list), |
+ cache_(cache), |
+ level_(level) {} |
+ virtual ~CloudPolicyProvider() {} |
+ |
+ virtual bool Provide(ConfigurationPolicyStoreInterface* store) { |
+ if (level_ == POLICY_LEVEL_MANDATORY) |
+ ApplyPolicyMap(&cache_->mandatory_policy_, store); |
+ else if (level_ == POLICY_LEVEL_RECOMMENDED) |
+ ApplyPolicyMap(&cache_->recommended_policy_, store); |
+ return true; |
+ } |
+ |
+ virtual bool IsInitializationComplete() const { |
+ return cache_->initialization_complete_; |
+ } |
+ |
+ virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) { |
+ cache_->observer_list_.AddObserver(observer); |
+ } |
+ virtual void RemoveObserver(ConfigurationPolicyProvider::Observer* observer) { |
+ cache_->observer_list_.RemoveObserver(observer); |
+ } |
+ |
+ private: |
+ // The underlying policy cache. |
+ CloudPolicyCacheBase* cache_; |
+ // Policy level this provider will handle. |
+ CloudPolicyCacheBase::PolicyLevel level_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(CloudPolicyProvider); |
+}; |
+ |
+CloudPolicyCacheBase::CloudPolicyCacheBase() |
+ : initialization_complete_(false), |
+ is_unmanaged_(false) { |
+ managed_policy_provider_.reset( |
+ new CloudPolicyProvider( |
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), |
+ this, |
+ POLICY_LEVEL_MANDATORY)); |
+ recommended_policy_provider_.reset( |
+ new CloudPolicyProvider( |
+ ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), |
+ this, |
+ POLICY_LEVEL_RECOMMENDED)); |
+} |
+ |
+CloudPolicyCacheBase::~CloudPolicyCacheBase() { |
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
+ observer_list_, OnProviderGoingAway()); |
+} |
+ |
+bool CloudPolicyCacheBase::SetPolicyInternal( |
+ const em::PolicyFetchResponse& policy, |
+ base::Time* timestamp, |
+ bool check_for_timestamp_validity) { |
+ DCHECK(CalledOnValidThread()); |
+ base::Time temp_timestamp; |
+ if (!timestamp && check_for_timestamp_validity) |
+ timestamp = &temp_timestamp; |
+ bool initialization_was_not_complete = !initialization_complete_; |
+ is_unmanaged_ = false; |
+ PolicyMap mandatory_policy; |
+ PolicyMap recommended_policy; |
+ bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy, |
+ timestamp); |
+ if (!ok) { |
+ LOG(WARNING) << "Decoding policy data failed."; |
+ return false; |
+ } |
+ if (timestamp && check_for_timestamp_validity && |
+ *timestamp > base::Time::NowFromSystemTime()) { |
+ LOG(WARNING) << "Rejected policy data, file is from the future."; |
+ return false; |
+ } |
+ |
+ const bool new_policy_differs = |
+ !mandatory_policy_.Equals(mandatory_policy) || |
+ !recommended_policy_.Equals(recommended_policy); |
+ mandatory_policy_.Swap(&mandatory_policy); |
+ recommended_policy_.Swap(&recommended_policy); |
+ initialization_complete_ = true; |
+ |
+ if (new_policy_differs || initialization_was_not_complete) { |
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
+ observer_list_, OnUpdatePolicy()); |
+ } |
+ return true; |
+} |
+ |
+void CloudPolicyCacheBase::SetUnmanagedInternal(const base::Time& timestamp) { |
+ is_unmanaged_ = true; |
+ initialization_complete_ = true; |
+ mandatory_policy_.Clear(); |
+ recommended_policy_.Clear(); |
+ last_policy_refresh_time_ = timestamp; |
+ |
+ FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
+ observer_list_, OnUpdatePolicy()); |
+} |
+ |
+ConfigurationPolicyProvider* CloudPolicyCacheBase::GetManagedPolicyProvider() { |
+ DCHECK(CalledOnValidThread()); |
+ return managed_policy_provider_.get(); |
+} |
+ |
+ConfigurationPolicyProvider* |
+ CloudPolicyCacheBase::GetRecommendedPolicyProvider() { |
+ DCHECK(CalledOnValidThread()); |
+ return recommended_policy_provider_.get(); |
+} |
+ |
+bool CloudPolicyCacheBase::DecodePolicyResponse( |
+ const em::PolicyFetchResponse& policy_response, |
+ PolicyMap* mandatory, |
+ PolicyMap* recommended, |
+ base::Time* timestamp) { |
+ std::string data = policy_response.policy_data(); |
+ em::PolicyData policy_data; |
+ if (!policy_data.ParseFromString(data)) { |
+ LOG(WARNING) << "Failed to parse PolicyData protobuf."; |
+ return false; |
+ } |
+ if (timestamp) { |
+ *timestamp = base::Time::UnixEpoch() + |
+ base::TimeDelta::FromMilliseconds(policy_data.timestamp()); |
+ } |
+ return DecodePolicyData(policy_data, mandatory, recommended); |
+} |
+ |
+} // namespace policy |