Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(395)

Side by Side Diff: chrome/browser/policy/cloud_policy_cache.cc

Issue 6520008: Device policy infrastructure (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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.h" 5 #include "chrome/browser/policy/cloud_policy_cache.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/task.h" 11 #include "base/task.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/browser_thread.h" 13 #include "chrome/browser/browser_thread.h"
14 #include "chrome/browser/policy/configuration_policy_pref_store.h"
14 #include "chrome/browser/policy/proto/cloud_policy.pb.h" 15 #include "chrome/browser/policy/proto/cloud_policy.pb.h"
15 #include "chrome/browser/policy/proto/device_management_backend.pb.h"
16 #include "chrome/browser/policy/proto/device_management_constants.h" 16 #include "chrome/browser/policy/proto/device_management_constants.h"
17 #include "chrome/browser/policy/proto/device_management_local.pb.h" 17 #include "chrome/browser/policy/proto/device_management_local.pb.h"
18 18
19 using google::protobuf::RepeatedField; 19 using google::protobuf::RepeatedField;
20 using google::protobuf::RepeatedPtrField; 20 using google::protobuf::RepeatedPtrField;
21 21
22 // This CloudPolicyCache currently supports two protocols for the interaction 22 // This CloudPolicyCache currently supports two protocols for the interaction
23 // with DMServer: the old "DevicePolicy" format, which is being used in the 23 // with DMServer: the old "DevicePolicy" format, which is being used in the
24 // CrOS Pilot Program and will be deprecated afterwards, and the new 24 // CrOS Pilot Program and will be deprecated afterwards, and the new
25 // "CloudPolicy" format, which will be used exclusively after the public launch 25 // "CloudPolicy" format, which will be used exclusively after the public launch
26 // of ChromeOS. 26 // of ChromeOS.
27 27
28 namespace policy { 28 namespace policy {
29 29
30 // A thin ConfigurationPolicyProvider implementation sitting on top of
31 // CloudPolicyCache for hooking up with ConfigurationPolicyPrefStore.
32 class CloudPolicyCache::CloudPolicyProvider
33 : public ConfigurationPolicyProvider {
34 public:
35 CloudPolicyProvider(const PolicyDefinitionList* policy_list,
36 CloudPolicyCache* cache,
37 CloudPolicyCache::PolicyLevel level)
38 : ConfigurationPolicyProvider(policy_list),
39 cache_(cache),
40 level_(level) {}
41 virtual ~CloudPolicyProvider() {}
42
43 virtual bool Provide(ConfigurationPolicyStoreInterface* store) {
44 if (cache_->has_device_policy()) {
gfeher 2011/02/14 17:28:50 Shouldn't this be has_cloud_policy() ?
Jakob Kummerow 2011/02/21 12:12:15 Done. Good catch!
45 if (level_ == POLICY_LEVEL_MANDATORY)
46 ApplyPolicyMap(&cache_->mandatory_policy_, store);
47 else if (level_ == POLICY_LEVEL_RECOMMENDED)
48 ApplyPolicyMap(&cache_->recommended_policy_, store);
49 } else {
50 ApplyPolicyValueTree(cache_->device_policy_.get(), store);
51 }
52 return true;
53 }
54
55 virtual bool IsInitializationComplete() const {
56 return cache_->initialization_complete_;
57 }
58
59 virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) {
60 cache_->observer_list_.AddObserver(observer);
61 }
62 virtual void RemoveObserver(ConfigurationPolicyProvider::Observer* observer) {
63 cache_->observer_list_.RemoveObserver(observer);
64 }
65
66 private:
67 // The underlying policy cache.
68 CloudPolicyCache* cache_;
69 // Policy level this provider will handle.
70 CloudPolicyCache::PolicyLevel level_;
71
72 DISALLOW_COPY_AND_ASSIGN(CloudPolicyProvider);
73 };
74
30 // Saves policy information to a file. 75 // Saves policy information to a file.
31 class PersistPolicyTask : public Task { 76 class PersistPolicyTask : public Task {
32 public: 77 public:
33 PersistPolicyTask(const FilePath& path, 78 PersistPolicyTask(const FilePath& path,
34 const em::CloudPolicyResponse* cloud_policy_response, 79 const em::CloudPolicyResponse* cloud_policy_response,
35 const em::DevicePolicyResponse* device_policy_response, 80 const em::DevicePolicyResponse* device_policy_response,
36 const bool is_unmanaged) 81 const bool is_unmanaged)
37 : path_(path), 82 : path_(path),
38 cloud_policy_response_(cloud_policy_response), 83 cloud_policy_response_(cloud_policy_response),
39 device_policy_response_(device_policy_response), 84 device_policy_response_(device_policy_response),
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 if (file_util::WriteFile(path_, data.c_str(), size) != size) { 117 if (file_util::WriteFile(path_, data.c_str(), size) != size) {
73 LOG(WARNING) << "Failed to write " << path_.value(); 118 LOG(WARNING) << "Failed to write " << path_.value();
74 return; 119 return;
75 } 120 }
76 } 121 }
77 122
78 CloudPolicyCache::CloudPolicyCache( 123 CloudPolicyCache::CloudPolicyCache(
79 const FilePath& backing_file_path) 124 const FilePath& backing_file_path)
80 : backing_file_path_(backing_file_path), 125 : backing_file_path_(backing_file_path),
81 device_policy_(new DictionaryValue), 126 device_policy_(new DictionaryValue),
82 fresh_policy_(false), 127 initialization_complete_(false),
83 is_unmanaged_(false), 128 is_unmanaged_(false),
84 has_device_policy_(false) { 129 has_device_policy_(false) {
130 managed_policy_provider_.reset(
131 new CloudPolicyProvider(
132 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
133 this,
134 POLICY_LEVEL_MANDATORY));
135 recommended_policy_provider_.reset(
136 new CloudPolicyProvider(
137 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
138 this,
139 POLICY_LEVEL_RECOMMENDED));
85 } 140 }
86 141
87 CloudPolicyCache::~CloudPolicyCache() {} 142 CloudPolicyCache::~CloudPolicyCache() {
143 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
144 observer_list_, OnProviderGoingAway());
145 }
88 146
89 void CloudPolicyCache::LoadPolicyFromFile() { 147 void CloudPolicyCache::LoadFromFile() {
90 // TODO(jkummerow): This method is doing file IO during browser startup. In 148 // TODO(jkummerow): This method is doing file IO during browser startup. In
91 // the long run it would be better to delay this until the FILE thread exists. 149 // the long run it would be better to delay this until the FILE thread exists.
92 if (!file_util::PathExists(backing_file_path_) || fresh_policy_) { 150 if (!file_util::PathExists(backing_file_path_) || initialization_complete_) {
93 return; 151 return;
94 } 152 }
95 153
96 // Read the protobuf from the file. 154 // Read the protobuf from the file.
97 std::string data; 155 std::string data;
98 if (!file_util::ReadFileToString(backing_file_path_, &data)) { 156 if (!file_util::ReadFileToString(backing_file_path_, &data)) {
99 LOG(WARNING) << "Failed to read policy data from " 157 LOG(WARNING) << "Failed to read policy data from "
100 << backing_file_path_.value(); 158 << backing_file_path_.value();
101 return; 159 return;
102 } 160 }
(...skipping 20 matching lines...) Expand all
123 LOG(WARNING) << "Decoding policy data failed."; 181 LOG(WARNING) << "Decoding policy data failed.";
124 return; 182 return;
125 } 183 }
126 } 184 }
127 if (timestamp > base::Time::NowFromSystemTime()) { 185 if (timestamp > base::Time::NowFromSystemTime()) {
128 LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value() 186 LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value()
129 << ", file is from the future."; 187 << ", file is from the future.";
130 return; 188 return;
131 } 189 }
132 // Swap in the new policy information. 190 // Swap in the new policy information.
133 if (is_unmanaged_) { 191 if (cached_response.has_cloud_policy()) {
134 base::AutoLock lock(lock_); 192 mandatory_policy_.swap(mandatory_policy);
135 last_policy_refresh_time_ = timestamp; 193 recommended_policy_.swap(recommended_policy);
136 return; 194 has_device_policy_ = false;
137 } else if (cached_response.has_cloud_policy()) {
138 if (!fresh_policy_) {
139 base::AutoLock lock(lock_);
140 mandatory_policy_.swap(mandatory_policy);
141 recommended_policy_.swap(recommended_policy);
142 last_policy_refresh_time_ = timestamp;
143 has_device_policy_ = false;
144 }
145 } else if (cached_response.has_device_policy()) { 195 } else if (cached_response.has_device_policy()) {
146 scoped_ptr<DictionaryValue> value( 196 scoped_ptr<DictionaryValue> value(
147 DecodeDevicePolicy(cached_response.device_policy())); 197 DecodeDevicePolicy(cached_response.device_policy()));
148 if (!fresh_policy_) { 198 device_policy_.reset(value.release());
149 base::AutoLock lock(lock_); 199 has_device_policy_ = true;
150 device_policy_.reset(value.release());
151 last_policy_refresh_time_ = timestamp;
152 has_device_policy_ = true;
153 }
154 } 200 }
201 last_policy_refresh_time_ = timestamp;
202 initialization_complete_ = true;
203
204 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
205 observer_list_, OnUpdatePolicy());
155 } 206 }
156 207
157 bool CloudPolicyCache::SetPolicy(const em::CloudPolicyResponse& policy) { 208 bool CloudPolicyCache::SetPolicy(const em::CloudPolicyResponse& policy) {
158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 209 DCHECK(CalledOnValidThread());
159 is_unmanaged_ = false; 210 is_unmanaged_ = false;
160 base::Time timestamp; 211 base::Time timestamp;
161 PolicyMapType mandatory_policy; 212 PolicyMapType mandatory_policy;
162 PolicyMapType recommended_policy; 213 PolicyMapType recommended_policy;
163 bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy, 214 bool ok = DecodePolicyResponse(policy, &mandatory_policy, &recommended_policy,
164 &timestamp); 215 &timestamp);
165 if (!ok) { 216 if (!ok) {
166 // TODO(jkummerow): Signal error to PolicyProvider. 217 // TODO(jkummerow): Signal error to CloudPolicyController.
167 return false; 218 return false;
168 } 219 }
169 const bool new_policy_differs = 220 const bool new_policy_differs =
170 !Equals(mandatory_policy, mandatory_policy_) || 221 !Equals(mandatory_policy, mandatory_policy_) ||
171 !Equals(recommended_policy, recommended_policy_); 222 !Equals(recommended_policy, recommended_policy_);
172 { 223 mandatory_policy_.swap(mandatory_policy);
173 base::AutoLock lock(lock_); 224 recommended_policy_.swap(recommended_policy);
174 mandatory_policy_.swap(mandatory_policy); 225 initialization_complete_ = true;
175 recommended_policy_.swap(recommended_policy); 226 last_policy_refresh_time_ = timestamp;
176 fresh_policy_ = true; 227 has_device_policy_ = false;
177 last_policy_refresh_time_ = timestamp; 228
178 has_device_policy_ = false; 229 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
179 } 230 observer_list_, OnUpdatePolicy());
180 231
181 em::CloudPolicyResponse* policy_copy = new em::CloudPolicyResponse; 232 em::CloudPolicyResponse* policy_copy = new em::CloudPolicyResponse;
182 policy_copy->CopyFrom(policy); 233 policy_copy->CopyFrom(policy);
183 BrowserThread::PostTask( 234 BrowserThread::PostTask(
184 BrowserThread::FILE, 235 BrowserThread::FILE,
185 FROM_HERE, 236 FROM_HERE,
186 new PersistPolicyTask(backing_file_path_, policy_copy, NULL, false)); 237 new PersistPolicyTask(backing_file_path_, policy_copy, NULL, false));
187 return new_policy_differs; 238 return new_policy_differs;
188 } 239 }
189 240
190 bool CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) { 241 bool CloudPolicyCache::SetDevicePolicy(const em::DevicePolicyResponse& policy) {
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 242 DCHECK(CalledOnValidThread());
192 is_unmanaged_ = false; 243 is_unmanaged_ = false;
193 DictionaryValue* value = DecodeDevicePolicy(policy); 244 DictionaryValue* value = DecodeDevicePolicy(policy);
194 const bool new_policy_differs = !(value->Equals(device_policy_.get())); 245 const bool new_policy_differs = !(value->Equals(device_policy_.get()));
195 base::Time now(base::Time::NowFromSystemTime()); 246 base::Time now(base::Time::NowFromSystemTime());
196 { 247 device_policy_.reset(value);
197 base::AutoLock lock(lock_); 248 initialization_complete_ = true;
198 device_policy_.reset(value); 249 last_policy_refresh_time_ = now;
199 fresh_policy_ = true; 250 has_device_policy_ = true;
200 last_policy_refresh_time_ = now; 251
201 has_device_policy_ = true; 252 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
202 } 253 observer_list_, OnUpdatePolicy());
203 254
204 em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse; 255 em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse;
205 policy_copy->CopyFrom(policy); 256 policy_copy->CopyFrom(policy);
206 BrowserThread::PostTask( 257 BrowserThread::PostTask(
207 BrowserThread::FILE, 258 BrowserThread::FILE,
208 FROM_HERE, 259 FROM_HERE,
209 new PersistPolicyTask(backing_file_path_, NULL, policy_copy, false)); 260 new PersistPolicyTask(backing_file_path_, NULL, policy_copy, false));
210 return new_policy_differs; 261 return new_policy_differs;
211 } 262 }
212 263
213 DictionaryValue* CloudPolicyCache::GetDevicePolicy() { 264 ConfigurationPolicyProvider* CloudPolicyCache::GetManagedPolicyProvider() {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 265 DCHECK(CalledOnValidThread());
215 base::AutoLock lock(lock_); 266 return managed_policy_provider_.get();
216 return device_policy_->DeepCopy();
217 } 267 }
218 268
219 const CloudPolicyCache::PolicyMapType* 269 ConfigurationPolicyProvider* CloudPolicyCache::GetRecommendedPolicyProvider() {
220 CloudPolicyCache::GetMandatoryPolicy() const { 270 DCHECK(CalledOnValidThread());
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 271 return recommended_policy_provider_.get();
222 return &mandatory_policy_;
223 }
224
225 const CloudPolicyCache::PolicyMapType*
226 CloudPolicyCache::GetRecommendedPolicy() const {
227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
228 return &recommended_policy_;
229 } 272 }
230 273
231 void CloudPolicyCache::SetUnmanaged() { 274 void CloudPolicyCache::SetUnmanaged() {
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 275 DCHECK(CalledOnValidThread());
233 is_unmanaged_ = true; 276 is_unmanaged_ = true;
234 { 277 mandatory_policy_.clear();
235 base::AutoLock lock(lock_); 278 recommended_policy_.clear();
236 mandatory_policy_.clear(); 279 device_policy_.reset(new DictionaryValue);
237 recommended_policy_.clear(); 280 last_policy_refresh_time_ = base::Time::NowFromSystemTime();
238 device_policy_.reset(new DictionaryValue); 281
239 last_policy_refresh_time_ = base::Time::NowFromSystemTime(); 282 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
240 } 283 observer_list_, OnUpdatePolicy());
284
241 BrowserThread::PostTask( 285 BrowserThread::PostTask(
242 BrowserThread::FILE, 286 BrowserThread::FILE,
243 FROM_HERE, 287 FROM_HERE,
244 new PersistPolicyTask(backing_file_path_, NULL, NULL, true)); 288 new PersistPolicyTask(backing_file_path_, NULL, NULL, true));
245 } 289 }
246 290
247 // static 291 // static
248 bool CloudPolicyCache::DecodePolicyResponse( 292 bool CloudPolicyCache::DecodePolicyResponse(
249 const em::CloudPolicyResponse& policy_response, 293 const em::CloudPolicyResponse& policy_response,
250 PolicyMapType* mandatory, 294 PolicyMapType* mandatory,
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 CloudPolicyCache::DecodeValue(named_value->value()); 455 CloudPolicyCache::DecodeValue(named_value->value());
412 if (decoded_value) 456 if (decoded_value)
413 result->Set(named_value->name(), decoded_value); 457 result->Set(named_value->name(), decoded_value);
414 } 458 }
415 } 459 }
416 } 460 }
417 return result; 461 return result;
418 } 462 }
419 463
420 } // namespace policy 464 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698