enrollment_handler_chromeos.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/enrollment_handler_chromeos.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/command_line.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/browser_process.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chromeos/chromeos_switches.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_constants.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "google_apis/gaia/gaia_urls.h" 191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/http/http_status_code.h" 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "policy/proto/device_management_backend.pb.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Retry for InstallAttrs initialization every 500ms. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLockRetryIntervalMs = 500; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maximum time to retry InstallAttrs initialization before we give up. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLockRetryTimeoutMs = 10 * 60 * 1000; // 10 minutes. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Testing token used when the enrollment-skip-robot-auth is set to skip talking 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// to GAIA for an actual token. This is needed to be able to run against the 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// testing DMServer implementations. 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const char kTestingRobotToken[] = "test-token"; 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EnrollmentHandlerChromeOS::EnrollmentHandlerChromeOS( 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeviceCloudPolicyStoreChromeOS* store, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnterpriseInstallAttributes* install_attributes, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<CloudPolicyClient> client, 448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> background_task_runner, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& auth_token, 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& client_id, 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_auto_enrollment, 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& requisition, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AllowedDeviceModes& allowed_device_modes, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const EnrollmentCallback& completion_callback) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : store_(store), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_attributes_(install_attributes), 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_(client.Pass()), 548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) background_task_runner_(background_task_runner), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_token_(auth_token), 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_id_(client_id), 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_auto_enrollment_(is_auto_enrollment), 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) requisition_(requisition), 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allowed_device_modes_(allowed_device_modes), 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) completion_callback_(completion_callback), 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_mode_(DEVICE_MODE_NOT_SET), 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enrollment_step_(STEP_PENDING), 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lockbox_init_duration_(0), 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_(this) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!client_->is_registered()); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(DM_STATUS_SUCCESS, client_->status()); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_->AddObserver(this); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_->AddObserver(this); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_->AddNamespaceToFetch(PolicyNamespaceKey( 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dm_protocol::kChromeDevicePolicyType, std::string())); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EnrollmentHandlerChromeOS::~EnrollmentHandlerChromeOS() { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_->RemoveObserver(this); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::StartEnrollment() { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(STEP_PENDING, enrollment_step_); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enrollment_step_ = STEP_LOADING_STORE; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AttemptRegistration(); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<CloudPolicyClient> EnrollmentHandlerChromeOS::ReleaseClient() { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return client_.Pass(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::OnPolicyFetched(CloudPolicyClient* client) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(client_.get(), client); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(STEP_POLICY_FETCH, enrollment_step_); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enrollment_step_ = STEP_VALIDATION; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Validate the policy. 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const em::PolicyFetchResponse* policy = client_->GetPolicyFor( 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PolicyNamespaceKey(dm_protocol::kChromeDevicePolicyType, std::string())); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!policy) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReportResult(EnrollmentStatus::ForFetchError( 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DM_STATUS_RESPONSE_DECODING_ERROR)); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DeviceCloudPolicyValidator> validator( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeviceCloudPolicyValidator::Create( 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<em::PolicyFetchResponse>( 1078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) new em::PolicyFetchResponse(*policy)), 1088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) background_task_runner_)); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) validator->ValidateTimestamp(base::Time(), base::Time::NowFromSystemTime(), 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If this is re-enrollment, make sure that the new policy matches the 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // previously-enrolled domain. 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string domain; 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (install_attributes_->IsEnterpriseDevice()) { 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) domain = install_attributes_->GetDomain(); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) validator->ValidateDomain(domain); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) validator->ValidateDMToken(client->dm_token(), 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CloudPolicyValidatorBase::DM_TOKEN_REQUIRED); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) validator->ValidatePolicyType(dm_protocol::kChromeDevicePolicyType); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) validator->ValidatePayload(); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If |domain| is empty here, the policy validation code will just use the 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // domain from the username field in the policy itself to do key validation. 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(mnissler): Plumb the enrolling user's username into this object so 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // we can validate the username on the resulting policy, and use the domain 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // from that username to validate the key below (http://crbug.com/343074). 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) validator->ValidateInitialKey(GetPolicyVerificationKey(), domain); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) validator.release()->StartValidation( 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&EnrollmentHandlerChromeOS::PolicyValidated, 1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::OnRegistrationStateChanged( 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloudPolicyClient* client) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(client_.get(), client); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enrollment_step_ == STEP_REGISTRATION && client_->is_registered()) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enrollment_step_ = STEP_POLICY_FETCH, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_mode_ = client_->device_mode(); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (device_mode_ == DEVICE_MODE_NOT_SET) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device_mode_ = DEVICE_MODE_ENTERPRISE; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!allowed_device_modes_.test(device_mode_)) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Bad device mode " << device_mode_; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForStatus( 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE)); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_->FetchPolicy(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Registration state changed to " << client_->is_registered() 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " in step " << enrollment_step_; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::OnClientError(CloudPolicyClient* client) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(client_.get(), client); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (enrollment_step_ == STEP_ROBOT_AUTH_FETCH) { 1611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) LOG(ERROR) << "API authentication code fetch failed: " 1621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) << client_->status(); 1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ReportResult(EnrollmentStatus::ForRobotAuthFetchError(client_->status())); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (enrollment_step_ < STEP_POLICY_FETCH) { 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForRegistrationError(client_->status())); 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForFetchError(client_->status())); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::OnStoreLoaded(CloudPolicyStore* store) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(store_, store); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enrollment_step_ == STEP_LOADING_STORE) { 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the |store_| wasn't initialized when StartEnrollment() was 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // called, then AttemptRegistration() bails silently. This gets 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // registration rolling again after the store finishes loading. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AttemptRegistration(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (enrollment_step_ == STEP_STORE_POLICY) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForStatus(EnrollmentStatus::STATUS_SUCCESS)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::OnStoreError(CloudPolicyStore* store) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(store_, store); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForStoreError(store_->status(), 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store_->validation_status())); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::AttemptRegistration() { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(STEP_LOADING_STORE, enrollment_step_); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (store_->is_initialized()) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enrollment_step_ = STEP_REGISTRATION; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_->Register(em::DeviceRegisterRequest::DEVICE, 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) auth_token_, client_id_, is_auto_enrollment_, 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) requisition_); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::PolicyValidated( 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeviceCloudPolicyValidator* validator) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(STEP_VALIDATION, enrollment_step_); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (validator->success()) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) policy_ = validator->policy().Pass(); 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) username_ = validator->policy_data()->username(); 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) device_id_ = validator->policy_data()->device_id(); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chromeos::switches::kEnterpriseEnrollmentSkipRobotAuth)) { 210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // For test purposes we allow enrollment to succeed without proper robot 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // account and use the provided value as a token. 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) refresh_token_ = kTestingRobotToken; 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enrollment_step_ = STEP_LOCK_DEVICE, 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StartLockDevice(username_, device_mode_, device_id_); 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enrollment_step_ = STEP_ROBOT_AUTH_FETCH; 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_->FetchRobotAuthCodes(auth_token_); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForValidationError(validator->status())); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EnrollmentHandlerChromeOS::OnRobotAuthCodesFetched( 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CloudPolicyClient* client) { 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(client_.get(), client); 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_EQ(STEP_ROBOT_AUTH_FETCH, enrollment_step_); 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enrollment_step_ = STEP_ROBOT_AUTH_REFRESH; 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gaia::OAuthClientInfo client_info; 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_info.client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id(); 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_info.client_secret = 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_secret(); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client_info.redirect_uri = "oob"; 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Use the system request context to avoid sending user cookies. 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gaia_oauth_client_.reset(new gaia::GaiaOAuthClient( 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) g_browser_process->system_request_context())); 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gaia_oauth_client_->GetTokensFromAuthCode(client_info, 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) client->robot_api_auth_code(), 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0 /* max_retries */, 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this); 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// GaiaOAuthClient::Delegate callback for OAuth2 refresh token fetched. 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EnrollmentHandlerChromeOS::OnGetTokensResponse( 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& refresh_token, 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& access_token, 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int expires_in_seconds) { 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_EQ(STEP_ROBOT_AUTH_REFRESH, enrollment_step_); 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) refresh_token_ = refresh_token; 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enrollment_step_ = STEP_LOCK_DEVICE, 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartLockDevice(username_, device_mode_, device_id_); 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// GaiaOAuthClient::Delegate 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EnrollmentHandlerChromeOS::OnRefreshTokenResponse( 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& access_token, 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int expires_in_seconds) { 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We never use the code that should trigger this callback. 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(FATAL) << "Unexpected callback invoked"; 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// GaiaOAuthClient::Delegate OAuth2 error when fetching refresh token request. 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EnrollmentHandlerChromeOS::OnOAuthError() { 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_EQ(STEP_ROBOT_AUTH_REFRESH, enrollment_step_); 2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // OnOAuthError is only called if the request is bad (malformed) or the 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // response is bad (empty access token returned). 2731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) LOG(ERROR) << "OAuth protocol error while fetching API refresh token."; 2741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ReportResult( 2751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EnrollmentStatus::ForRobotRefreshFetchError(net::HTTP_BAD_REQUEST)); 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// GaiaOAuthClient::Delegate network error when fetching refresh token. 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EnrollmentHandlerChromeOS::OnNetworkError(int response_code) { 2801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK_EQ(STEP_ROBOT_AUTH_REFRESH, enrollment_step_); 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Network error while fetching API refresh token: " 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << response_code; 2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ReportResult( 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EnrollmentStatus::ForRobotRefreshFetchError(response_code)); 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EnrollmentHandlerChromeOS::StartLockDevice( 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeviceMode device_mode, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& device_id) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(STEP_LOCK_DEVICE, enrollment_step_); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since this method is also called directly. 2931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) install_attributes_->LockDevice( 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user, device_mode, device_id, 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EnrollmentHandlerChromeOS::HandleLockDeviceResult, 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user, 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) device_mode, 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) device_id)); 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void EnrollmentHandlerChromeOS::HandleLockDeviceResult( 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& user, 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DeviceMode device_mode, 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& device_id, 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EnterpriseInstallAttributes::LockResult lock_result) { 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CHECK_EQ(STEP_LOCK_DEVICE, enrollment_step_); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (lock_result) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EnterpriseInstallAttributes::LOCK_SUCCESS: 3121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Get the token service so we can store our robot refresh token. 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) enrollment_step_ = STEP_STORE_ROBOT_AUTH; 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chromeos::DeviceOAuth2TokenServiceFactory::Get( 3151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&EnrollmentHandlerChromeOS::DidGetTokenService, 3161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EnterpriseInstallAttributes::LOCK_NOT_READY: 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We wait up to |kLockRetryTimeoutMs| milliseconds and if it hasn't 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // succeeded by then show an error to the user and stop the enrollment. 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (lockbox_init_duration_ < kLockRetryTimeoutMs) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InstallAttributes not ready yet, retry later. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Install Attributes not ready yet will retry in " 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << kLockRetryIntervalMs << "ms."; 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&EnrollmentHandlerChromeOS::StartLockDevice, 3281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user, device_mode, device_id), 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kLockRetryIntervalMs)); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lockbox_init_duration_ += kLockRetryIntervalMs; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForStatus( 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnrollmentStatus::STATUS_LOCK_TIMEOUT)); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EnterpriseInstallAttributes::LOCK_BACKEND_ERROR: 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForStatus( 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnrollmentStatus::STATUS_LOCK_ERROR)); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EnterpriseInstallAttributes::LOCK_WRONG_USER: 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Enrollment cannot proceed because the InstallAttrs " 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "has been locked already!"; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForStatus( 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnrollmentStatus::STATUS_LOCK_WRONG_USER)); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Invalid lock result " << lock_result; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportResult(EnrollmentStatus::ForStatus( 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnrollmentStatus::STATUS_LOCK_ERROR)); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void EnrollmentHandlerChromeOS::DidGetTokenService( 3551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) chromeos::DeviceOAuth2TokenService* token_service) { 3561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CHECK_EQ(STEP_STORE_ROBOT_AUTH, enrollment_step_); 3571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Store the robot API auth refresh token. 3581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!token_service) { 3591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) LOG(ERROR) << "Failed to store API refresh token (no token service)."; 3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ReportResult(EnrollmentStatus::ForStatus( 3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED)); 3621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 3631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!token_service->SetAndSaveRefreshToken(refresh_token_)) { 3661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) LOG(ERROR) << "Failed to store API refresh token."; 3671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ReportResult(EnrollmentStatus::ForStatus( 3681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED)); 3691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 3701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 3711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) enrollment_step_ = STEP_STORE_POLICY; 3731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) store_->InstallInitialPolicy(*policy_); 3741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::Stop() { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (client_.get()) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_->RemoveObserver(this); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enrollment_step_ = STEP_FINISHED; 3801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) completion_callback_.Reset(); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void EnrollmentHandlerChromeOS::ReportResult(EnrollmentStatus status) { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnrollmentCallback callback = completion_callback_; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status.status() != EnrollmentStatus::STATUS_SUCCESS) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Enrollment failed: " << status.status() 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " " << status.client_status() 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " " << status.validation_status() 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " " << status.store_status(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback.is_null()) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(status); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy 400