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