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"
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"
27 // A helper class that takes care of asynchronously revoking a given token.
28 class TokenRevoker
: public GaiaAuthConsumer
{
31 ~TokenRevoker() override
;
33 void Start(const std::string
& token
);
36 void OnOAuth2RevokeTokenCompleted() override
;
39 GaiaAuthFetcher gaia_fetcher_
;
41 DISALLOW_COPY_AND_ASSIGN(TokenRevoker
);
44 TokenRevoker::TokenRevoker()
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);
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
),
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
) {
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
) {
101 DoEnrollUsingToken(token
);
104 void EnterpriseEnrollmentHelperImpl::ClearAuth(const base::Closure
& callback
) {
105 // Do not revoke the additional token if enrollment has finished
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
);
140 status_consumer()->OnOtherError(OTHER_ERROR_DOMAIN_MISMATCH
);
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
,
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(
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
,
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
);
197 status_consumer()->OnAuthError(error
);
201 if (!is_additional_token
) {
202 DoEnrollUsingToken(token
);
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
);
220 if (status
.status() == policy::EnrollmentStatus::STATUS_SUCCESS
) {
222 StartupUtils::MarkOobeCompleted();
223 status_consumer()->OnDeviceEnrolled(additional_token_
);
225 status_consumer()->OnEnrollmentError(status
);
229 void EnterpriseEnrollmentHelperImpl::OnDeviceAttributeUpdatePermission(
231 status_consumer()->OnDeviceAttributeUpdatePermission(granted
);
234 void EnterpriseEnrollmentHelperImpl::OnDeviceAttributeUploadCompleted(
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();
254 case GoogleServiceAuthError::USER_NOT_SIGNED_UP
:
255 UMA(policy::kMetricEnrollmentAccountNotSignedUp
);
256 LOG(ERROR
) << "Account not signed up " << error
.state();
258 case GoogleServiceAuthError::ACCOUNT_DELETED
:
259 UMA(policy::kMetricEnrollmentAccountDeleted
);
260 LOG(ERROR
) << "Account deleted " << error
.state();
262 case GoogleServiceAuthError::ACCOUNT_DISABLED
:
263 UMA(policy::kMetricEnrollmentAccountDisabled
);
264 LOG(ERROR
) << "Account disabled " << error
.state();
266 case GoogleServiceAuthError::CONNECTION_FAILED
:
267 case GoogleServiceAuthError::SERVICE_UNAVAILABLE
:
268 UMA(policy::kMetricEnrollmentNetworkFailed
);
269 LOG(WARNING
) << "Network error " << error
.state();
271 case GoogleServiceAuthError::NUM_STATES
:
277 void EnterpriseEnrollmentHelperImpl::ReportEnrollmentStatus(
278 policy::EnrollmentStatus status
) {
279 switch (status
.status()) {
280 case policy::EnrollmentStatus::STATUS_SUCCESS
:
281 UMA(policy::kMetricEnrollmentOK
);
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
:
289 case policy::DM_STATUS_REQUEST_INVALID
:
290 UMA(policy::kMetricEnrollmentRegisterPolicyPayloadInvalid
);
292 case policy::DM_STATUS_SERVICE_DEVICE_NOT_FOUND
:
293 UMA(policy::kMetricEnrollmentRegisterPolicyDeviceNotFound
);
295 case policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID
:
296 UMA(policy::kMetricEnrollmentRegisterPolicyDMTokenInvalid
);
298 case policy::DM_STATUS_SERVICE_ACTIVATION_PENDING
:
299 UMA(policy::kMetricEnrollmentRegisterPolicyActivationPending
);
301 case policy::DM_STATUS_SERVICE_DEVICE_ID_CONFLICT
:
302 UMA(policy::kMetricEnrollmentRegisterPolicyDeviceIdConflict
);
304 case policy::DM_STATUS_SERVICE_POLICY_NOT_FOUND
:
305 UMA(policy::kMetricEnrollmentRegisterPolicyNotFound
);
307 case policy::DM_STATUS_REQUEST_FAILED
:
308 UMA(policy::kMetricEnrollmentRegisterPolicyRequestFailed
);
310 case policy::DM_STATUS_TEMPORARY_UNAVAILABLE
:
311 UMA(policy::kMetricEnrollmentRegisterPolicyTempUnavailable
);
313 case policy::DM_STATUS_HTTP_STATUS_ERROR
:
314 UMA(policy::kMetricEnrollmentRegisterPolicyHttpError
);
316 case policy::DM_STATUS_RESPONSE_DECODING_ERROR
:
317 UMA(policy::kMetricEnrollmentRegisterPolicyResponseInvalid
);
319 case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED
:
320 UMA(policy::kMetricEnrollmentNotSupported
);
322 case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER
:
323 UMA(policy::kMetricEnrollmentRegisterPolicyInvalidSerial
);
325 case policy::DM_STATUS_SERVICE_MISSING_LICENSES
:
326 UMA(policy::kMetricEnrollmentRegisterPolicyMissingLicenses
);
328 case policy::DM_STATUS_SERVICE_DEPROVISIONED
:
329 UMA(policy::kMetricEnrollmentRegisterPolicyDeprovisioned
);
331 case policy::DM_STATUS_SERVICE_DOMAIN_MISMATCH
:
332 UMA(policy::kMetricEnrollmentRegisterPolicyDomainMismatch
);
336 case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE
:
337 UMA(policy::kMetricEnrollmentInvalidEnrollmentMode
);
339 case policy::EnrollmentStatus::STATUS_NO_STATE_KEYS
:
340 UMA(policy::kMetricEnrollmentNoStateKeys
);
342 case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED
:
343 UMA(policy::kMetricEnrollmentPolicyValidationFailed
);
345 case policy::EnrollmentStatus::STATUS_STORE_ERROR
:
346 UMA(policy::kMetricEnrollmentCloudPolicyStoreError
);
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
:
354 case policy::EnterpriseInstallAttributes::LOCK_TIMEOUT
:
355 UMA(policy::kMetricEnrollmentLockboxTimeoutError
);
357 case policy::EnterpriseInstallAttributes::LOCK_BACKEND_INVALID
:
358 UMA(policy::kMetricEnrollmentLockBackendInvalid
);
360 case policy::EnterpriseInstallAttributes::LOCK_ALREADY_LOCKED
:
361 UMA(policy::kMetricEnrollmentLockAlreadyLocked
);
363 case policy::EnterpriseInstallAttributes::LOCK_SET_ERROR
:
364 UMA(policy::kMetricEnrollmentLockSetError
);
366 case policy::EnterpriseInstallAttributes::LOCK_FINALIZE_ERROR
:
367 UMA(policy::kMetricEnrollmentLockFinalizeError
);
369 case policy::EnterpriseInstallAttributes::LOCK_READBACK_ERROR
:
370 UMA(policy::kMetricEnrollmentLockReadbackError
);
372 case policy::EnterpriseInstallAttributes::LOCK_WRONG_DOMAIN
:
373 UMA(policy::kMetricEnrollmentLockDomainMismatch
);
375 case policy::EnterpriseInstallAttributes::LOCK_WRONG_MODE
:
376 UMA(policy::kMetricEnrollmentLockModeMismatch
);
380 case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED
:
381 UMA(policy::kMetricEnrollmentRobotAuthCodeFetchFailed
);
383 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED
:
384 UMA(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed
);
386 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED
:
387 UMA(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed
);
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
);
395 case policy::EnrollmentStatus::STATUS_ATTRIBUTE_UPDATE_FAILED
:
396 UMA(policy::kMetricEnrollmentAttributeUpdateFailed
);
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;
411 } // namespace chromeos