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

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

Issue 12189011: Split up chrome/browser/policy subdirectory (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase, add chrome/browser/chromeos/policy/OWNERS Created 7 years, 9 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/cloud_policy_client.h"
6
7 #include "base/bind.h"
8 #include "base/guid.h"
9 #include "base/logging.h"
10 #include "base/stl_util.h"
11 #include "chrome/browser/policy/device_management_service.h"
12
13 namespace em = enterprise_management;
14
15 namespace policy {
16
17 namespace {
18
19 // Translates the DeviceRegisterResponse::DeviceMode |mode| to the enum used
20 // internally to represent different device modes.
21 DeviceMode TranslateProtobufDeviceMode(
22 em::DeviceRegisterResponse::DeviceMode mode) {
23 switch (mode) {
24 case em::DeviceRegisterResponse::ENTERPRISE:
25 return DEVICE_MODE_ENTERPRISE;
26 case em::DeviceRegisterResponse::RETAIL:
27 return DEVICE_MODE_KIOSK;
28 }
29 LOG(ERROR) << "Unknown enrollment mode in registration response: " << mode;
30 return DEVICE_MODE_NOT_SET;
31 }
32
33 bool IsChromePolicy(const std::string& type) {
34 return type == dm_protocol::kChromeDevicePolicyType ||
35 type == dm_protocol::kChromeUserPolicyType;
36 }
37
38 } // namespace
39
40 CloudPolicyClient::Observer::~Observer() {}
41
42 CloudPolicyClient::StatusProvider::~StatusProvider() {}
43
44 CloudPolicyClient::CloudPolicyClient(const std::string& machine_id,
45 const std::string& machine_model,
46 UserAffiliation user_affiliation,
47 StatusProvider* status_provider,
48 DeviceManagementService* service)
49 : machine_id_(machine_id),
50 machine_model_(machine_model),
51 user_affiliation_(user_affiliation),
52 device_mode_(DEVICE_MODE_NOT_SET),
53 submit_machine_id_(false),
54 public_key_version_(-1),
55 public_key_version_valid_(false),
56 service_(service), // Can be NULL for unit tests.
57 status_provider_(status_provider), // Can be NULL for unit tests.
58 status_(DM_STATUS_SUCCESS) {
59 }
60
61 CloudPolicyClient::~CloudPolicyClient() {
62 STLDeleteValues(&responses_);
63 }
64
65 void CloudPolicyClient::SetupRegistration(const std::string& dm_token,
66 const std::string& client_id) {
67 DCHECK(!dm_token.empty());
68 DCHECK(!client_id.empty());
69 DCHECK(!is_registered());
70
71 dm_token_ = dm_token;
72 client_id_ = client_id;
73 request_job_.reset();
74 STLDeleteValues(&responses_);
75
76 NotifyRegistrationStateChanged();
77 }
78
79 void CloudPolicyClient::Register(em::DeviceRegisterRequest::Type type,
80 const std::string& auth_token,
81 const std::string& client_id,
82 bool is_auto_enrollement) {
83 DCHECK(service_);
84 DCHECK(!auth_token.empty());
85 DCHECK(!is_registered());
86
87 if (client_id.empty()) {
88 // Generate a new client ID. This is intentionally done on each new
89 // registration request in order to preserve privacy. Reusing IDs would mean
90 // the server could track clients by their registration attempts.
91 client_id_ = base::GenerateGUID();
92 } else {
93 client_id_ = client_id;
94 }
95
96 request_job_.reset(
97 service_->CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION));
98 request_job_->SetOAuthToken(auth_token);
99 request_job_->SetClientID(client_id_);
100
101 em::DeviceRegisterRequest* request =
102 request_job_->GetRequest()->mutable_register_request();
103 if (!client_id.empty())
104 request->set_reregister(true);
105 request->set_type(type);
106 if (!machine_id_.empty())
107 request->set_machine_id(machine_id_);
108 if (!machine_model_.empty())
109 request->set_machine_model(machine_model_);
110 if (is_auto_enrollement)
111 request->set_auto_enrolled(true);
112
113 request_job_->SetRetryCallback(
114 base::Bind(&CloudPolicyClient::OnRetryRegister, base::Unretained(this)));
115
116 request_job_->Start(base::Bind(&CloudPolicyClient::OnRegisterCompleted,
117 base::Unretained(this)));
118 }
119
120 void CloudPolicyClient::FetchPolicy() {
121 CHECK(is_registered());
122 CHECK(!namespaces_to_fetch_.empty());
123
124 request_job_.reset(
125 service_->CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH));
126 request_job_->SetDMToken(dm_token_);
127 request_job_->SetClientID(client_id_);
128 request_job_->SetUserAffiliation(user_affiliation_);
129
130 em::DeviceManagementRequest* request = request_job_->GetRequest();
131
132 // Build policy fetch requests.
133 em::DevicePolicyRequest* policy_request = request->mutable_policy_request();
134 for (NamespaceSet::iterator it = namespaces_to_fetch_.begin();
135 it != namespaces_to_fetch_.end(); ++it) {
136 em::PolicyFetchRequest* fetch_request = policy_request->add_request();
137 fetch_request->set_policy_type(it->first);
138 if (!it->second.empty())
139 fetch_request->set_settings_entity_id(it->second);
140
141 #if defined(OS_CHROMEOS)
142 // All policy types on ChromeOS ask for a signed policy blob.
143 fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA);
144 #else
145 // Don't request signed blobs for desktop policy.
146 fetch_request->set_signature_type(em::PolicyFetchRequest::NONE);
147 #endif
148 if (public_key_version_valid_)
149 fetch_request->set_public_key_version(public_key_version_);
150
151 // These fields are included only in requests for chrome policy.
152 if (IsChromePolicy(it->first)) {
153 if (submit_machine_id_ && !machine_id_.empty())
154 fetch_request->set_machine_id(machine_id_);
155 if (!last_policy_timestamp_.is_null()) {
156 base::TimeDelta timestamp(
157 last_policy_timestamp_ - base::Time::UnixEpoch());
158 fetch_request->set_timestamp(timestamp.InMilliseconds());
159 }
160 }
161 }
162
163 // Add status data.
164 if (status_provider_) {
165 if (!status_provider_->GetDeviceStatus(
166 request->mutable_device_status_report_request())) {
167 request->clear_device_status_report_request();
168 }
169 if (!status_provider_->GetSessionStatus(
170 request->mutable_session_status_report_request())) {
171 request->clear_session_status_report_request();
172 }
173 }
174
175 // Fire the job.
176 request_job_->Start(base::Bind(&CloudPolicyClient::OnPolicyFetchCompleted,
177 base::Unretained(this)));
178 }
179
180 void CloudPolicyClient::Unregister() {
181 DCHECK(service_);
182 request_job_.reset(
183 service_->CreateJob(DeviceManagementRequestJob::TYPE_UNREGISTRATION));
184 request_job_->SetDMToken(dm_token_);
185 request_job_->SetClientID(client_id_);
186 request_job_->GetRequest()->mutable_unregister_request();
187 request_job_->Start(base::Bind(&CloudPolicyClient::OnUnregisterCompleted,
188 base::Unretained(this)));
189 }
190
191 void CloudPolicyClient::AddObserver(Observer* observer) {
192 observers_.AddObserver(observer);
193 }
194
195 void CloudPolicyClient::RemoveObserver(Observer* observer) {
196 observers_.RemoveObserver(observer);
197 }
198
199 void CloudPolicyClient::AddNamespaceToFetch(const PolicyNamespaceKey& key) {
200 namespaces_to_fetch_.insert(key);
201 }
202
203 void CloudPolicyClient::RemoveNamespaceToFetch(const PolicyNamespaceKey& key) {
204 namespaces_to_fetch_.erase(key);
205 }
206
207 const em::PolicyFetchResponse* CloudPolicyClient::GetPolicyFor(
208 const PolicyNamespaceKey& key) const {
209 ResponseMap::const_iterator it = responses_.find(key);
210 return it == responses_.end() ? NULL : it->second;
211 }
212
213 void CloudPolicyClient::OnRetryRegister(DeviceManagementRequestJob* job) {
214 DCHECK_EQ(request_job_.get(), job);
215 // If the initial request managed to get to the server but the response didn't
216 // arrive at the client then retrying with the same client ID will fail.
217 // Set the re-registration flag so that the server accepts it.
218 // If the server hasn't seen the client ID before then it will also accept
219 // the re-registration.
220 job->GetRequest()->mutable_register_request()->set_reregister(true);
221 }
222
223 void CloudPolicyClient::OnRegisterCompleted(
224 DeviceManagementStatus status,
225 const em::DeviceManagementResponse& response) {
226 if (status == DM_STATUS_SUCCESS &&
227 (!response.has_register_response() ||
228 !response.register_response().has_device_management_token())) {
229 LOG(WARNING) << "Invalid registration response.";
230 status = DM_STATUS_RESPONSE_DECODING_ERROR;
231 }
232
233 status_ = status;
234 if (status == DM_STATUS_SUCCESS) {
235 dm_token_ = response.register_response().device_management_token();
236 DVLOG(1) << "Client registration complete - DMToken = " << dm_token_;
237
238 // Device mode is only relevant for device policy really, it's the
239 // responsibility of the consumer of the field to check validity.
240 device_mode_ = DEVICE_MODE_NOT_SET;
241 if (response.register_response().has_enrollment_type()) {
242 device_mode_ = TranslateProtobufDeviceMode(
243 response.register_response().enrollment_type());
244 }
245
246 NotifyRegistrationStateChanged();
247 } else {
248 NotifyClientError();
249 }
250 }
251
252 void CloudPolicyClient::OnPolicyFetchCompleted(
253 DeviceManagementStatus status,
254 const em::DeviceManagementResponse& response) {
255 if (status == DM_STATUS_SUCCESS) {
256 if (!response.has_policy_response() ||
257 response.policy_response().response_size() == 0) {
258 LOG(WARNING) << "Empty policy response.";
259 status = DM_STATUS_RESPONSE_DECODING_ERROR;
260 }
261 }
262
263 status_ = status;
264 if (status == DM_STATUS_SUCCESS) {
265 const em::DevicePolicyResponse& policy_response =
266 response.policy_response();
267 STLDeleteValues(&responses_);
268 for (int i = 0; i < policy_response.response_size(); ++i) {
269 const em::PolicyFetchResponse& response = policy_response.response(i);
270 em::PolicyData policy_data;
271 if (!policy_data.ParseFromString(response.policy_data()) ||
272 !policy_data.IsInitialized() ||
273 !policy_data.has_policy_type()) {
274 LOG(WARNING) << "Invalid PolicyData received, ignoring";
275 continue;
276 }
277 const std::string& type = policy_data.policy_type();
278 std::string entity_id;
279 if (policy_data.has_settings_entity_id())
280 entity_id = policy_data.settings_entity_id();
281 PolicyNamespaceKey key(type, entity_id);
282 if (ContainsKey(responses_, key)) {
283 LOG(WARNING) << "Duplicate PolicyFetchResponse for type: "
284 << type << ", entity: " << entity_id << ", ignoring";
285 continue;
286 }
287 responses_[key] = new em::PolicyFetchResponse(response);
288 }
289 if (status_provider_)
290 status_provider_->OnSubmittedSuccessfully();
291 NotifyPolicyFetched();
292 } else {
293 NotifyClientError();
294 }
295 }
296
297 void CloudPolicyClient::OnUnregisterCompleted(
298 DeviceManagementStatus status,
299 const em::DeviceManagementResponse& response) {
300 if (status == DM_STATUS_SUCCESS && !response.has_unregister_response()) {
301 // Assume unregistration has succeeded either way.
302 LOG(WARNING) << "Empty unregistration response.";
303 }
304
305 status_ = status;
306 if (status == DM_STATUS_SUCCESS) {
307 dm_token_.clear();
308 NotifyRegistrationStateChanged();
309 } else {
310 NotifyClientError();
311 }
312 }
313
314 void CloudPolicyClient::NotifyPolicyFetched() {
315 FOR_EACH_OBSERVER(Observer, observers_, OnPolicyFetched(this));
316 }
317
318 void CloudPolicyClient::NotifyRegistrationStateChanged() {
319 FOR_EACH_OBSERVER(Observer, observers_, OnRegistrationStateChanged(this));
320 }
321
322 void CloudPolicyClient::NotifyClientError() {
323 FOR_EACH_OBSERVER(Observer, observers_, OnClientError(this));
324 }
325
326 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/cloud_policy_client.h ('k') | chrome/browser/policy/cloud_policy_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698