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

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

Powered by Google App Engine
This is Rietveld 408576698