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

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

Issue 7298012: Consolidate data storage and notifications in the cloud policy subsystem (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 9 years, 5 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) 2011 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/cloud_policy_controller.h" 5 #include "chrome/browser/policy/cloud_policy_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/logging.h" 10 #include "base/logging.h"
12 #include "base/message_loop.h"
13 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
14 #include "base/rand_util.h" 12 #include "base/rand_util.h"
15 #include "base/string_util.h" 13 #include "base/string_util.h"
16 #include "chrome/browser/policy/cloud_policy_cache_base.h" 14 #include "chrome/browser/policy/cloud_policy_cache_base.h"
17 #include "chrome/browser/policy/cloud_policy_subsystem.h" 15 #include "chrome/browser/policy/cloud_policy_subsystem.h"
18 #include "chrome/browser/policy/device_management_backend.h"
19 #include "chrome/browser/policy/device_management_service.h" 16 #include "chrome/browser/policy/device_management_service.h"
20 #include "chrome/browser/policy/enterprise_metrics.h" 17 #include "chrome/browser/policy/enterprise_metrics.h"
21 #include "chrome/browser/policy/proto/device_management_constants.h" 18 #include "chrome/browser/policy/proto/device_management_constants.h"
19 #include "chrome/common/guid.h"
20
21 namespace {
22 22
23 // Domain names that are known not to be managed. 23 // Domain names that are known not to be managed.
24 // We don't register the device when such a user logs in. 24 // We don't register the device when such a user logs in.
25 static const char* kNonManagedDomains[] = { 25 const char* kNonManagedDomains[] = {
26 "@googlemail.com", 26 "@googlemail.com",
27 "@gmail.com" 27 "@gmail.com"
28 }; 28 };
29 29
30 // Checks the domain part of the given username against the list of known 30 // Checks the domain part of the given username against the list of known
31 // non-managed domain names. Returns false if |username| is empty or 31 // non-managed domain names. Returns false if |username| is empty or
32 // in a domain known not to be managed. 32 // in a domain known not to be managed.
33 static bool CanBeInManagedDomain(const std::string& username) { 33 bool CanBeInManagedDomain(const std::string& username) {
34 if (username.empty()) { 34 if (username.empty()) {
35 // This means incognito user in case of ChromiumOS and 35 // This means incognito user in case of ChromiumOS and
36 // no logged-in user in case of Chromium (SigninService). 36 // no logged-in user in case of Chromium (SigninService).
37 return false; 37 return false;
38 } 38 }
39 for (size_t i = 0; i < arraysize(kNonManagedDomains); i++) { 39 for (size_t i = 0; i < arraysize(kNonManagedDomains); i++) {
40 if (EndsWith(username, kNonManagedDomains[i], true)) { 40 if (EndsWith(username, kNonManagedDomains[i], true)) {
41 return false; 41 return false;
42 } 42 }
43 } 43 }
44 return true; 44 return true;
45 } 45 }
46 46
47 }
48
47 namespace policy { 49 namespace policy {
48 50
49 namespace em = enterprise_management; 51 namespace em = enterprise_management;
50 52
51 // The maximum ratio in percent of the policy refresh rate we use for adjusting 53 // The maximum ratio in percent of the policy refresh rate we use for adjusting
52 // the policy refresh time instant. The rationale is to avoid load spikes from 54 // the policy refresh time instant. The rationale is to avoid load spikes from
53 // many devices that were set up in sync for some reason. 55 // many devices that were set up in sync for some reason.
54 static const int kPolicyRefreshDeviationFactorPercent = 10; 56 static const int kPolicyRefreshDeviationFactorPercent = 10;
55 // Maximum deviation we are willing to accept. 57 // Maximum deviation we are willing to accept.
56 static const int64 kPolicyRefreshDeviationMaxInMilliseconds = 30 * 60 * 1000; 58 static const int64 kPolicyRefreshDeviationMaxInMilliseconds = 30 * 60 * 1000;
57 59
58 // These are the base values for delays before retrying after an error. They 60 // These are the base values for delays before retrying after an error. They
59 // will be doubled each time they are used. 61 // will be doubled each time they are used.
60 static const int64 kPolicyRefreshErrorDelayInMilliseconds = 62 static const int64 kPolicyRefreshErrorDelayInMilliseconds =
61 5 * 60 * 1000; // 5 minutes 63 5 * 60 * 1000; // 5 minutes
62 64
63 // Default value for the policy refresh rate. 65 // Default value for the policy refresh rate.
64 static const int kPolicyRefreshRateInMilliseconds = 66 static const int kPolicyRefreshRateInMilliseconds =
65 3 * 60 * 60 * 1000; // 3 hours. 67 3 * 60 * 60 * 1000; // 3 hours.
66 68
67 CloudPolicyController::CloudPolicyController( 69 CloudPolicyController::CloudPolicyController(
68 DeviceManagementService* service, 70 DeviceManagementService* service,
69 CloudPolicyCacheBase* cache, 71 CloudPolicyCacheBase* cache,
70 DeviceTokenFetcher* token_fetcher, 72 DeviceTokenFetcher* token_fetcher,
71 CloudPolicyIdentityStrategy* identity_strategy, 73 CloudPolicyDataStore* data_store,
72 PolicyNotifier* notifier) { 74 PolicyNotifier* notifier) {
73 Initialize(service, 75 Initialize(service,
74 cache, 76 cache,
75 token_fetcher, 77 token_fetcher,
76 identity_strategy, 78 data_store,
77 notifier, 79 notifier,
78 new DelayedWorkScheduler); 80 new DelayedWorkScheduler);
79 } 81 }
80 82
81 CloudPolicyController::~CloudPolicyController() { 83 CloudPolicyController::~CloudPolicyController() {
82 token_fetcher_->RemoveObserver(this); 84 data_store_->RemoveObserver(this);
83 identity_strategy_->RemoveObserver(this);
84 scheduler_->CancelDelayedWork(); 85 scheduler_->CancelDelayedWork();
85 } 86 }
86 87
87 void CloudPolicyController::SetRefreshRate(int64 refresh_rate_milliseconds) { 88 void CloudPolicyController::SetRefreshRate(int64 refresh_rate_milliseconds) {
88 policy_refresh_rate_ms_ = refresh_rate_milliseconds; 89 policy_refresh_rate_ms_ = refresh_rate_milliseconds;
89 90
90 // Reschedule the refresh task if necessary. 91 // Reschedule the refresh task if necessary.
91 if (state_ == STATE_POLICY_VALID) 92 if (state_ == STATE_POLICY_VALID)
92 SetState(STATE_POLICY_VALID); 93 SetState(STATE_POLICY_VALID);
93 } 94 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 case DeviceManagementBackend::kErrorRequestFailed: 154 case DeviceManagementBackend::kErrorRequestFailed:
154 case DeviceManagementBackend::kErrorTemporaryUnavailable: { 155 case DeviceManagementBackend::kErrorTemporaryUnavailable: {
155 VLOG(1) << "A temporary error in the communication with the policy server" 156 VLOG(1) << "A temporary error in the communication with the policy server"
156 << " occurred."; 157 << " occurred.";
157 // Will retry last operation but gracefully backing off. 158 // Will retry last operation but gracefully backing off.
158 SetState(STATE_POLICY_ERROR); 159 SetState(STATE_POLICY_ERROR);
159 } 160 }
160 } 161 }
161 } 162 }
162 163
163 void CloudPolicyController::OnDeviceTokenAvailable() {
164 identity_strategy_->OnDeviceTokenAvailable(token_fetcher_->GetDeviceToken());
165 }
166
167 void CloudPolicyController::OnDeviceTokenChanged() { 164 void CloudPolicyController::OnDeviceTokenChanged() {
168 if (identity_strategy_->GetDeviceToken().empty()) 165 if (data_store_->device_token().empty())
169 SetState(STATE_TOKEN_UNAVAILABLE); 166 SetState(STATE_TOKEN_UNAVAILABLE);
170 else 167 else
171 SetState(STATE_TOKEN_VALID); 168 SetState(STATE_TOKEN_VALID);
172 } 169 }
173 170
174 void CloudPolicyController::OnCredentialsChanged() { 171 void CloudPolicyController::OnCredentialsChanged() {
175 notifier_->Inform(CloudPolicySubsystem::UNENROLLED, 172 // This notification is only interesting if we don't have a device token.
176 CloudPolicySubsystem::NO_DETAILS, 173 // If we already have a device token, that must be matching the current
177 PolicyNotifier::POLICY_CONTROLLER); 174 // user, because (1) we always recreate the policy subsystem after user
178 effective_policy_refresh_error_delay_ms_ = 175 // login (2) tokens are cached per user.
179 kPolicyRefreshErrorDelayInMilliseconds; 176 if (data_store_->device_token().empty()) {
180 SetState(STATE_TOKEN_UNAVAILABLE); 177 notifier_->Inform(CloudPolicySubsystem::UNENROLLED,
178 CloudPolicySubsystem::NO_DETAILS,
179 PolicyNotifier::POLICY_CONTROLLER);
180 effective_policy_refresh_error_delay_ms_ =
181 kPolicyRefreshErrorDelayInMilliseconds;
182 SetState(STATE_TOKEN_UNAVAILABLE);
183 }
184 }
185
186 void CloudPolicyController::OnDataStoreGoingAway() {
187 NOTREACHED();
181 } 188 }
182 189
183 CloudPolicyController::CloudPolicyController( 190 CloudPolicyController::CloudPolicyController(
184 DeviceManagementService* service, 191 DeviceManagementService* service,
185 CloudPolicyCacheBase* cache, 192 CloudPolicyCacheBase* cache,
186 DeviceTokenFetcher* token_fetcher, 193 DeviceTokenFetcher* token_fetcher,
187 CloudPolicyIdentityStrategy* identity_strategy, 194 CloudPolicyDataStore* data_store,
188 PolicyNotifier* notifier, 195 PolicyNotifier* notifier,
189 DelayedWorkScheduler* scheduler) { 196 DelayedWorkScheduler* scheduler) {
190 Initialize(service, 197 Initialize(service,
191 cache, 198 cache,
192 token_fetcher, 199 token_fetcher,
193 identity_strategy, 200 data_store,
194 notifier, 201 notifier,
195 scheduler); 202 scheduler);
196 } 203 }
197 204
198 void CloudPolicyController::Initialize( 205 void CloudPolicyController::Initialize(
199 DeviceManagementService* service, 206 DeviceManagementService* service,
200 CloudPolicyCacheBase* cache, 207 CloudPolicyCacheBase* cache,
201 DeviceTokenFetcher* token_fetcher, 208 DeviceTokenFetcher* token_fetcher,
202 CloudPolicyIdentityStrategy* identity_strategy, 209 CloudPolicyDataStore* data_store,
203 PolicyNotifier* notifier, 210 PolicyNotifier* notifier,
204 DelayedWorkScheduler* scheduler) { 211 DelayedWorkScheduler* scheduler) {
205 DCHECK(cache); 212 DCHECK(cache);
206 213
207 service_ = service; 214 service_ = service;
208 cache_ = cache; 215 cache_ = cache;
209 token_fetcher_ = token_fetcher; 216 token_fetcher_ = token_fetcher;
210 identity_strategy_ = identity_strategy; 217 data_store_ = data_store;
211 notifier_ = notifier; 218 notifier_ = notifier;
212 state_ = STATE_TOKEN_UNAVAILABLE; 219 state_ = STATE_TOKEN_UNAVAILABLE;
213 policy_refresh_rate_ms_ = kPolicyRefreshRateInMilliseconds; 220 policy_refresh_rate_ms_ = kPolicyRefreshRateInMilliseconds;
214 effective_policy_refresh_error_delay_ms_ = 221 effective_policy_refresh_error_delay_ms_ =
215 kPolicyRefreshErrorDelayInMilliseconds; 222 kPolicyRefreshErrorDelayInMilliseconds;
216 scheduler_.reset(scheduler); 223 scheduler_.reset(scheduler);
217 token_fetcher_->AddObserver(this); 224 data_store_->AddObserver(this);
218 identity_strategy_->AddObserver(this); 225 if (!data_store_->device_token().empty())
219 if (!identity_strategy_->GetDeviceToken().empty())
220 SetState(STATE_TOKEN_VALID); 226 SetState(STATE_TOKEN_VALID);
221 else 227 else
222 SetState(STATE_TOKEN_UNAVAILABLE); 228 SetState(STATE_TOKEN_UNAVAILABLE);
223 } 229 }
224 230
225 void CloudPolicyController::FetchToken() { 231 void CloudPolicyController::FetchToken() {
226 std::string username; 232 if (data_store_->token_cache_loaded() &&
227 std::string auth_token; 233 !data_store_->user_name().empty() &&
228 std::string device_id = identity_strategy_->GetDeviceID(); 234 !data_store_->gaia_token().empty()) {
229 std::string machine_id = identity_strategy_->GetMachineID(); 235 if (CanBeInManagedDomain(data_store_->user_name())) {
230 std::string machine_model = identity_strategy_->GetMachineModel(); 236 // Generate a new random device id. (It'll only be kept if registration
231 em::DeviceRegisterRequest_Type policy_type = 237 // succeeds.)
232 identity_strategy_->GetPolicyRegisterType(); 238 data_store_->set_device_id(guid::GenerateGUID());
233 if (identity_strategy_->GetCredentials(&username, &auth_token)) { 239 token_fetcher_->FetchToken();
234 if (CanBeInManagedDomain(username)) {
235 token_fetcher_->FetchToken(auth_token, device_id, policy_type,
236 machine_id, machine_model);
237 } else { 240 } else {
238 SetState(STATE_TOKEN_UNMANAGED); 241 SetState(STATE_TOKEN_UNMANAGED);
239 } 242 }
240 } 243 }
241 } 244 }
242 245
243 void CloudPolicyController::SendPolicyRequest() { 246 void CloudPolicyController::SendPolicyRequest() {
244 backend_.reset(service_->CreateBackend()); 247 backend_.reset(service_->CreateBackend());
245 DCHECK(!identity_strategy_->GetDeviceToken().empty()); 248 DCHECK(!data_store_->device_token().empty());
246 em::DevicePolicyRequest policy_request; 249 em::DevicePolicyRequest policy_request;
247 em::PolicyFetchRequest* fetch_request = policy_request.add_request(); 250 em::PolicyFetchRequest* fetch_request = policy_request.add_request();
248 fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA); 251 fetch_request->set_signature_type(em::PolicyFetchRequest::SHA1_RSA);
249 fetch_request->set_policy_type(identity_strategy_->GetPolicyType()); 252 fetch_request->set_policy_type(data_store_->policy_type());
250 if (!cache_->is_unmanaged() && 253 if (!cache_->is_unmanaged() &&
251 !cache_->last_policy_refresh_time().is_null()) { 254 !cache_->last_policy_refresh_time().is_null()) {
252 base::TimeDelta timestamp = 255 base::TimeDelta timestamp =
253 cache_->last_policy_refresh_time() - base::Time::UnixEpoch(); 256 cache_->last_policy_refresh_time() - base::Time::UnixEpoch();
254 fetch_request->set_timestamp(timestamp.InMilliseconds()); 257 fetch_request->set_timestamp(timestamp.InMilliseconds());
255 } 258 }
256 int key_version = 0; 259 int key_version = 0;
257 if (cache_->GetPublicKeyVersion(&key_version)) 260 if (cache_->GetPublicKeyVersion(&key_version))
258 fetch_request->set_public_key_version(key_version); 261 fetch_request->set_public_key_version(key_version);
259 262
260 backend_->ProcessPolicyRequest(identity_strategy_->GetDeviceToken(), 263 backend_->ProcessPolicyRequest(data_store_->device_token(),
261 identity_strategy_->GetDeviceID(), 264 data_store_->device_id(),
262 policy_request, this); 265 policy_request, this);
263 } 266 }
264 267
265 void CloudPolicyController::DoWork() { 268 void CloudPolicyController::DoWork() {
266 switch (state_) { 269 switch (state_) {
267 case STATE_TOKEN_UNAVAILABLE: 270 case STATE_TOKEN_UNAVAILABLE:
268 case STATE_TOKEN_ERROR: 271 case STATE_TOKEN_ERROR:
269 FetchToken(); 272 FetchToken();
270 return; 273 return;
271 case STATE_TOKEN_VALID: 274 case STATE_TOKEN_VALID:
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 } 363 }
361 364
362 int64 CloudPolicyController::GetRefreshDelay() { 365 int64 CloudPolicyController::GetRefreshDelay() {
363 int64 deviation = (kPolicyRefreshDeviationFactorPercent * 366 int64 deviation = (kPolicyRefreshDeviationFactorPercent *
364 policy_refresh_rate_ms_) / 100; 367 policy_refresh_rate_ms_) / 100;
365 deviation = std::min(deviation, kPolicyRefreshDeviationMaxInMilliseconds); 368 deviation = std::min(deviation, kPolicyRefreshDeviationMaxInMilliseconds);
366 return policy_refresh_rate_ms_ - base::RandGenerator(deviation + 1); 369 return policy_refresh_rate_ms_ - base::RandGenerator(deviation + 1);
367 } 370 }
368 371
369 } // namespace policy 372 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/cloud_policy_controller.h ('k') | chrome/browser/policy/cloud_policy_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698