- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / policy / cloud / component_cloud_policy_updater.cc
1 // Copyright (c) 2013 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/cloud/component_cloud_policy_updater.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/logging.h"
12 #include "base/sequenced_task_runner.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "chrome/browser/policy/cloud/component_cloud_policy_store.h"
15 #include "chrome/browser/policy/cloud/external_policy_data_fetcher.h"
16 #include "chrome/browser/policy/proto/cloud/chrome_extension_policy.pb.h"
17 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h"
18 #include "components/policy/core/common/policy_namespace.h"
19
20 namespace em = enterprise_management;
21
22 namespace policy {
23
24 namespace {
25
26 // The maximum size of the serialized policy protobuf.
27 const size_t kPolicyProtoMaxSize = 16 * 1024;
28
29 // The maximum size of the downloaded policy data.
30 const int64 kPolicyDataMaxSize = 5 * 1024 * 1024;
31
32 // Tha maximum number of policy data fetches to run in parallel.
33 const int64 kMaxParallelPolicyDataFetches = 2;
34
35 }  // namespace
36
37 ComponentCloudPolicyUpdater::ComponentCloudPolicyUpdater(
38     scoped_refptr<base::SequencedTaskRunner> task_runner,
39     scoped_ptr<ExternalPolicyDataFetcher> external_policy_data_fetcher,
40     ComponentCloudPolicyStore* store)
41     : store_(store),
42       external_policy_data_updater_(task_runner,
43                                     external_policy_data_fetcher.Pass(),
44                                     kMaxParallelPolicyDataFetches) {
45 }
46
47 ComponentCloudPolicyUpdater::~ComponentCloudPolicyUpdater() {
48 }
49
50 void ComponentCloudPolicyUpdater::UpdateExternalPolicy(
51     scoped_ptr<em::PolicyFetchResponse> response) {
52   // Keep a serialized copy of |response|, to cache it later.
53   // The policy is also rejected if it exceeds the maximum size.
54   std::string serialized_response;
55   if (!response->SerializeToString(&serialized_response) ||
56       serialized_response.size() > kPolicyProtoMaxSize) {
57     return;
58   }
59
60   // Validate the policy before doing anything else.
61   PolicyNamespace ns;
62   em::ExternalPolicyData data;
63   if (!store_->ValidatePolicy(response.Pass(), &ns, &data)) {
64     LOG(ERROR) << "Failed to validate component policy fetched from DMServer";
65     return;
66   }
67
68   // Maybe the data for this hash has already been downloaded and cached.
69   const std::string& cached_hash = store_->GetCachedHash(ns);
70   if (!cached_hash.empty() && data.secure_hash() == cached_hash) {
71     return;
72   }
73
74   // TODO(joaodasilva): implement the other two auth methods.
75   if (data.download_auth_method() != em::ExternalPolicyData::NONE)
76     return;
77
78   // Encode |ns| into a string |key|.
79   const std::string domain = base::IntToString(ns.domain);
80   const std::string key =
81       base::IntToString(domain.size()) + ":" + domain + ":" + ns.component_id;
82
83   if (data.download_url().empty() || !data.has_secure_hash()) {
84     // If there is no policy for this component or the policy has been removed,
85     // cancel any existing request to fetch policy for this component.
86     external_policy_data_updater_.CancelExternalDataFetch(key);
87
88     // Delete any existing policy for this component.
89     store_->Delete(ns);
90   } else {
91     // Make a request to fetch policy for this component. If another fetch
92     // request is already pending for the component, it will be canceled.
93     external_policy_data_updater_.FetchExternalData(
94         key,
95         ExternalPolicyDataUpdater::Request(data.download_url(),
96                                            data.secure_hash(),
97                                            kPolicyDataMaxSize),
98         base::Bind(&ComponentCloudPolicyStore::Store, base::Unretained(store_),
99                    ns,
100                    serialized_response,
101                    data.secure_hash()));
102   }
103 }
104
105 }  // namespace policy