supervised_user_creation_controller_new.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// found in the LICENSE file.
423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_creation_controller_new.h"
623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/base64.h"
823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/bind.h"
923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/file_util.h"
1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/files/file_path.h"
1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/strings/string_util.h"
1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/sys_info.h"
1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/task_runner_util.h"
1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/values.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_constants.h"
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h"
2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h"
2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h"
2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chromeos/cryptohome/cryptohome_parameters.h"
2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chromeos/dbus/session_manager_client.h"
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/auth/key.h"
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/auth/user_context.h"
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_manager/user.h"
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/public/browser/user_metrics.h"
3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "crypto/random.h"
3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace chromeos {
3823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)namespace {
4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const int kUserCreationTimeoutSeconds = 30;  // 30 seconds.
4223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool StoreSupervisedUserFiles(const std::string& token,
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              const base::FilePath& base_path) {
4523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!base::SysInfo::IsRunningOnChromeOS()) {
4623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // If running on desktop, cryptohome stub does not create home directory.
4723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    base::CreateDirectory(base_path);
4823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::FilePath token_file = base_path.Append(kSupervisedUserTokenFilename);
5023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int bytes = base::WriteFile(token_file, token.c_str(), token.length());
5123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return bytes >= 0;
5223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
5323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
5423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}  // namespace
5523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SupervisedUserCreationControllerNew::SupervisedUserCreationControllerNew(
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SupervisedUserCreationControllerNew::StatusConsumer* consumer,
5823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& manager_id)
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : SupervisedUserCreationController(consumer),
6023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      stage_(STAGE_INITIAL),
6123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      weak_factory_(this) {
6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_.reset(
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new SupervisedUserCreationControllerNew::UserCreationContext());
6423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->manager_id = manager_id;
6523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
6623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SupervisedUserCreationControllerNew::~SupervisedUserCreationControllerNew() {}
6823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SupervisedUserCreationControllerNew::UserCreationContext::
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    UserCreationContext() {}
7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SupervisedUserCreationControllerNew::UserCreationContext::
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ~UserCreationContext() {}
7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::SetManagerProfile(
7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    Profile* manager_profile) {
7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->manager_profile = manager_profile;
7823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
7923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)Profile* SupervisedUserCreationControllerNew::GetManagerProfile() {
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return creation_context_->manager_profile;
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::StartCreation(
8523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const base::string16& display_name,
8623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& password,
8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int avatar_index) {
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(creation_context_);
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->creation_type = NEW_USER;
9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->display_name = display_name;
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->password = password;
9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->avatar_index = avatar_index;
9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  StartCreationImpl();
9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::StartImport(
9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const base::string16& display_name,
9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& password,
9923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int avatar_index,
10023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& sync_id,
10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& master_key) {
10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(creation_context_);
10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->creation_type = USER_IMPORT_OLD;
10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->display_name = display_name;
10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->password = password;
10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->avatar_index = avatar_index;
10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->sync_user_id = sync_id;
11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->master_key = master_key;
11223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  StartCreationImpl();
11323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::StartImport(
11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const base::string16& display_name,
11723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    int avatar_index,
11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& sync_id,
11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& master_key,
12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const base::DictionaryValue* password_data,
12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& encryption_key,
12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& signature_key) {
12323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(creation_context_);
124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  creation_context_->creation_type = USER_IMPORT_NEW;
12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->display_name = display_name;
127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
12823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->avatar_index = avatar_index;
12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->sync_user_id = sync_id;
13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->master_key = master_key;
13323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  password_data->GetStringWithoutPathExpansion(
13523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      kEncryptedPassword, &creation_context_->salted_password);
13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
13723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->signature_key = signature_key;
13823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->encryption_key = encryption_key;
13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->password_data.MergeDictionary(password_data);
14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  StartCreationImpl();
14323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
14423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::StartCreationImpl() {
14623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(creation_context_);
147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK_EQ(STAGE_INITIAL, stage_);
14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  VLOG(1) << "Starting supervised user creation";
14923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  VLOG(1) << " Phase 1 : Prepare keys";
15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  SupervisedUserManager* manager =
1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ChromeUserManager::Get()->GetSupervisedUserManager();
15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  manager->StartCreationTransaction(creation_context_->display_name);
15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->local_user_id = manager->GenerateUserId();
15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (creation_context_->creation_type == NEW_USER) {
15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    creation_context_->sync_user_id =
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        SupervisedUserRegistrationUtility::GenerateNewSupervisedUserId();
15923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  manager->SetCreationTransactionUserId(creation_context_->local_user_id);
16223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
16323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stage_ = TRANSACTION_STARTED;
16423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  manager->CreateUserRecord(creation_context_->manager_id,
16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                            creation_context_->local_user_id,
16723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                            creation_context_->sync_user_id,
16823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                            creation_context_->display_name);
16923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
17023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  SupervisedUserAuthentication* authentication =
1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ChromeUserManager::Get()->GetSupervisedUserManager()->GetAuthentication();
17223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
17323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // When importing M35+ users we need only to store data, for all other cases
17423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // we need to create some keys.
17523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (creation_context_->creation_type != USER_IMPORT_NEW) {
17623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // Of all required keys old imported users have only master key.
17723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    // Otherwise they are the same as newly created users in terms of keys.
17823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (creation_context_->creation_type == NEW_USER) {
17923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      creation_context_->master_key = authentication->GenerateMasterKey();
18023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    }
18123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    base::DictionaryValue extra;
18323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    authentication->FillDataForNewUser(creation_context_->local_user_id,
18423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                       creation_context_->password,
18523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                       &creation_context_->password_data,
18623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                       &extra);
187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    creation_context_->password_data.GetStringWithoutPathExpansion(
188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        kEncryptedPassword, &creation_context_->salted_password);
18923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    extra.GetStringWithoutPathExpansion(kPasswordEncryptionKey,
19023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                        &creation_context_->encryption_key);
19123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    extra.GetStringWithoutPathExpansion(kPasswordSignatureKey,
19223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                        &creation_context_->signature_key);
19323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
19423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
19523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  authentication->StorePasswordData(creation_context_->local_user_id,
19623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                    creation_context_->password_data);
19723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stage_ = KEYS_GENERATED;
19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
19923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  VLOG(1) << " Phase 2 : Create cryptohome";
20023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
20123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  timeout_timer_.Start(
20223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      FROM_HERE,
20323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      base::TimeDelta::FromSeconds(kUserCreationTimeoutSeconds),
20423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      this,
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      &SupervisedUserCreationControllerNew::CreationTimedOut);
20623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  authenticator_ = new ExtendedAuthenticator(this);
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UserContext user_context;
208cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  user_context.SetKey(Key(creation_context_->master_key));
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  authenticator_->TransformKeyIfNeeded(
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      user_context,
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&SupervisedUserCreationControllerNew::OnKeyTransformedIfNeeded,
21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
21423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::OnKeyTransformedIfNeeded(
216cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const UserContext& user_context) {
21723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  VLOG(1) << " Phase 2.1 : Got hashed master key";
218cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  creation_context_->salted_master_key = user_context.GetKey()->GetSecret();
21923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
22023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Create home dir with two keys.
22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  std::vector<cryptohome::KeyDefinition> keys;
22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Main key is the master key. Just as keys for plain GAIA users, it is salted
22423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // with system salt. It has all usual privileges.
22523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  cryptohome::KeyDefinition master_key(creation_context_->salted_master_key,
22623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                       kCryptohomeMasterKeyLabel,
22723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                       cryptohome::PRIV_DEFAULT);
22823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
22923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  keys.push_back(master_key);
23023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  authenticator_->CreateMount(
23123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      creation_context_->local_user_id,
23223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      keys,
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&SupervisedUserCreationControllerNew::OnMountSuccess,
23423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
23523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
23623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::OnAuthenticationFailure(
23823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ExtendedAuthenticator::AuthState error) {
23923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  timeout_timer_.Stop();
24023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ErrorCode code = NO_ERROR;
24123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  switch (error) {
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case SupervisedUserAuthenticator::NO_MOUNT:
24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      code = CRYPTOHOME_NO_MOUNT;
24423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      break;
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case SupervisedUserAuthenticator::FAILED_MOUNT:
24623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      code = CRYPTOHOME_FAILED_MOUNT;
24723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      break;
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    case SupervisedUserAuthenticator::FAILED_TPM:
24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      code = CRYPTOHOME_FAILED_TPM;
25023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      break;
25123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    default:
25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      NOTREACHED();
25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
25423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stage_ = STAGE_ERROR;
25523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (consumer_)
25623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    consumer_->OnCreationError(code);
25723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::OnMountSuccess(
26023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& mount_hash) {
26123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(creation_context_);
262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK_EQ(KEYS_GENERATED, stage_);
263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  VLOG(1) << " Phase 2.2 : Created home dir with master key";
26423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
26523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->mount_hash = mount_hash;
266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Plain text password, hashed and salted with individual salt.
268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // It can be used for mounting homedir, and can be replaced only when signed.
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  cryptohome::KeyDefinition password_key(
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      creation_context_->salted_password,
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      kCryptohomeSupervisedUserKeyLabel,
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      kCryptohomeSupervisedUserKeyPrivileges);
273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::Base64Decode(creation_context_->encryption_key,
274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                     &password_key.encryption_key);
275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::Base64Decode(creation_context_->signature_key,
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                     &password_key.signature_key);
277c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Key key(Key::KEY_TYPE_SALTED_PBKDF2_AES256_1234,
27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          std::string(),  // The salt is stored elsewhere.
28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          creation_context_->salted_master_key);
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  key.SetLabel(kCryptohomeMasterKeyLabel);
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UserContext context(creation_context_->local_user_id);
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  context.SetKey(key);
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  context.SetIsUsingOAuth(false);
285c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  authenticator_->AddKey(
287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      context,
288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      password_key,
289c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      true,
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&SupervisedUserCreationControllerNew::OnAddKeySuccess,
291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 weak_factory_.GetWeakPtr()));
292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::OnAddKeySuccess() {
295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(creation_context_);
296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK_EQ(KEYS_GENERATED, stage_);
297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  stage_ = CRYPTOHOME_CREATED;
298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
29923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  VLOG(1) << " Phase 3 : Create/update user on chrome.com/manage";
30023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
30123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ProfileSyncService* sync_service =
30223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      ProfileSyncServiceFactory::GetInstance()->GetForProfile(
30323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          creation_context_->manager_profile);
30423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ProfileSyncService::SyncStatusSummary status =
30523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      sync_service->QuerySyncStatusSummary();
30623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
30723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (status == ProfileSyncService::DATATYPES_NOT_INITIALIZED)
30823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    consumer_->OnLongCreationWarning();
30923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
31023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->registration_utility =
311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      SupervisedUserRegistrationUtility::Create(
31223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          creation_context_->manager_profile);
31323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SupervisedUserRegistrationInfo info(creation_context_->display_name,
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                      creation_context_->avatar_index);
31623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  info.master_key = creation_context_->master_key;
31723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  info.password_signature_key = creation_context_->signature_key;
31823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  info.password_encryption_key = creation_context_->encryption_key;
31923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
32023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  info.password_data.MergeDictionary(&creation_context_->password_data);
32123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
32223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Registration utility will update user data if user already exist.
32323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->registration_utility->Register(
32423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      creation_context_->sync_user_id,
32523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      info,
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&SupervisedUserCreationControllerNew::RegistrationCallback,
32723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                 weak_factory_.GetWeakPtr()));
32823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
32923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::RegistrationCallback(
33123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const GoogleServiceAuthError& error,
33223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const std::string& token) {
33323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(creation_context_);
334c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK_EQ(CRYPTOHOME_CREATED, stage_);
33523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
33623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stage_ = DASHBOARD_CREATED;
33723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
33823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (error.state() == GoogleServiceAuthError::NONE) {
33923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    creation_context_->token = token;
34023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
34123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    PostTaskAndReplyWithResult(
34223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        content::BrowserThread::GetBlockingPool(),
34323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        FROM_HERE,
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&StoreSupervisedUserFiles,
34523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                   creation_context_->token,
34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   ProfileHelper::GetProfilePathByUserIdHash(
34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                       creation_context_->mount_hash)),
34803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        base::Bind(
34903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            &SupervisedUserCreationControllerNew::OnSupervisedUserFilesStored,
35003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            weak_factory_.GetWeakPtr()));
35123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else {
35223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    stage_ = STAGE_ERROR;
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(ERROR) << "Supervised user creation failed. Error code "
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               << error.state();
35523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (consumer_)
35623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      consumer_->OnCreationError(CLOUD_SERVER_ERROR);
35723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
35823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
35923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::OnSupervisedUserFilesStored(
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool success) {
36223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(creation_context_);
363c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK_EQ(DASHBOARD_CREATED, stage_);
36423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
36523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (!success) {
36623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    stage_ = STAGE_ERROR;
36723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    if (consumer_)
36823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      consumer_->OnCreationError(TOKEN_WRITE_FAILED);
36923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return;
37023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
37123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Assume that new token is valid. It will be automatically invalidated if
37223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // sync service fails to use it.
3736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  user_manager::UserManager::Get()->SaveUserOAuthStatus(
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      creation_context_->local_user_id,
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_manager::User::OAUTH2_TOKEN_STATUS_VALID);
37623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
37723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stage_ = TOKEN_WRITTEN;
37823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
37923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  timeout_timer_.Stop();
3806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ChromeUserManager::Get()
3816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ->GetSupervisedUserManager()
3826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ->CommitCreationTransaction();
38323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  content::RecordAction(
38423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      base::UserMetricsAction("ManagedMode_LocallyManagedUserCreated"));
38523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
38623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  stage_ = TRANSACTION_COMMITTED;
38723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
38823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (consumer_)
38923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    consumer_->OnCreationSuccess();
39023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
39123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::CreationTimedOut() {
39323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  LOG(ERROR) << "Supervised user creation timed out. stage = " << stage_;
39423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (consumer_)
39523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    consumer_->OnCreationTimeout();
39623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
39723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::FinishCreation() {
39923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  chrome::AttemptUserExit();
40023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
40123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void SupervisedUserCreationControllerNew::CancelCreation() {
40323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  creation_context_->registration_utility.reset();
40423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  chrome::AttemptUserExit();
40523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
40623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::string SupervisedUserCreationControllerNew::GetSupervisedUserId() {
40823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  DCHECK(creation_context_);
40923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return creation_context_->local_user_id;
41023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
41123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
41223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}  // namespace chromeos
413