Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / enrollment / enterprise_enrollment_helper_impl.cc
blob8c898f19296afac2739afe92f351b0351274758b
1 // Copyright 2014 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.
5 #include "chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/browser_process_platform_part.h"
13 #include "chrome/browser/chromeos/login/enrollment/enrollment_uma.h"
14 #include "chrome/browser/chromeos/login/startup_utils.h"
15 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
16 #include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h"
17 #include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h"
18 #include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
19 #include "chrome/browser/chromeos/profiles/profile_helper.h"
20 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
21 #include "google_apis/gaia/gaia_auth_consumer.h"
22 #include "google_apis/gaia/gaia_auth_fetcher.h"
23 #include "google_apis/gaia/gaia_constants.h"
25 namespace {
27 // A helper class that takes care of asynchronously revoking a given token.
28 class TokenRevoker : public GaiaAuthConsumer {
29 public:
30 TokenRevoker();
31 ~TokenRevoker() override;
33 void Start(const std::string& token);
35 // GaiaAuthConsumer:
36 void OnOAuth2RevokeTokenCompleted() override;
38 private:
39 GaiaAuthFetcher gaia_fetcher_;
41 DISALLOW_COPY_AND_ASSIGN(TokenRevoker);
44 TokenRevoker::TokenRevoker()
45 : gaia_fetcher_(this,
46 GaiaConstants::kChromeOSSource,
47 g_browser_process->system_request_context()) {
50 TokenRevoker::~TokenRevoker() {
53 void TokenRevoker::Start(const std::string& token) {
54 gaia_fetcher_.StartRevokeOAuth2Token(token);
57 void TokenRevoker::OnOAuth2RevokeTokenCompleted() {
58 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
61 } // namespace
63 namespace chromeos {
65 EnterpriseEnrollmentHelperImpl::EnterpriseEnrollmentHelperImpl(
66 EnrollmentStatusConsumer* status_consumer,
67 const policy::EnrollmentConfig& enrollment_config,
68 const std::string& enrolling_user_domain)
69 : EnterpriseEnrollmentHelper(status_consumer),
70 enrollment_config_(enrollment_config),
71 enrolling_user_domain_(enrolling_user_domain),
72 started_(false),
73 finished_(false),
74 success_(false),
75 auth_data_cleared_(false),
76 weak_ptr_factory_(this) {
79 EnterpriseEnrollmentHelperImpl::~EnterpriseEnrollmentHelperImpl() {
80 DCHECK(g_browser_process->IsShuttingDown() || !started_ ||
81 (finished_ && (success_ || auth_data_cleared_)));
84 void EnterpriseEnrollmentHelperImpl::EnrollUsingAuthCode(
85 const std::string& auth_code,
86 bool fetch_additional_token) {
87 DCHECK(!started_);
88 started_ = true;
89 oauth_fetcher_.reset(new policy::PolicyOAuth2TokenFetcher());
90 oauth_fetcher_->StartWithAuthCode(
91 auth_code, g_browser_process->system_request_context(),
92 base::Bind(&EnterpriseEnrollmentHelperImpl::OnTokenFetched,
93 weak_ptr_factory_.GetWeakPtr(),
94 fetch_additional_token /* is_additional_token */));
97 void EnterpriseEnrollmentHelperImpl::EnrollUsingToken(
98 const std::string& token) {
99 DCHECK(!started_);
100 started_ = true;
101 DoEnrollUsingToken(token);
104 void EnterpriseEnrollmentHelperImpl::ClearAuth(const base::Closure& callback) {
105 // Do not revoke the additional token if enrollment has finished
106 // successfully.
107 if (!success_ && additional_token_.length())
108 (new TokenRevoker())->Start(additional_token_);
110 if (oauth_fetcher_) {
111 if (!oauth_fetcher_->oauth2_access_token().empty())
112 (new TokenRevoker())->Start(oauth_fetcher_->oauth2_access_token());
114 if (!oauth_fetcher_->oauth2_refresh_token().empty())
115 (new TokenRevoker())->Start(oauth_fetcher_->oauth2_refresh_token());
117 oauth_fetcher_.reset();
118 } else if (oauth_token_.length()) {
119 // EnrollUsingToken was called.
120 (new TokenRevoker())->Start(oauth_token_);
123 chromeos::ProfileHelper::Get()->ClearSigninProfile(
124 base::Bind(&EnterpriseEnrollmentHelperImpl::OnSigninProfileCleared,
125 weak_ptr_factory_.GetWeakPtr(), callback));
128 void EnterpriseEnrollmentHelperImpl::DoEnrollUsingToken(
129 const std::string& token) {
130 DCHECK(token == oauth_token_ || oauth_token_.empty());
131 oauth_token_ = token;
132 policy::BrowserPolicyConnectorChromeOS* connector =
133 g_browser_process->platform_part()->browser_policy_connector_chromeos();
134 if (connector->IsEnterpriseManaged() &&
135 connector->GetEnterpriseDomain() != enrolling_user_domain_) {
136 LOG(ERROR) << "Trying to re-enroll to a different domain than "
137 << connector->GetEnterpriseDomain();
138 UMA(policy::kMetricEnrollmentPrecheckDomainMismatch);
139 finished_ = true;
140 status_consumer()->OnOtherError(OTHER_ERROR_DOMAIN_MISMATCH);
141 return;
144 policy::DeviceCloudPolicyInitializer::AllowedDeviceModes device_modes;
145 device_modes[policy::DEVICE_MODE_ENTERPRISE] = true;
146 connector->ScheduleServiceInitialization(0);
148 policy::DeviceCloudPolicyInitializer* dcp_initializer =
149 connector->GetDeviceCloudPolicyInitializer();
150 CHECK(dcp_initializer);
151 dcp_initializer->StartEnrollment(
152 policy::MANAGEMENT_MODE_ENTERPRISE_MANAGED,
153 connector->device_management_service(),
154 nullptr /* owner_settings_service */, enrollment_config_, token,
155 device_modes,
156 base::Bind(&EnterpriseEnrollmentHelperImpl::OnEnrollmentFinished,
157 weak_ptr_factory_.GetWeakPtr()));
160 void EnterpriseEnrollmentHelperImpl::GetDeviceAttributeUpdatePermission() {
161 policy::BrowserPolicyConnectorChromeOS* connector =
162 g_browser_process->platform_part()->browser_policy_connector_chromeos();
163 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
164 connector->GetDeviceCloudPolicyManager();
165 policy::CloudPolicyClient* client = policy_manager->core()->client();
167 client->GetDeviceAttributeUpdatePermission(
168 oauth_token_,
169 base::Bind(
170 &EnterpriseEnrollmentHelperImpl::OnDeviceAttributeUpdatePermission,
171 weak_ptr_factory_.GetWeakPtr()));
174 void EnterpriseEnrollmentHelperImpl::UpdateDeviceAttributes(
175 const std::string& asset_id,
176 const std::string& location) {
177 policy::BrowserPolicyConnectorChromeOS* connector =
178 g_browser_process->platform_part()->browser_policy_connector_chromeos();
179 policy::DeviceCloudPolicyManagerChromeOS* policy_manager =
180 connector->GetDeviceCloudPolicyManager();
181 policy::CloudPolicyClient* client = policy_manager->core()->client();
183 client->UpdateDeviceAttributes(
184 oauth_token_, asset_id, location,
185 base::Bind(
186 &EnterpriseEnrollmentHelperImpl::OnDeviceAttributeUploadCompleted,
187 weak_ptr_factory_.GetWeakPtr()));
190 void EnterpriseEnrollmentHelperImpl::OnTokenFetched(
191 bool is_additional_token,
192 const std::string& token,
193 const GoogleServiceAuthError& error) {
194 if (error.state() != GoogleServiceAuthError::NONE) {
195 ReportAuthStatus(error);
196 finished_ = true;
197 status_consumer()->OnAuthError(error);
198 return;
201 if (!is_additional_token) {
202 DoEnrollUsingToken(token);
203 return;
206 additional_token_ = token;
207 std::string refresh_token = oauth_fetcher_->oauth2_refresh_token();
208 oauth_fetcher_.reset(new policy::PolicyOAuth2TokenFetcher());
209 oauth_fetcher_->StartWithRefreshToken(
210 refresh_token, g_browser_process->system_request_context(),
211 base::Bind(&EnterpriseEnrollmentHelperImpl::OnTokenFetched,
212 weak_ptr_factory_.GetWeakPtr(),
213 false /* is_additional_token */));
216 void EnterpriseEnrollmentHelperImpl::OnEnrollmentFinished(
217 policy::EnrollmentStatus status) {
218 ReportEnrollmentStatus(status);
219 finished_ = true;
220 if (status.status() == policy::EnrollmentStatus::STATUS_SUCCESS) {
221 success_ = true;
222 StartupUtils::MarkOobeCompleted();
223 status_consumer()->OnDeviceEnrolled(additional_token_);
224 } else {
225 status_consumer()->OnEnrollmentError(status);
229 void EnterpriseEnrollmentHelperImpl::OnDeviceAttributeUpdatePermission(
230 bool granted) {
231 status_consumer()->OnDeviceAttributeUpdatePermission(granted);
234 void EnterpriseEnrollmentHelperImpl::OnDeviceAttributeUploadCompleted(
235 bool success) {
236 status_consumer()->OnDeviceAttributeUploadCompleted(success);
239 void EnterpriseEnrollmentHelperImpl::ReportAuthStatus(
240 const GoogleServiceAuthError& error) {
241 switch (error.state()) {
242 case GoogleServiceAuthError::NONE:
243 case GoogleServiceAuthError::CAPTCHA_REQUIRED:
244 case GoogleServiceAuthError::TWO_FACTOR:
245 case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
246 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
247 case GoogleServiceAuthError::REQUEST_CANCELED:
248 case GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE:
249 case GoogleServiceAuthError::SERVICE_ERROR:
250 case GoogleServiceAuthError::WEB_LOGIN_REQUIRED:
251 UMA(policy::kMetricEnrollmentLoginFailed);
252 LOG(ERROR) << "Auth error " << error.state();
253 break;
254 case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
255 UMA(policy::kMetricEnrollmentAccountNotSignedUp);
256 LOG(ERROR) << "Account not signed up " << error.state();
257 break;
258 case GoogleServiceAuthError::ACCOUNT_DELETED:
259 UMA(policy::kMetricEnrollmentAccountDeleted);
260 LOG(ERROR) << "Account deleted " << error.state();
261 break;
262 case GoogleServiceAuthError::ACCOUNT_DISABLED:
263 UMA(policy::kMetricEnrollmentAccountDisabled);
264 LOG(ERROR) << "Account disabled " << error.state();
265 break;
266 case GoogleServiceAuthError::CONNECTION_FAILED:
267 case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
268 UMA(policy::kMetricEnrollmentNetworkFailed);
269 LOG(WARNING) << "Network error " << error.state();
270 break;
271 case GoogleServiceAuthError::NUM_STATES:
272 NOTREACHED();
273 break;
277 void EnterpriseEnrollmentHelperImpl::ReportEnrollmentStatus(
278 policy::EnrollmentStatus status) {
279 switch (status.status()) {
280 case policy::EnrollmentStatus::STATUS_SUCCESS:
281 UMA(policy::kMetricEnrollmentOK);
282 return;
283 case policy::EnrollmentStatus::STATUS_REGISTRATION_FAILED:
284 case policy::EnrollmentStatus::STATUS_POLICY_FETCH_FAILED:
285 switch (status.client_status()) {
286 case policy::DM_STATUS_SUCCESS:
287 NOTREACHED();
288 break;
289 case policy::DM_STATUS_REQUEST_INVALID:
290 UMA(policy::kMetricEnrollmentRegisterPolicyPayloadInvalid);
291 break;
292 case policy::DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
293 UMA(policy::kMetricEnrollmentRegisterPolicyDeviceNotFound);
294 break;
295 case policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
296 UMA(policy::kMetricEnrollmentRegisterPolicyDMTokenInvalid);
297 break;
298 case policy::DM_STATUS_SERVICE_ACTIVATION_PENDING:
299 UMA(policy::kMetricEnrollmentRegisterPolicyActivationPending);
300 break;
301 case policy::DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
302 UMA(policy::kMetricEnrollmentRegisterPolicyDeviceIdConflict);
303 break;
304 case policy::DM_STATUS_SERVICE_POLICY_NOT_FOUND:
305 UMA(policy::kMetricEnrollmentRegisterPolicyNotFound);
306 break;
307 case policy::DM_STATUS_REQUEST_FAILED:
308 UMA(policy::kMetricEnrollmentRegisterPolicyRequestFailed);
309 break;
310 case policy::DM_STATUS_TEMPORARY_UNAVAILABLE:
311 UMA(policy::kMetricEnrollmentRegisterPolicyTempUnavailable);
312 break;
313 case policy::DM_STATUS_HTTP_STATUS_ERROR:
314 UMA(policy::kMetricEnrollmentRegisterPolicyHttpError);
315 break;
316 case policy::DM_STATUS_RESPONSE_DECODING_ERROR:
317 UMA(policy::kMetricEnrollmentRegisterPolicyResponseInvalid);
318 break;
319 case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
320 UMA(policy::kMetricEnrollmentNotSupported);
321 break;
322 case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
323 UMA(policy::kMetricEnrollmentRegisterPolicyInvalidSerial);
324 break;
325 case policy::DM_STATUS_SERVICE_MISSING_LICENSES:
326 UMA(policy::kMetricEnrollmentRegisterPolicyMissingLicenses);
327 break;
328 case policy::DM_STATUS_SERVICE_DEPROVISIONED:
329 UMA(policy::kMetricEnrollmentRegisterPolicyDeprovisioned);
330 break;
331 case policy::DM_STATUS_SERVICE_DOMAIN_MISMATCH:
332 UMA(policy::kMetricEnrollmentRegisterPolicyDomainMismatch);
333 break;
335 break;
336 case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE:
337 UMA(policy::kMetricEnrollmentInvalidEnrollmentMode);
338 break;
339 case policy::EnrollmentStatus::STATUS_NO_STATE_KEYS:
340 UMA(policy::kMetricEnrollmentNoStateKeys);
341 break;
342 case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED:
343 UMA(policy::kMetricEnrollmentPolicyValidationFailed);
344 break;
345 case policy::EnrollmentStatus::STATUS_STORE_ERROR:
346 UMA(policy::kMetricEnrollmentCloudPolicyStoreError);
347 break;
348 case policy::EnrollmentStatus::STATUS_LOCK_ERROR:
349 switch (status.lock_status()) {
350 case policy::EnterpriseInstallAttributes::LOCK_SUCCESS:
351 case policy::EnterpriseInstallAttributes::LOCK_NOT_READY:
352 NOTREACHED();
353 break;
354 case policy::EnterpriseInstallAttributes::LOCK_TIMEOUT:
355 UMA(policy::kMetricEnrollmentLockboxTimeoutError);
356 break;
357 case policy::EnterpriseInstallAttributes::LOCK_BACKEND_INVALID:
358 UMA(policy::kMetricEnrollmentLockBackendInvalid);
359 break;
360 case policy::EnterpriseInstallAttributes::LOCK_ALREADY_LOCKED:
361 UMA(policy::kMetricEnrollmentLockAlreadyLocked);
362 break;
363 case policy::EnterpriseInstallAttributes::LOCK_SET_ERROR:
364 UMA(policy::kMetricEnrollmentLockSetError);
365 break;
366 case policy::EnterpriseInstallAttributes::LOCK_FINALIZE_ERROR:
367 UMA(policy::kMetricEnrollmentLockFinalizeError);
368 break;
369 case policy::EnterpriseInstallAttributes::LOCK_READBACK_ERROR:
370 UMA(policy::kMetricEnrollmentLockReadbackError);
371 break;
372 case policy::EnterpriseInstallAttributes::LOCK_WRONG_DOMAIN:
373 UMA(policy::kMetricEnrollmentLockDomainMismatch);
374 break;
375 case policy::EnterpriseInstallAttributes::LOCK_WRONG_MODE:
376 UMA(policy::kMetricEnrollmentLockModeMismatch);
377 break;
379 break;
380 case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED:
381 UMA(policy::kMetricEnrollmentRobotAuthCodeFetchFailed);
382 break;
383 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED:
384 UMA(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed);
385 break;
386 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED:
387 UMA(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed);
388 break;
389 case policy::EnrollmentStatus::STATUS_STORE_TOKEN_AND_ID_FAILED:
390 // This error should not happen for enterprise enrollment, it only affects
391 // consumer enrollment.
392 UMA(policy::kMetricEnrollmentStoreTokenAndIdFailed);
393 NOTREACHED();
394 break;
395 case policy::EnrollmentStatus::STATUS_ATTRIBUTE_UPDATE_FAILED:
396 UMA(policy::kMetricEnrollmentAttributeUpdateFailed);
397 break;
401 void EnterpriseEnrollmentHelperImpl::UMA(policy::MetricEnrollment sample) {
402 EnrollmentUMA(sample, enrollment_config_.mode);
405 void EnterpriseEnrollmentHelperImpl::OnSigninProfileCleared(
406 const base::Closure& callback) {
407 auth_data_cleared_ = true;
408 callback.Run();
411 } // namespace chromeos