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

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

Issue 11946017: Remove old cloud policy code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address nits. Created 7 years, 11 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) 2012 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/cros_user_policy_cache.h"
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/file_util.h"
12 #include "chrome/browser/policy/proto/cloud_policy.pb.h"
13 #include "chrome/browser/policy/proto/device_management_backend.pb.h"
14 #include "chrome/browser/policy/proto/device_management_local.pb.h"
15 #include "chromeos/dbus/session_manager_client.h"
16 #include "content/public/browser/browser_thread.h"
17
18 using content::BrowserThread;
19
20 namespace em = enterprise_management;
21
22 namespace policy {
23
24 // Decodes a CloudPolicySettings object into a policy map. The implementation is
25 // generated code in policy/cloud_policy_generated.cc.
26 void DecodePolicy(const em::CloudPolicySettings& policy, PolicyMap* policies);
27
28 // Takes care of sending a new policy blob to session manager and reports back
29 // the status through a callback.
30 class CrosUserPolicyCache::StorePolicyOperation {
31 public:
32 typedef base::Callback<void(bool)> StatusCallback;
33
34 StorePolicyOperation(
35 const em::PolicyFetchResponse& policy,
36 chromeos::SessionManagerClient* session_manager_client,
37 const StatusCallback& callback);
38
39 // Executes the operation.
40 void Run();
41
42 // Cancels a pending callback.
43 void Cancel();
44
45 const em::PolicyFetchResponse& policy() { return policy_; }
46
47 private:
48 // StorePolicyOperation manages its own lifetime.
49 ~StorePolicyOperation() {}
50
51 // A callback function suitable for passing to session_manager_client.
52 void OnPolicyStored(bool result);
53
54 em::PolicyFetchResponse policy_;
55 chromeos::SessionManagerClient* session_manager_client_;
56 StatusCallback callback_;
57
58 DISALLOW_COPY_AND_ASSIGN(StorePolicyOperation);
59 };
60
61 CrosUserPolicyCache::StorePolicyOperation::StorePolicyOperation(
62 const em::PolicyFetchResponse& policy,
63 chromeos::SessionManagerClient* session_manager_client,
64 const StatusCallback& callback)
65 : policy_(policy),
66 session_manager_client_(session_manager_client),
67 callback_(callback) {}
68
69 void CrosUserPolicyCache::StorePolicyOperation::Run() {
70 std::string serialized;
71 if (!policy_.SerializeToString(&serialized)) {
72 LOG(ERROR) << "Failed to serialize policy protobuf!";
73 if (!callback_.is_null())
74 callback_.Run(false);
75 delete this;
76 return;
77 }
78 session_manager_client_->StoreUserPolicy(
79 serialized,
80 base::Bind(&CrosUserPolicyCache::StorePolicyOperation::OnPolicyStored,
81 base::Unretained(this)));
82 }
83
84 void CrosUserPolicyCache::StorePolicyOperation::Cancel() {
85 callback_.Reset();
86 }
87
88 void CrosUserPolicyCache::StorePolicyOperation::OnPolicyStored(bool result) {
89 if (!callback_.is_null())
90 callback_.Run(result);
91 delete this;
92 }
93
94 class CrosUserPolicyCache::RetrievePolicyOperation {
95 public:
96 typedef base::Callback<void(bool, const em::PolicyFetchResponse&)>
97 ResultCallback;
98
99 RetrievePolicyOperation(
100 chromeos::SessionManagerClient* session_manager_client,
101 const ResultCallback& callback);
102
103 // Executes the operation.
104 void Run();
105
106 // Cancels a pending callback.
107 void Cancel();
108
109 private:
110 // RetrievePolicyOperation manages its own lifetime.
111 ~RetrievePolicyOperation() {}
112
113 // Decodes the policy data and triggers a signature check.
114 void OnPolicyRetrieved(const std::string& policy_blob);
115
116 chromeos::SessionManagerClient* session_manager_client_;
117 ResultCallback callback_;
118
119 DISALLOW_COPY_AND_ASSIGN(RetrievePolicyOperation);
120 };
121
122 CrosUserPolicyCache::RetrievePolicyOperation::RetrievePolicyOperation(
123 chromeos::SessionManagerClient* session_manager_client,
124 const ResultCallback& callback)
125 : session_manager_client_(session_manager_client),
126 callback_(callback) {}
127
128 void CrosUserPolicyCache::RetrievePolicyOperation::Run() {
129 session_manager_client_->RetrieveUserPolicy(
130 base::Bind(
131 &CrosUserPolicyCache::RetrievePolicyOperation::OnPolicyRetrieved,
132 base::Unretained(this)));
133 }
134
135 void CrosUserPolicyCache::RetrievePolicyOperation::Cancel() {
136 callback_.Reset();
137 }
138
139 void CrosUserPolicyCache::RetrievePolicyOperation::OnPolicyRetrieved(
140 const std::string& policy_blob) {
141 bool status = true;
142 em::PolicyFetchResponse policy;
143 if (!policy.ParseFromString(policy_blob) ||
144 !policy.has_policy_data() ||
145 !policy.has_policy_data_signature()) {
146 LOG(ERROR) << "Failed to decode policy";
147 status = false;
148 }
149
150 if (!callback_.is_null())
151 callback_.Run(status, policy);
152 delete this;
153 }
154
155 CrosUserPolicyCache::CrosUserPolicyCache(
156 chromeos::SessionManagerClient* session_manager_client,
157 CloudPolicyDataStore* data_store,
158 bool wait_for_policy_fetch,
159 const FilePath& legacy_token_cache_file,
160 const FilePath& legacy_policy_cache_file)
161 : session_manager_client_(session_manager_client),
162 data_store_(data_store),
163 pending_policy_fetch_(wait_for_policy_fetch),
164 pending_disk_cache_load_(true),
165 store_operation_(NULL),
166 retrieve_operation_(NULL),
167 legacy_cache_dir_(legacy_token_cache_file.DirName()),
168 ALLOW_THIS_IN_INITIALIZER_LIST(
169 legacy_token_cache_delegate_factory_(this)),
170 ALLOW_THIS_IN_INITIALIZER_LIST(
171 legacy_policy_cache_delegate_factory_(this)) {
172 DCHECK_EQ(legacy_token_cache_file.DirName().value(),
173 legacy_policy_cache_file.DirName().value());
174
175 legacy_token_loader_ =
176 new UserPolicyTokenLoader(
177 legacy_token_cache_delegate_factory_.GetWeakPtr(),
178 legacy_token_cache_file);
179 legacy_policy_cache_ =
180 new UserPolicyDiskCache(
181 legacy_policy_cache_delegate_factory_.GetWeakPtr(),
182 legacy_policy_cache_file);
183 }
184
185 CrosUserPolicyCache::~CrosUserPolicyCache() {
186 CancelStore();
187 CancelRetrieve();
188 }
189
190 void CrosUserPolicyCache::Load() {
191 retrieve_operation_ =
192 new RetrievePolicyOperation(
193 session_manager_client_,
194 base::Bind(&CrosUserPolicyCache::OnPolicyLoadDone,
195 base::Unretained(this)));
196 retrieve_operation_->Run();
197 }
198
199 bool CrosUserPolicyCache::SetPolicy(const em::PolicyFetchResponse& policy) {
200 CancelStore();
201 set_last_policy_refresh_time(base::Time::NowFromSystemTime());
202 pending_policy_fetch_ = true;
203 store_operation_ =
204 new StorePolicyOperation(policy,
205 session_manager_client_,
206 base::Bind(&CrosUserPolicyCache::OnPolicyStored,
207 base::Unretained(this)));
208 store_operation_->Run();
209 return true;
210 }
211
212 void CrosUserPolicyCache::SetUnmanaged() {
213 base::Time now(base::Time::NowFromSystemTime());
214 SetUnmanagedInternal(now);
215
216 // Construct a policy blob with unmanaged state.
217 em::PolicyData policy_data;
218 policy_data.set_policy_type(data_store_->policy_type());
219 policy_data.set_timestamp((now - base::Time::UnixEpoch()).InMilliseconds());
220 policy_data.set_state(em::PolicyData::UNMANAGED);
221
222 em::PolicyFetchResponse policy;
223 if (!policy_data.SerializeToString(policy.mutable_policy_data())) {
224 LOG(ERROR) << "Failed to serialize policy_data";
225 return;
226 }
227
228 SetPolicy(policy);
229 }
230
231 void CrosUserPolicyCache::SetFetchingDone() {
232 // If there is a pending policy store or reload, wait for that to complete
233 // before reporting fetching done.
234 if (store_operation_ || retrieve_operation_)
235 return;
236
237 pending_policy_fetch_ = false;
238 CheckIfDone();
239 }
240
241 bool CrosUserPolicyCache::DecodePolicyData(const em::PolicyData& policy_data,
242 PolicyMap* policies) {
243 em::CloudPolicySettings policy;
244 if (!policy.ParseFromString(policy_data.policy_value())) {
245 LOG(WARNING) << "Failed to parse CloudPolicySettings protobuf.";
246 return false;
247 }
248 DecodePolicy(policy, policies);
249 return true;
250 }
251
252 void CrosUserPolicyCache::OnTokenLoaded(const std::string& token,
253 const std::string& device_id) {
254 if (token.empty())
255 LOG(WARNING) << "Failed to load legacy token cache";
256
257 data_store_->set_device_id(device_id);
258 data_store_->SetDeviceToken(token, true);
259 }
260
261 void CrosUserPolicyCache::OnDiskCacheLoaded(
262 UserPolicyDiskCache::LoadResult result,
263 const em::CachedCloudPolicyResponse& policy) {
264 if (result == UserPolicyDiskCache::LOAD_RESULT_SUCCESS) {
265 if (policy.unmanaged())
266 SetUnmanagedInternal(base::Time::FromTimeT(policy.timestamp()));
267 else if (policy.has_cloud_policy())
268 InstallLegacyPolicy(policy.cloud_policy());
269 } else {
270 LOG(WARNING) << "Failed to load legacy policy cache: " << result;
271 }
272
273 pending_disk_cache_load_ = false;
274 CheckIfDone();
275 }
276
277 void CrosUserPolicyCache::OnPolicyStored(bool result) {
278 DCHECK(store_operation_);
279 CancelStore();
280 if (result) {
281 // Policy is stored successfully, reload from session_manager and apply.
282 // This helps us making sure we only use policy that session_manager has
283 // checked and confirmed to be good.
284 CancelRetrieve();
285 retrieve_operation_ =
286 new RetrievePolicyOperation(
287 session_manager_client_,
288 base::Bind(&CrosUserPolicyCache::OnPolicyReloadDone,
289 base::Unretained(this)));
290 retrieve_operation_->Run();
291
292 // Now that the new policy blob is installed, remove the old cache dir.
293 if (!legacy_cache_dir_.empty()) {
294 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
295 base::Bind(&RemoveLegacyCacheDir,
296 legacy_cache_dir_));
297 }
298 } else {
299 LOG(ERROR) << "Failed to store user policy.";
300 InformNotifier(CloudPolicySubsystem::LOCAL_ERROR,
301 CloudPolicySubsystem::POLICY_LOCAL_ERROR);
302 pending_policy_fetch_ = false;
303 CheckIfDone();
304 }
305 }
306
307 void CrosUserPolicyCache::OnPolicyLoadDone(
308 bool result,
309 const em::PolicyFetchResponse& policy) {
310 DCHECK(retrieve_operation_);
311 CancelRetrieve();
312 if (!result) {
313 LOG(WARNING) << "No user policy present, trying legacy caches.";
314 legacy_token_loader_->Load();
315 legacy_policy_cache_->Load();
316 return;
317 }
318
319 // We have new-style policy, no need to clean up.
320 legacy_cache_dir_.clear();
321
322 em::PolicyData policy_data;
323 if (!policy_data.ParseFromString(policy.policy_data())) {
324 LOG(WARNING) << "Failed to parse PolicyData protobuf.";
325 InformNotifier(CloudPolicySubsystem::LOCAL_ERROR,
326 CloudPolicySubsystem::POLICY_LOCAL_ERROR);
327 data_store_->SetDeviceToken(std::string(), true);
328 } else if (policy_data.request_token().empty() ||
329 policy_data.username().empty() ||
330 policy_data.device_id().empty()) {
331 LOG(WARNING) << "Policy protobuf is missing credentials";
332 InformNotifier(CloudPolicySubsystem::LOCAL_ERROR,
333 CloudPolicySubsystem::POLICY_LOCAL_ERROR);
334 data_store_->SetDeviceToken(std::string(), true);
335 } else {
336 data_store_->set_device_id(policy_data.device_id());
337 data_store_->SetDeviceToken(policy_data.request_token(), true);
338 if (SetPolicyInternal(policy, NULL, true))
339 set_last_policy_refresh_time(base::Time::NowFromSystemTime());
340 }
341
342 pending_disk_cache_load_ = false;
343 CheckIfDone();
344 }
345
346 void CrosUserPolicyCache::OnPolicyReloadDone(
347 bool result,
348 const em::PolicyFetchResponse& policy) {
349 DCHECK(retrieve_operation_);
350 CancelRetrieve();
351 if (result) {
352 if (SetPolicyInternal(policy, NULL, false))
353 set_last_policy_refresh_time(base::Time::NowFromSystemTime());
354 } else {
355 InformNotifier(CloudPolicySubsystem::LOCAL_ERROR,
356 CloudPolicySubsystem::POLICY_LOCAL_ERROR);
357 }
358 pending_policy_fetch_ = false;
359 CheckIfDone();
360 }
361
362 void CrosUserPolicyCache::CancelStore() {
363 if (store_operation_) {
364 store_operation_->Cancel();
365 store_operation_ = NULL;
366 }
367 }
368
369 void CrosUserPolicyCache::CancelRetrieve() {
370 if (retrieve_operation_) {
371 retrieve_operation_->Cancel();
372 retrieve_operation_ = NULL;
373 }
374 }
375
376 void CrosUserPolicyCache::CheckIfDone() {
377 if (!pending_policy_fetch_ && !pending_disk_cache_load_) {
378 if (!IsReady())
379 SetReady();
380 CloudPolicyCacheBase::SetFetchingDone();
381 }
382 }
383
384 void CrosUserPolicyCache::InstallLegacyPolicy(
385 const em::PolicyFetchResponse& policy) {
386 em::PolicyFetchResponse mutable_policy(policy);
387 mutable_policy.clear_policy_data_signature();
388 mutable_policy.clear_new_public_key();
389 mutable_policy.clear_new_public_key_signature();
390 em::PolicyData policy_data;
391 if (!policy_data.ParseFromString(mutable_policy.policy_data())) {
392 LOG(ERROR) << "Failed to parse policy data.";
393 return;
394 }
395
396 policy_data.clear_public_key_version();
397 if (!policy_data.SerializeToString(mutable_policy.mutable_policy_data())) {
398 LOG(ERROR) << "Failed to serialize policy data.";
399 return;
400 }
401
402 base::Time timestamp;
403 if (SetPolicyInternal(mutable_policy, &timestamp, true))
404 set_last_policy_refresh_time(timestamp);
405 }
406
407 // static
408 void CrosUserPolicyCache::RemoveLegacyCacheDir(const FilePath& dir) {
409 if (!file_util::Delete(dir, true))
410 PLOG(ERROR) << "Failed to remove " << dir.value();
411 }
412
413 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/cros_user_policy_cache.h ('k') | chrome/browser/policy/cros_user_policy_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698