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

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

Issue 6312121: Add initial device policy infrastructure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix race condition and tests. 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) 2010 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/device_management_policy_cache.h" 5 #include "chrome/browser/policy/cloud_policy_cache.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <string> 8 #include <string>
9 9
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/task.h" 12 #include "base/task.h"
13 #include "base/values.h" 13 #include "base/values.h"
14 #include "chrome/browser/browser_thread.h" 14 #include "chrome/browser/browser_thread.h"
15 #include "chrome/browser/policy/configuration_policy_pref_store.h"
16 #include "chrome/browser/policy/configuration_policy_provider.h"
15 #include "chrome/browser/policy/proto/device_management_constants.h" 17 #include "chrome/browser/policy/proto/device_management_constants.h"
16 #include "chrome/browser/policy/proto/device_management_local.pb.h" 18 #include "chrome/browser/policy/proto/device_management_local.pb.h"
17 19
18 using google::protobuf::RepeatedField; 20 using google::protobuf::RepeatedField;
19 using google::protobuf::RepeatedPtrField; 21 using google::protobuf::RepeatedPtrField;
20 22
21 namespace policy { 23 namespace policy {
22 24
25 // A thin ConfigurationPolicyProvider implementation sitting on top of
26 // CloudPolicyCache for hooking up with ConfigurationPolicyPrefStore.
27 class CloudPolicyCache::CloudPolicyProvider
28 : public ConfigurationPolicyProvider {
29 public:
30 CloudPolicyProvider(const PolicyDefinitionList* policy_list,
31 CloudPolicyCache* cache,
32 CloudPolicyCache::PolicyLevel level)
33 : ConfigurationPolicyProvider(policy_list),
34 cache_(cache),
35 level_(level) {}
36 virtual ~CloudPolicyProvider() {}
37
38 virtual bool Provide(ConfigurationPolicyStoreInterface* store) {
39 // TODO(mnissler) handle level once we have support for that in the cache.
40 DecodePolicyValueTree(cache_->policy_.get(), store);
41 return true;
42 }
43
44 virtual bool IsInitializationComplete() const {
45 return cache_->initialization_complete_;
46 }
47
48 virtual void AddObserver(ConfigurationPolicyProvider::Observer* observer) {
49 cache_->observer_list_.AddObserver(observer);
50 }
51 virtual void RemoveObserver(ConfigurationPolicyProvider::Observer* observer) {
52 cache_->observer_list_.RemoveObserver(observer);
53 }
54
55 private:
56 // The underlying policy cache.
57 CloudPolicyCache* cache_;
58 // Policy level this provider will handle.
59 CloudPolicyCache::PolicyLevel level_;
60
61 DISALLOW_COPY_AND_ASSIGN(CloudPolicyProvider);
62 };
63
23 // Saves policy information to a file. 64 // Saves policy information to a file.
24 class PersistPolicyTask : public Task { 65 class PersistPolicyTask : public Task {
25 public: 66 public:
26 PersistPolicyTask(const FilePath& path, 67 PersistPolicyTask(const FilePath& path,
27 const em::DevicePolicyResponse* policy, 68 const em::DevicePolicyResponse* policy,
28 const base::Time& timestamp, 69 const base::Time& timestamp,
29 const bool is_device_unmanaged) 70 const bool is_device_unmanaged)
30 : path_(path), 71 : path_(path),
31 policy_(policy), 72 policy_(policy),
32 timestamp_(timestamp), 73 timestamp_(timestamp),
(...skipping 22 matching lines...) Expand all
55 return; 96 return;
56 } 97 }
57 98
58 int size = data.size(); 99 int size = data.size();
59 if (file_util::WriteFile(path_, data.c_str(), size) != size) { 100 if (file_util::WriteFile(path_, data.c_str(), size) != size) {
60 LOG(WARNING) << "Failed to write " << path_.value(); 101 LOG(WARNING) << "Failed to write " << path_.value();
61 return; 102 return;
62 } 103 }
63 } 104 }
64 105
65 DeviceManagementPolicyCache::DeviceManagementPolicyCache( 106 CloudPolicyCache::CloudPolicyCache(
66 const FilePath& backing_file_path) 107 const FilePath& backing_file_path)
67 : backing_file_path_(backing_file_path), 108 : backing_file_path_(backing_file_path),
68 policy_(new DictionaryValue), 109 policy_(new DictionaryValue),
69 fresh_policy_(false), 110 initialization_complete_(false),
70 is_device_unmanaged_(false) { 111 is_device_unmanaged_(false) {
112 managed_policy_provider_.reset(
113 new CloudPolicyProvider(
114 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
115 this,
116 POLICY_LEVEL_MANDATORY));
117 recommended_policy_provider_.reset(
118 new CloudPolicyProvider(
119 ConfigurationPolicyPrefStore::GetChromePolicyDefinitionList(),
120 this,
121 POLICY_LEVEL_RECOMMENDED));
71 } 122 }
72 123
73 DeviceManagementPolicyCache::~DeviceManagementPolicyCache() {} 124 CloudPolicyCache::~CloudPolicyCache() {
125 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
126 observer_list_, OnProviderGoingAway());
127 }
74 128
75 void DeviceManagementPolicyCache::LoadPolicyFromFile() { 129 void CloudPolicyCache::LoadFromFile() {
76 if (!file_util::PathExists(backing_file_path_) || fresh_policy_) 130 if (!file_util::PathExists(backing_file_path_) || initialization_complete_)
77 return; 131 return;
78 132
79 // Read the protobuf from the file. 133 // Read the protobuf from the file.
80 std::string data; 134 std::string data;
81 if (!file_util::ReadFileToString(backing_file_path_, &data)) { 135 if (!file_util::ReadFileToString(backing_file_path_, &data)) {
82 LOG(WARNING) << "Failed to read policy data from " 136 LOG(WARNING) << "Failed to read policy data from "
83 << backing_file_path_.value(); 137 << backing_file_path_.value();
84 return; 138 return;
85 } 139 }
86 140
87 em::CachedDevicePolicyResponse cached_policy; 141 em::CachedDevicePolicyResponse cached_policy;
88 if (!cached_policy.ParseFromArray(data.c_str(), data.size())) { 142 if (!cached_policy.ParseFromArray(data.c_str(), data.size())) {
89 LOG(WARNING) << "Failed to parse policy data read from " 143 LOG(WARNING) << "Failed to parse policy data read from "
90 << backing_file_path_.value(); 144 << backing_file_path_.value();
91 return; 145 return;
92 } 146 }
93 147
94 // Reject files that claim to be from the future. 148 // Reject files that claim to be from the future.
95 base::Time timestamp = base::Time::FromInternalValue( 149 base::Time timestamp = base::Time::FromInternalValue(
96 cached_policy.timestamp()); 150 cached_policy.timestamp());
97 if (timestamp > base::Time::NowFromSystemTime()) { 151 if (timestamp > base::Time::NowFromSystemTime()) {
98 LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value() 152 LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value()
99 << ", file is from the future."; 153 << ", file is from the future.";
100 return; 154 return;
101 } 155 }
102 is_device_unmanaged_ = cached_policy.unmanaged();
103 156
104 // Decode and swap in the new policy information. 157 // Decode and swap in the new policy information.
105 scoped_ptr<DictionaryValue> value(DecodePolicy(cached_policy.policy())); 158 scoped_ptr<DictionaryValue> value(DecodePolicy(cached_policy.policy()));
106 { 159 initialization_complete_ = true;
107 base::AutoLock lock(lock_); 160 is_device_unmanaged_ = cached_policy.unmanaged();
108 if (!fresh_policy_) 161 policy_.reset(value.release());
109 policy_.reset(value.release()); 162 last_policy_refresh_time_ = timestamp;
110 last_policy_refresh_time_ = timestamp; 163
111 } 164 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
165 observer_list_, OnUpdatePolicy());
112 } 166 }
113 167
114 bool DeviceManagementPolicyCache::SetPolicy( 168 bool CloudPolicyCache::SetPolicy(
115 const em::DevicePolicyResponse& policy) { 169 const em::DevicePolicyResponse& policy) {
116 is_device_unmanaged_ = false; 170 is_device_unmanaged_ = false;
117 DictionaryValue* value = DeviceManagementPolicyCache::DecodePolicy(policy); 171 DictionaryValue* value = CloudPolicyCache::DecodePolicy(policy);
118 const bool new_policy_differs = !(value->Equals(policy_.get())); 172 const bool new_policy_differs = !(value->Equals(policy_.get()));
119 base::Time now(base::Time::NowFromSystemTime()); 173 base::Time now(base::Time::NowFromSystemTime());
120 { 174 policy_.reset(value);
121 base::AutoLock lock(lock_); 175 initialization_complete_ = true;
122 policy_.reset(value); 176 last_policy_refresh_time_ = now;
123 fresh_policy_ = true; 177
124 last_policy_refresh_time_ = now; 178 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
125 } 179 observer_list_, OnUpdatePolicy());
126 180
127 em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse; 181 em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse;
128 policy_copy->CopyFrom(policy); 182 policy_copy->CopyFrom(policy);
129 BrowserThread::PostTask( 183 BrowserThread::PostTask(
130 BrowserThread::FILE, 184 BrowserThread::FILE,
131 FROM_HERE, 185 FROM_HERE,
132 new PersistPolicyTask(backing_file_path_, policy_copy, now, false)); 186 new PersistPolicyTask(backing_file_path_, policy_copy, now, false));
133 return new_policy_differs; 187 return new_policy_differs;
134 } 188 }
135 189
136 DictionaryValue* DeviceManagementPolicyCache::GetPolicy() { 190 ConfigurationPolicyProvider* CloudPolicyCache::GetManagedPolicyProvider() {
137 base::AutoLock lock(lock_); 191 return managed_policy_provider_.get();
138 return policy_->DeepCopy();
139 } 192 }
140 193
141 void DeviceManagementPolicyCache::SetDeviceUnmanaged() { 194 ConfigurationPolicyProvider* CloudPolicyCache::GetRecommendedPolicyProvider() {
195 return recommended_policy_provider_.get();
196 }
197
198 void CloudPolicyCache::SetDeviceUnmanaged() {
142 is_device_unmanaged_ = true; 199 is_device_unmanaged_ = true;
143 base::Time now(base::Time::NowFromSystemTime()); 200 base::Time now(base::Time::NowFromSystemTime());
144 { 201 policy_.reset(new DictionaryValue);
145 base::AutoLock lock(lock_); 202 last_policy_refresh_time_ = now;
146 policy_.reset(new DictionaryValue); 203
147 last_policy_refresh_time_ = now; 204 FOR_EACH_OBSERVER(ConfigurationPolicyProvider::Observer,
148 } 205 observer_list_, OnUpdatePolicy());
206
149 BrowserThread::PostTask( 207 BrowserThread::PostTask(
150 BrowserThread::FILE, 208 BrowserThread::FILE,
151 FROM_HERE, 209 FROM_HERE,
152 new PersistPolicyTask(backing_file_path_, NULL, now, true)); 210 new PersistPolicyTask(backing_file_path_, NULL, now, true));
153 } 211 }
154 212
155 // static 213 // static
156 Value* DeviceManagementPolicyCache::DecodeIntegerValue( 214 Value* CloudPolicyCache::DecodeIntegerValue(
157 google::protobuf::int64 value) { 215 google::protobuf::int64 value) {
158 if (value < std::numeric_limits<int>::min() || 216 if (value < std::numeric_limits<int>::min() ||
159 value > std::numeric_limits<int>::max()) { 217 value > std::numeric_limits<int>::max()) {
160 LOG(WARNING) << "Integer value " << value 218 LOG(WARNING) << "Integer value " << value
161 << " out of numeric limits, ignoring."; 219 << " out of numeric limits, ignoring.";
162 return NULL; 220 return NULL;
163 } 221 }
164 222
165 return Value::CreateIntegerValue(static_cast<int>(value)); 223 return Value::CreateIntegerValue(static_cast<int>(value));
166 } 224 }
167 225
168 // static 226 // static
169 Value* DeviceManagementPolicyCache::DecodeValue(const em::GenericValue& value) { 227 Value* CloudPolicyCache::DecodeValue(const em::GenericValue& value) {
170 if (!value.has_value_type()) 228 if (!value.has_value_type())
171 return NULL; 229 return NULL;
172 230
173 switch (value.value_type()) { 231 switch (value.value_type()) {
174 case em::GenericValue::VALUE_TYPE_BOOL: 232 case em::GenericValue::VALUE_TYPE_BOOL:
175 if (value.has_bool_value()) 233 if (value.has_bool_value())
176 return Value::CreateBooleanValue(value.bool_value()); 234 return Value::CreateBooleanValue(value.bool_value());
177 return NULL; 235 return NULL;
178 case em::GenericValue::VALUE_TYPE_INT64: 236 case em::GenericValue::VALUE_TYPE_INT64:
179 if (value.has_int64_value()) 237 if (value.has_int64_value())
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 return list; 286 return list;
229 } 287 }
230 default: 288 default:
231 NOTREACHED() << "Unhandled value type"; 289 NOTREACHED() << "Unhandled value type";
232 } 290 }
233 291
234 return NULL; 292 return NULL;
235 } 293 }
236 294
237 // static 295 // static
238 DictionaryValue* DeviceManagementPolicyCache::DecodePolicy( 296 DictionaryValue* CloudPolicyCache::DecodePolicy(
239 const em::DevicePolicyResponse& policy) { 297 const em::DevicePolicyResponse& policy) {
240 DictionaryValue* result = new DictionaryValue; 298 DictionaryValue* result = new DictionaryValue;
241 RepeatedPtrField<em::DevicePolicySetting>::const_iterator setting; 299 RepeatedPtrField<em::DevicePolicySetting>::const_iterator setting;
242 for (setting = policy.setting().begin(); 300 for (setting = policy.setting().begin();
243 setting != policy.setting().end(); 301 setting != policy.setting().end();
244 ++setting) { 302 ++setting) {
245 // Wrong policy key? Skip. 303 // Wrong policy key? Skip.
246 if (setting->policy_key().compare(kChromeDevicePolicySettingKey) != 0) 304 if (setting->policy_key().compare(kChromeDevicePolicySettingKey) != 0)
247 continue; 305 continue;
248 306
249 // No policy value? Skip. 307 // No policy value? Skip.
250 if (!setting->has_policy_value()) 308 if (!setting->has_policy_value())
251 continue; 309 continue;
252 310
253 // Iterate through all the name-value pairs wrapped in |setting|. 311 // Iterate through all the name-value pairs wrapped in |setting|.
254 const em::GenericSetting& policy_value(setting->policy_value()); 312 const em::GenericSetting& policy_value(setting->policy_value());
255 RepeatedPtrField<em::GenericNamedValue>::const_iterator named_value; 313 RepeatedPtrField<em::GenericNamedValue>::const_iterator named_value;
256 for (named_value = policy_value.named_value().begin(); 314 for (named_value = policy_value.named_value().begin();
257 named_value != policy_value.named_value().end(); 315 named_value != policy_value.named_value().end();
258 ++named_value) { 316 ++named_value) {
259 if (named_value->has_value()) { 317 if (named_value->has_value()) {
260 Value* decoded_value = 318 Value* decoded_value =
261 DeviceManagementPolicyCache::DecodeValue(named_value->value()); 319 CloudPolicyCache::DecodeValue(named_value->value());
262 if (decoded_value) 320 if (decoded_value)
263 result->Set(named_value->name(), decoded_value); 321 result->Set(named_value->name(), decoded_value);
264 } 322 }
265 } 323 }
266 } 324 }
267 return result; 325 return result;
268 } 326 }
269 327
270 } // namespace policy 328 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/cloud_policy_cache.h ('k') | chrome/browser/policy/cloud_policy_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698