| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/policy/cloud_policy_cache_base.h" | 5 #include "chrome/browser/policy/cloud_policy_cache_base.h" |
| 6 | 6 |
| 7 #include <set> |
| 7 #include <string> | 8 #include <string> |
| 8 | 9 |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "base/values.h" | 11 #include "base/values.h" |
| 11 #include "chrome/browser/policy/configuration_policy_pref_store.h" | 12 #include "chrome/browser/policy/configuration_policy_pref_store.h" |
| 12 #include "chrome/browser/policy/policy_notifier.h" | 13 #include "chrome/browser/policy/policy_notifier.h" |
| 13 | 14 |
| 14 namespace policy { | 15 namespace policy { |
| 15 | 16 |
| 16 // A thin ConfigurationPolicyProvider implementation sitting on top of | 17 CloudPolicyProvider::CloudPolicyProvider( |
| 17 // CloudPolicyCacheBase for hooking up with ConfigurationPolicyPrefStore. | 18 const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list, |
| 18 class CloudPolicyCacheBase::CloudPolicyProvider | 19 CloudPolicyCacheBase::PolicyLevel level) |
| 19 : public ConfigurationPolicyProvider { | 20 : ConfigurationPolicyProvider(policy_list), |
| 20 public: | 21 cache_(NULL), |
| 21 CloudPolicyProvider(const PolicyDefinitionList* policy_list, | 22 level_(level) {} |
| 22 CloudPolicyCacheBase* cache, | |
| 23 CloudPolicyCacheBase::PolicyLevel level) | |
| 24 : ConfigurationPolicyProvider(policy_list), | |
| 25 cache_(cache), | |
| 26 level_(level) {} | |
| 27 virtual ~CloudPolicyProvider() {} | |
| 28 | 23 |
| 29 virtual bool Provide(ConfigurationPolicyStoreInterface* store) { | 24 CloudPolicyProvider::~CloudPolicyProvider() { |
| 30 if (level_ == POLICY_LEVEL_MANDATORY) | 25 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
| 31 ApplyPolicyMap(&cache_->mandatory_policy_, store); | 26 observer_list_, OnProviderGoingAway()); |
| 32 else if (level_ == POLICY_LEVEL_RECOMMENDED) | 27 if (cache_) |
| 33 ApplyPolicyMap(&cache_->recommended_policy_, store); | 28 cache_->RemoveObserver(this); |
| 34 return true; | 29 } |
| 30 |
| 31 void CloudPolicyProvider::set_cache(CloudPolicyCacheBase* cache) { |
| 32 cache_ = cache; |
| 33 cache_->AddObserver(this); |
| 34 } |
| 35 |
| 36 bool CloudPolicyProvider::Provide(ConfigurationPolicyStoreInterface* store) { |
| 37 if (!cache_) |
| 38 return false; |
| 39 if (level_ == CloudPolicyCacheBase::POLICY_LEVEL_MANDATORY) |
| 40 ApplyPolicyMap(cache_->mandatory_policy(), store); |
| 41 else if (level_ == CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED) |
| 42 ApplyPolicyMap(cache_->recommended_policy(), store); |
| 43 return true; |
| 44 } |
| 45 |
| 46 bool CloudPolicyProvider::IsInitializationComplete() const { |
| 47 return cache_ && cache_->initialization_complete(); |
| 48 } |
| 49 |
| 50 void CloudPolicyProvider::AddObserver( |
| 51 ConfigurationPolicyProvider::Observer* observer) { |
| 52 observer_list_.AddObserver(observer); |
| 53 } |
| 54 void CloudPolicyProvider::RemoveObserver( |
| 55 ConfigurationPolicyProvider::Observer* observer) { |
| 56 observer_list_.RemoveObserver(observer); |
| 57 } |
| 58 |
| 59 void CloudPolicyProvider::OnUpdatePolicy() { |
| 60 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
| 61 observer_list_, OnUpdatePolicy()); |
| 62 } |
| 63 |
| 64 void CloudPolicyProvider::OnProviderGoingAway() { |
| 65 cache_->RemoveObserver(this); |
| 66 cache_ = NULL; |
| 67 } |
| 68 |
| 69 PolicyMap* CloudPolicyProvider::policy_map() { |
| 70 if (!cache_) |
| 71 return NULL; |
| 72 if (level_ == CloudPolicyCacheBase::POLICY_LEVEL_MANDATORY) |
| 73 return cache_->mandatory_policy(); |
| 74 else if (level_ == CloudPolicyCacheBase::POLICY_LEVEL_RECOMMENDED) |
| 75 return cache_->recommended_policy(); |
| 76 NOTREACHED(); |
| 77 return NULL; |
| 78 } |
| 79 |
| 80 CombiningCloudPolicyProvider::CombiningCloudPolicyProvider( |
| 81 const ConfigurationPolicyProvider::PolicyDefinitionList* policy_list) |
| 82 : ConfigurationPolicyProvider(policy_list) {} |
| 83 |
| 84 CombiningCloudPolicyProvider::~CombiningCloudPolicyProvider() { |
| 85 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
| 86 observer_list_, OnProviderGoingAway()); |
| 87 } |
| 88 |
| 89 void CombiningCloudPolicyProvider::AddCloudPolicyProvider( |
| 90 CloudPolicyProvider* cloud_policy_provider) { |
| 91 cloud_policy_providers_.push_back( |
| 92 new CloudPolicyProviderWithObserver(this, |
| 93 cloud_policy_provider)); |
| 94 } |
| 95 |
| 96 bool CombiningCloudPolicyProvider::Provide( |
| 97 ConfigurationPolicyStoreInterface* store) { |
| 98 typedef std::set<ConfigurationPolicyType> PolicySet; |
| 99 PolicySet already_applied; |
| 100 PolicySet newly_applied; |
| 101 for (ListType::iterator i = cloud_policy_providers_.begin(); |
| 102 i != cloud_policy_providers_.end(); ++i) { |
| 103 if ((*i)->cloud_policy_provider() && |
| 104 (*i)->cloud_policy_provider()->IsInitializationComplete()) { |
| 105 PolicyMap* policy_map = (*i)->cloud_policy_provider()->policy_map(); |
| 106 if (policy_map) { |
| 107 const PolicyDefinitionList* policy_list(policy_definition_list()); |
| 108 for (const PolicyDefinitionList::Entry* j = policy_list->begin; |
| 109 j != policy_list->end; ++j) { |
| 110 // Already applied by a CloudProvider which takes precedence. |
| 111 if (already_applied.find(j->policy_type)!=already_applied.end()) |
| 112 continue; |
| 113 const Value* value = policy_map->Get(j->policy_type); |
| 114 if (value && value->IsType(j->value_type)) { |
| 115 newly_applied.insert(j->policy_type); |
| 116 store->Apply(j->policy_type, value->DeepCopy()); |
| 117 } |
| 118 } |
| 119 // Update the already_applied PolicySet |
| 120 for (PolicySet::iterator policy = newly_applied.begin(); |
| 121 policy != newly_applied.end(); ++policy) { |
| 122 already_applied.insert(*policy); |
| 123 // In case that one Proxy Policy got applied, we want to set all of |
| 124 // them as applied. We need that in order not to end up with an |
| 125 // inconsistend Proxy-state in case that the different Policy-related |
| 126 // Policies got set by different CloudPolicyProviders. |
| 127 if (*policy == kPolicyProxyMode || |
| 128 *policy == kPolicyProxyServerMode || |
| 129 *policy == kPolicyProxyServer || |
| 130 *policy == kPolicyProxyPacUrl || |
| 131 *policy == kPolicyProxyBypassList) { |
| 132 already_applied.insert(kPolicyProxyMode); |
| 133 already_applied.insert(kPolicyProxyServerMode); |
| 134 already_applied.insert(kPolicyProxyServer); |
| 135 already_applied.insert(kPolicyProxyPacUrl); |
| 136 already_applied.insert(kPolicyProxyBypassList); |
| 137 } |
| 138 } |
| 139 } |
| 140 } |
| 35 } | 141 } |
| 142 // Return true if we could apply at least one policy. |
| 143 return !already_applied.empty(); |
| 144 } |
| 36 | 145 |
| 37 virtual bool IsInitializationComplete() const { | 146 bool CombiningCloudPolicyProvider::IsInitializationComplete() const { |
| 38 return cache_->initialization_complete_; | 147 bool initialization_complete = false; |
| 148 for (ListType::const_iterator i = cloud_policy_providers_.begin(); |
| 149 i != cloud_policy_providers_.end(); ++i) { |
| 150 initialization_complete = initialization_complete || |
| 151 ((*i)->cloud_policy_provider() && |
| 152 (*i)->cloud_policy_provider()->IsInitializationComplete()); |
| 39 } | 153 } |
| 154 return initialization_complete; |
| 155 } |
| 40 | 156 |
| 41 virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) { | 157 void CombiningCloudPolicyProvider::AddObserver( |
| 42 cache_->observer_list_.AddObserver(observer); | 158 ConfigurationPolicyProvider::Observer* observer) { |
| 159 observer_list_.AddObserver(observer); |
| 160 } |
| 161 |
| 162 void CombiningCloudPolicyProvider::RemoveObserver( |
| 163 ConfigurationPolicyProvider::Observer* observer) { |
| 164 observer_list_.RemoveObserver(observer); |
| 165 } |
| 166 |
| 167 // Note: we are triggering updates even though the change might not actually be |
| 168 // visible to the outside. |
| 169 void CombiningCloudPolicyProvider::OnUpdatePolicy( |
| 170 CloudPolicyProvider* cloud_policy_provider) { |
| 171 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
| 172 observer_list_, OnUpdatePolicy()); |
| 173 } |
| 174 |
| 175 // Removes the going-away CloudPolicyProvider from |cloud_policy_providers_|. |
| 176 void CombiningCloudPolicyProvider::OnProviderGoingAway( |
| 177 CloudPolicyProvider* cloud_policy_provider) { |
| 178 ListType::iterator i; |
| 179 for (i = cloud_policy_providers_.begin(); |
| 180 i != cloud_policy_providers_.end(); ++i) { |
| 181 if ((*i)->cloud_policy_provider() == cloud_policy_provider) { |
| 182 cloud_policy_providers_.erase(i); |
| 183 return; |
| 184 } |
| 43 } | 185 } |
| 44 virtual void RemoveObserver(ConfigurationPolicyProvider::Observer* observer) { | 186 } |
| 45 cache_->observer_list_.RemoveObserver(observer); | |
| 46 } | |
| 47 | |
| 48 private: | |
| 49 // The underlying policy cache. | |
| 50 CloudPolicyCacheBase* cache_; | |
| 51 // Policy level this provider will handle. | |
| 52 CloudPolicyCacheBase::PolicyLevel level_; | |
| 53 | |
| 54 DISALLOW_COPY_AND_ASSIGN(CloudPolicyProvider); | |
| 55 }; | |
| 56 | 187 |
| 57 CloudPolicyCacheBase::CloudPolicyCacheBase() | 188 CloudPolicyCacheBase::CloudPolicyCacheBase() |
| 58 : notifier_(NULL), | 189 : notifier_(NULL), |
| 59 initialization_complete_(false), | 190 initialization_complete_(false), |
| 60 is_unmanaged_(false) { | 191 is_unmanaged_(false) { |
| 61 public_key_version_.valid = false; | 192 public_key_version_.valid = false; |
| 62 managed_policy_provider_.reset( | |
| 63 new CloudPolicyProvider( | |
| 64 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), | |
| 65 this, | |
| 66 POLICY_LEVEL_MANDATORY)); | |
| 67 recommended_policy_provider_.reset( | |
| 68 new CloudPolicyProvider( | |
| 69 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(), | |
| 70 this, | |
| 71 POLICY_LEVEL_RECOMMENDED)); | |
| 72 } | 193 } |
| 73 | 194 |
| 74 CloudPolicyCacheBase::~CloudPolicyCacheBase() { | 195 CloudPolicyCacheBase::~CloudPolicyCacheBase() { |
| 75 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, | 196 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
| 76 observer_list_, OnProviderGoingAway()); | 197 observer_list_, OnProviderGoingAway()); |
| 77 } | 198 } |
| 78 | 199 |
| 200 void CloudPolicyCacheBase::AddObserver( |
| 201 ConfigurationPolicyProvider::Observer* observer) { |
| 202 observer_list_.AddObserver(observer); |
| 203 } |
| 204 |
| 205 void CloudPolicyCacheBase::RemoveObserver( |
| 206 ConfigurationPolicyProvider::Observer* observer) { |
| 207 observer_list_.RemoveObserver(observer); |
| 208 } |
| 209 |
| 210 PolicyMap* CloudPolicyCacheBase::mandatory_policy() { |
| 211 return &mandatory_policy_; |
| 212 } |
| 213 |
| 214 PolicyMap* CloudPolicyCacheBase::recommended_policy() { |
| 215 return &recommended_policy_; |
| 216 } |
| 217 |
| 79 bool CloudPolicyCacheBase::GetPublicKeyVersion(int* version) { | 218 bool CloudPolicyCacheBase::GetPublicKeyVersion(int* version) { |
| 80 if (public_key_version_.valid) | 219 if (public_key_version_.valid) |
| 81 *version = public_key_version_.version; | 220 *version = public_key_version_.version; |
| 82 | 221 |
| 83 return public_key_version_.valid; | 222 return public_key_version_.valid; |
| 84 } | 223 } |
| 85 | 224 |
| 86 bool CloudPolicyCacheBase::SetPolicyInternal( | 225 bool CloudPolicyCacheBase::SetPolicyInternal( |
| 87 const em::PolicyFetchResponse& policy, | 226 const em::PolicyFetchResponse& policy, |
| 88 base::Time* timestamp, | 227 base::Time* timestamp, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 initialization_complete_ = true; | 271 initialization_complete_ = true; |
| 133 public_key_version_.valid = false; | 272 public_key_version_.valid = false; |
| 134 mandatory_policy_.Clear(); | 273 mandatory_policy_.Clear(); |
| 135 recommended_policy_.Clear(); | 274 recommended_policy_.Clear(); |
| 136 last_policy_refresh_time_ = timestamp; | 275 last_policy_refresh_time_ = timestamp; |
| 137 | 276 |
| 138 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, | 277 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer, |
| 139 observer_list_, OnUpdatePolicy()); | 278 observer_list_, OnUpdatePolicy()); |
| 140 } | 279 } |
| 141 | 280 |
| 142 ConfigurationPolicyProvider* CloudPolicyCacheBase::GetManagedPolicyProvider() { | |
| 143 DCHECK(CalledOnValidThread()); | |
| 144 return managed_policy_provider_.get(); | |
| 145 } | |
| 146 | |
| 147 ConfigurationPolicyProvider* | |
| 148 CloudPolicyCacheBase::GetRecommendedPolicyProvider() { | |
| 149 DCHECK(CalledOnValidThread()); | |
| 150 return recommended_policy_provider_.get(); | |
| 151 } | |
| 152 | |
| 153 bool CloudPolicyCacheBase::DecodePolicyResponse( | 281 bool CloudPolicyCacheBase::DecodePolicyResponse( |
| 154 const em::PolicyFetchResponse& policy_response, | 282 const em::PolicyFetchResponse& policy_response, |
| 155 PolicyMap* mandatory, | 283 PolicyMap* mandatory, |
| 156 PolicyMap* recommended, | 284 PolicyMap* recommended, |
| 157 base::Time* timestamp, | 285 base::Time* timestamp, |
| 158 PublicKeyVersion* public_key_version) { | 286 PublicKeyVersion* public_key_version) { |
| 159 std::string data = policy_response.policy_data(); | 287 std::string data = policy_response.policy_data(); |
| 160 em::PolicyData policy_data; | 288 em::PolicyData policy_data; |
| 161 if (!policy_data.ParseFromString(data)) { | 289 if (!policy_data.ParseFromString(data)) { |
| 162 LOG(WARNING) << "Failed to parse PolicyData protobuf."; | 290 LOG(WARNING) << "Failed to parse PolicyData protobuf."; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 178 void CloudPolicyCacheBase::InformNotifier( | 306 void CloudPolicyCacheBase::InformNotifier( |
| 179 CloudPolicySubsystem::PolicySubsystemState state, | 307 CloudPolicySubsystem::PolicySubsystemState state, |
| 180 CloudPolicySubsystem::ErrorDetails error_details) { | 308 CloudPolicySubsystem::ErrorDetails error_details) { |
| 181 // TODO(jkummerow): To obsolete this NULL-check, make all uses of | 309 // TODO(jkummerow): To obsolete this NULL-check, make all uses of |
| 182 // UserPolicyCache explicitly set a notifier using |set_policy_notifier()|. | 310 // UserPolicyCache explicitly set a notifier using |set_policy_notifier()|. |
| 183 if (notifier_) | 311 if (notifier_) |
| 184 notifier_->Inform(state, error_details, PolicyNotifier::POLICY_CACHE); | 312 notifier_->Inform(state, error_details, PolicyNotifier::POLICY_CACHE); |
| 185 } | 313 } |
| 186 | 314 |
| 187 } // namespace policy | 315 } // namespace policy |
| OLD | NEW |