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

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

Issue 6409040: New policy protobuf protocol. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comments 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
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/policy/device_management_policy_cache.h"
6
7 #include <limits>
8 #include <string>
9
10 #include "base/file_util.h"
11 #include "base/logging.h"
12 #include "base/task.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_thread.h"
15 #include "chrome/browser/policy/proto/device_management_constants.h"
16 #include "chrome/browser/policy/proto/device_management_local.pb.h"
17
18 using google::protobuf::RepeatedField;
19 using google::protobuf::RepeatedPtrField;
20
21 namespace policy {
22
23 // Saves policy information to a file.
24 class PersistPolicyTask : public Task {
25 public:
26 PersistPolicyTask(const FilePath& path,
27 const em::DevicePolicyResponse* policy,
28 const base::Time& timestamp,
29 const bool is_device_unmanaged)
30 : path_(path),
31 policy_(policy),
32 timestamp_(timestamp),
33 is_device_unmanaged_(is_device_unmanaged) {}
34
35 private:
36 // Task override.
37 virtual void Run();
38
39 const FilePath path_;
40 scoped_ptr<const em::DevicePolicyResponse> policy_;
41 const base::Time timestamp_;
42 const bool is_device_unmanaged_;
43 };
44
45 void PersistPolicyTask::Run() {
46 std::string data;
47 em::CachedDevicePolicyResponse cached_policy;
48 if (policy_.get())
49 cached_policy.mutable_policy()->CopyFrom(*policy_);
50 if (is_device_unmanaged_)
51 cached_policy.set_unmanaged(true);
52 cached_policy.set_timestamp(timestamp_.ToInternalValue());
53 if (!cached_policy.SerializeToString(&data)) {
54 LOG(WARNING) << "Failed to serialize policy data";
55 return;
56 }
57
58 int size = data.size();
59 if (file_util::WriteFile(path_, data.c_str(), size) != size) {
60 LOG(WARNING) << "Failed to write " << path_.value();
61 return;
62 }
63 }
64
65 DeviceManagementPolicyCache::DeviceManagementPolicyCache(
66 const FilePath& backing_file_path)
67 : backing_file_path_(backing_file_path),
68 policy_(new DictionaryValue),
69 fresh_policy_(false),
70 is_device_unmanaged_(false) {
71 }
72
73 DeviceManagementPolicyCache::~DeviceManagementPolicyCache() {}
74
75 void DeviceManagementPolicyCache::LoadPolicyFromFile() {
76 if (!file_util::PathExists(backing_file_path_) || fresh_policy_)
77 return;
78
79 // Read the protobuf from the file.
80 std::string data;
81 if (!file_util::ReadFileToString(backing_file_path_, &data)) {
82 LOG(WARNING) << "Failed to read policy data from "
83 << backing_file_path_.value();
84 return;
85 }
86
87 em::CachedDevicePolicyResponse cached_policy;
88 if (!cached_policy.ParseFromArray(data.c_str(), data.size())) {
89 LOG(WARNING) << "Failed to parse policy data read from "
90 << backing_file_path_.value();
91 return;
92 }
93
94 // Reject files that claim to be from the future.
95 base::Time timestamp = base::Time::FromInternalValue(
96 cached_policy.timestamp());
97 if (timestamp > base::Time::NowFromSystemTime()) {
98 LOG(WARNING) << "Rejected policy data from " << backing_file_path_.value()
99 << ", file is from the future.";
100 return;
101 }
102 is_device_unmanaged_ = cached_policy.unmanaged();
103
104 // Decode and swap in the new policy information.
105 scoped_ptr<DictionaryValue> value(DecodePolicy(cached_policy.policy()));
106 {
107 base::AutoLock lock(lock_);
108 if (!fresh_policy_)
109 policy_.reset(value.release());
110 last_policy_refresh_time_ = timestamp;
111 }
112 }
113
114 bool DeviceManagementPolicyCache::SetPolicy(
115 const em::DevicePolicyResponse& policy) {
116 is_device_unmanaged_ = false;
117 DictionaryValue* value = DeviceManagementPolicyCache::DecodePolicy(policy);
118 const bool new_policy_differs = !(value->Equals(policy_.get()));
119 base::Time now(base::Time::NowFromSystemTime());
120 {
121 base::AutoLock lock(lock_);
122 policy_.reset(value);
123 fresh_policy_ = true;
124 last_policy_refresh_time_ = now;
125 }
126
127 em::DevicePolicyResponse* policy_copy = new em::DevicePolicyResponse;
128 policy_copy->CopyFrom(policy);
129 BrowserThread::PostTask(
130 BrowserThread::FILE,
131 FROM_HERE,
132 new PersistPolicyTask(backing_file_path_, policy_copy, now, false));
133 return new_policy_differs;
134 }
135
136 DictionaryValue* DeviceManagementPolicyCache::GetPolicy() {
137 base::AutoLock lock(lock_);
138 return policy_->DeepCopy();
139 }
140
141 void DeviceManagementPolicyCache::SetDeviceUnmanaged() {
142 is_device_unmanaged_ = true;
143 base::Time now(base::Time::NowFromSystemTime());
144 {
145 base::AutoLock lock(lock_);
146 policy_.reset(new DictionaryValue);
147 last_policy_refresh_time_ = now;
148 }
149 BrowserThread::PostTask(
150 BrowserThread::FILE,
151 FROM_HERE,
152 new PersistPolicyTask(backing_file_path_, NULL, now, true));
153 }
154
155 // static
156 Value* DeviceManagementPolicyCache::DecodeIntegerValue(
157 google::protobuf::int64 value) {
158 if (value < std::numeric_limits<int>::min() ||
159 value > std::numeric_limits<int>::max()) {
160 LOG(WARNING) << "Integer value " << value
161 << " out of numeric limits, ignoring.";
162 return NULL;
163 }
164
165 return Value::CreateIntegerValue(static_cast<int>(value));
166 }
167
168 // static
169 Value* DeviceManagementPolicyCache::DecodeValue(const em::GenericValue& value) {
170 if (!value.has_value_type())
171 return NULL;
172
173 switch (value.value_type()) {
174 case em::GenericValue::VALUE_TYPE_BOOL:
175 if (value.has_bool_value())
176 return Value::CreateBooleanValue(value.bool_value());
177 return NULL;
178 case em::GenericValue::VALUE_TYPE_INT64:
179 if (value.has_int64_value())
180 return DecodeIntegerValue(value.int64_value());
181 return NULL;
182 case em::GenericValue::VALUE_TYPE_STRING:
183 if (value.has_string_value())
184 return Value::CreateStringValue(value.string_value());
185 return NULL;
186 case em::GenericValue::VALUE_TYPE_DOUBLE:
187 if (value.has_double_value())
188 return Value::CreateDoubleValue(value.double_value());
189 return NULL;
190 case em::GenericValue::VALUE_TYPE_BYTES:
191 if (value.has_bytes_value()) {
192 std::string bytes = value.bytes_value();
193 return BinaryValue::CreateWithCopiedBuffer(bytes.c_str(), bytes.size());
194 }
195 return NULL;
196 case em::GenericValue::VALUE_TYPE_BOOL_ARRAY: {
197 ListValue* list = new ListValue;
198 RepeatedField<bool>::const_iterator i;
199 for (i = value.bool_array().begin(); i != value.bool_array().end(); ++i)
200 list->Append(Value::CreateBooleanValue(*i));
201 return list;
202 }
203 case em::GenericValue::VALUE_TYPE_INT64_ARRAY: {
204 ListValue* list = new ListValue;
205 RepeatedField<google::protobuf::int64>::const_iterator i;
206 for (i = value.int64_array().begin();
207 i != value.int64_array().end(); ++i) {
208 Value* int_value = DecodeIntegerValue(*i);
209 if (int_value)
210 list->Append(int_value);
211 }
212 return list;
213 }
214 case em::GenericValue::VALUE_TYPE_STRING_ARRAY: {
215 ListValue* list = new ListValue;
216 RepeatedPtrField<std::string>::const_iterator i;
217 for (i = value.string_array().begin();
218 i != value.string_array().end(); ++i)
219 list->Append(Value::CreateStringValue(*i));
220 return list;
221 }
222 case em::GenericValue::VALUE_TYPE_DOUBLE_ARRAY: {
223 ListValue* list = new ListValue;
224 RepeatedField<double>::const_iterator i;
225 for (i = value.double_array().begin();
226 i != value.double_array().end(); ++i)
227 list->Append(Value::CreateDoubleValue(*i));
228 return list;
229 }
230 default:
231 NOTREACHED() << "Unhandled value type";
232 }
233
234 return NULL;
235 }
236
237 // static
238 DictionaryValue* DeviceManagementPolicyCache::DecodePolicy(
239 const em::DevicePolicyResponse& policy) {
240 DictionaryValue* result = new DictionaryValue;
241 RepeatedPtrField<em::DevicePolicySetting>::const_iterator setting;
242 for (setting = policy.setting().begin();
243 setting != policy.setting().end();
244 ++setting) {
245 // Wrong policy key? Skip.
246 if (setting->policy_key().compare(kChromeDevicePolicySettingKey) != 0)
247 continue;
248
249 // No policy value? Skip.
250 if (!setting->has_policy_value())
251 continue;
252
253 // Iterate through all the name-value pairs wrapped in |setting|.
254 const em::GenericSetting& policy_value(setting->policy_value());
255 RepeatedPtrField<em::GenericNamedValue>::const_iterator named_value;
256 for (named_value = policy_value.named_value().begin();
257 named_value != policy_value.named_value().end();
258 ++named_value) {
259 if (named_value->has_value()) {
260 Value* decoded_value =
261 DeviceManagementPolicyCache::DecodeValue(named_value->value());
262 if (decoded_value)
263 result->Set(named_value->name(), decoded_value);
264 }
265 }
266 }
267 return result;
268 }
269
270 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698