supervised_user_manager_impl.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file.
48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/file_util.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/files/file_path.h"
98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/prefs/pref_service.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/strings/string_util.h"
138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/strings/stringprintf.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h"
168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/values.h"
178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/browser_process.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/supervised/supervised_user_constants.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_service.h"
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/user_names.h"
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h"
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/user_manager/user_type.h"
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)using content::BrowserThread;
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace {
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Names for pref keys in Local State.
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A map from supervised user local user id to sync user id.
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kSupervisedUserSyncId[] = "ManagedUserSyncId";
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A map from supervised user id to manager user id.
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kSupervisedUserManagers[] = "ManagedUserManagers";
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A map from supervised user id to manager display name.
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kSupervisedUserManagerNames[] = "ManagedUserManagerNames";
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A map from supervised user id to manager display e-mail.
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const char kSupervisedUserManagerDisplayEmails[] =
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "ManagedUserManagerDisplayEmails";
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A vector pref of the supervised accounts defined on this device, that had
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// not logged in yet.
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kSupervisedUsersFirstRun[] = "LocallyManagedUsersFirstRun";
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A pref of the next id for supervised users generation.
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kSupervisedUsersNextId[] = "LocallyManagedUsersNextId";
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A pref of the next id for supervised users generation.
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kSupervisedUserCreationTransactionDisplayName[] =
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "LocallyManagedUserCreationTransactionDisplayName";
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A pref of the next id for supervised users generation.
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kSupervisedUserCreationTransactionUserId[] =
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "LocallyManagedUserCreationTransactionUserId";
628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A map from user id to password schema id.
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSupervisedUserPasswordSchema[] =
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "SupervisedUserPasswordSchema";
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A map from user id to password salt.
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSupervisedUserPasswordSalt[] =
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "SupervisedUserPasswordSalt";
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A map from user id to password revision.
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSupervisedUserPasswordRevision[] =
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "SupervisedUserPasswordRevision";
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// A map from user id to flag indicating if password should be updated upon
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// signin.
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kSupervisedUserNeedPasswordUpdate[] =
78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    "SupervisedUserNeedPasswordUpdate";
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// A map from user id to flag indicating if cryptohome does not have signature
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// key.
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kSupervisedUserIncompleteKey[] = "SupervisedUserHasIncompleteKey";
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string LoadSyncToken(base::FilePath profile_dir) {
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string token;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath token_file =
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_dir.Append(chromeos::kSupervisedUserTokenFilename);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VLOG(1) << "Loading" << token_file.value();
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!base::ReadFileToString(token_file, &token))
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return std::string();
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return token;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace
958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace chromeos {
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSchemaVersion[] = "SchemaVersion";
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kPasswordRevision[] = "PasswordRevision";
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSalt[] = "PasswordSalt";
10123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const char kPasswordSignature[] = "PasswordSignature";
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kEncryptedPassword[] = "EncryptedPassword";
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kRequirePasswordUpdate[] = "RequirePasswordUpdate";
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char kHasIncompleteKey[] = "HasIncompleteKey";
10523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const char kPasswordEncryptionKey[] = "password.hmac.encryption";
10623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const char kPasswordSignatureKey[] = "password.hmac.signature";
10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kPasswordUpdateFile[] = "password.update";
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kMinPasswordRevision = 1;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// static
1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManager::RegisterPrefs(PrefRegistrySimple* registry) {
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterListPref(kSupervisedUsersFirstRun);
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  registry->RegisterIntegerPref(kSupervisedUsersNextId, 0);
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  registry->RegisterStringPref(
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kSupervisedUserCreationTransactionDisplayName, "");
1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  registry->RegisterStringPref(
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kSupervisedUserCreationTransactionUserId, "");
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserSyncId);
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserManagers);
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserManagerNames);
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserManagerDisplayEmails);
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserPasswordSchema);
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserPasswordSalt);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserPasswordRevision);
127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  registry->RegisterDictionaryPref(kSupervisedUserNeedPasswordUpdate);
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  registry->RegisterDictionaryPref(kSupervisedUserIncompleteKey);
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SupervisedUserManagerImpl::SupervisedUserManagerImpl(ChromeUserManager* owner)
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    : owner_(owner), cros_settings_(CrosSettings::Get()) {
1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // SupervisedUserManager instance should be used only on UI thread.
1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  authentication_.reset(new SupervisedUserAuthentication(this));
1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string SupervisedUserManagerImpl::GenerateUserId() {
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int counter = g_browser_process->local_state()->
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetInteger(kSupervisedUsersNextId);
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string id;
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool user_exists;
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  do {
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    id = base::StringPrintf(
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        "%d@%s", counter, chromeos::login::kSupervisedUserDomain);
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    counter++;
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    user_exists = (NULL != owner_->FindUser(id));
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DCHECK(!user_exists);
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (user_exists) {
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      LOG(ERROR) << "Supervised user with id " << id << " already exists.";
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } while (user_exists);
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      SetInteger(kSupervisedUsersNextId, counter);
1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return id;
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SupervisedUserManagerImpl::HasSupervisedUsers(
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::string& manager_id) const {
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const user_manager::UserList& users = owner_->GetUsers();
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (user_manager::UserList::const_iterator it = users.begin();
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != users.end();
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if ((*it)->GetType() == user_manager::USER_TYPE_SUPERVISED) {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (manager_id == GetManagerUserId((*it)->email()))
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return true;
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const user_manager::User* SupervisedUserManagerImpl::CreateUserRecord(
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& manager_id,
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& local_user_id,
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& sync_user_id,
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const base::string16& display_name) {
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const user_manager::User* user = FindByDisplayName(display_name);
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(!user);
1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (user)
1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return user;
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const user_manager::User* manager = owner_->FindUser(manager_id);
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK(manager);
1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  user_manager::User* new_user =
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      user_manager::User::CreateSupervisedUser(local_user_id);
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  owner_->AddUserRecord(new_user);
1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ListPrefUpdate prefs_new_users_update(local_state,
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        kSupervisedUsersFirstRun);
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DictionaryPrefUpdate sync_id_update(local_state, kSupervisedUserSyncId);
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DictionaryPrefUpdate manager_update(local_state, kSupervisedUserManagers);
2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DictionaryPrefUpdate manager_name_update(local_state,
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           kSupervisedUserManagerNames);
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DictionaryPrefUpdate manager_email_update(
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      local_state,
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      kSupervisedUserManagerDisplayEmails);
2078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs_new_users_update->Insert(0, new base::StringValue(local_user_id));
2098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  sync_id_update->SetWithoutPathExpansion(local_user_id,
2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new base::StringValue(sync_user_id));
2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  manager_update->SetWithoutPathExpansion(local_user_id,
2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new base::StringValue(manager->email()));
2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  manager_name_update->SetWithoutPathExpansion(local_user_id,
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new base::StringValue(manager->GetDisplayName()));
2168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  manager_email_update->SetWithoutPathExpansion(local_user_id,
2178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new base::StringValue(manager->display_email()));
2188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  owner_->SaveUserDisplayName(local_user_id, display_name);
2208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
2228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return new_user;
2238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string SupervisedUserManagerImpl::GetUserSyncId(const std::string& user_id)
2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const {
2278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string result;
228f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GetUserStringValue(user_id, kSupervisedUserSyncId, &result);
2298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return result;
2308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 SupervisedUserManagerImpl::GetManagerDisplayName(
2338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& user_id) const {
2348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* manager_names =
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      local_state->GetDictionary(kSupervisedUserManagerNames);
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 result;
2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (manager_names->GetStringWithoutPathExpansion(user_id, &result) &&
2398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      !result.empty())
2408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return result;
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::UTF8ToUTF16(GetManagerDisplayEmail(user_id));
2428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string SupervisedUserManagerImpl::GetManagerUserId(
2458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& user_id) const {
2468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string result;
247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GetUserStringValue(user_id, kSupervisedUserManagers, &result);
2488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return result;
2498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string SupervisedUserManagerImpl::GetManagerDisplayEmail(
2528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& user_id) const {
2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string result;
254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (GetUserStringValue(user_id,
255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         kSupervisedUserManagerDisplayEmails,
256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         &result) &&
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      !result.empty())
2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return result;
2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return GetManagerUserId(user_id);
2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
2618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::GetPasswordInformation(
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id,
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* result) {
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int value;
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (GetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, &value))
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result->SetIntegerWithoutPathExpansion(kSchemaVersion, value);
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (GetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, &value))
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result->SetIntegerWithoutPathExpansion(kPasswordRevision, value);
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool flag;
272c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (GetUserBooleanValue(user_id, kSupervisedUserNeedPasswordUpdate, &flag))
273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    result->SetBooleanWithoutPathExpansion(kRequirePasswordUpdate, flag);
274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (GetUserBooleanValue(user_id, kSupervisedUserIncompleteKey, &flag))
275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    result->SetBooleanWithoutPathExpansion(kHasIncompleteKey, flag);
276c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string salt;
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (GetUserStringValue(user_id, kSupervisedUserPasswordSalt, &salt))
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result->SetStringWithoutPathExpansion(kSalt, salt);
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::SetPasswordInformation(
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::string& user_id,
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const base::DictionaryValue* password_info) {
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int value;
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (password_info->GetIntegerWithoutPathExpansion(kSchemaVersion, &value))
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, value);
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (password_info->GetIntegerWithoutPathExpansion(kPasswordRevision, &value))
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, value);
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
291c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool flag;
292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (password_info->GetBooleanWithoutPathExpansion(kRequirePasswordUpdate,
293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                                    &flag)) {
294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    SetUserBooleanValue(user_id, kSupervisedUserNeedPasswordUpdate, flag);
295c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
296c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (password_info->GetBooleanWithoutPathExpansion(kHasIncompleteKey, &flag))
297c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    SetUserBooleanValue(user_id, kSupervisedUserIncompleteKey, flag);
298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string salt;
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (password_info->GetStringWithoutPathExpansion(kSalt, &salt))
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetUserStringValue(user_id, kSupervisedUserPasswordSalt, salt);
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SupervisedUserManagerImpl::GetUserStringValue(
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id,
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* key,
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string* out_value) const {
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return dictionary->GetStringWithoutPathExpansion(user_id, out_value);
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SupervisedUserManagerImpl::GetUserIntegerValue(
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id,
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* key,
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int* out_value) const {
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return dictionary->GetIntegerWithoutPathExpansion(user_id, out_value);
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
323c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool SupervisedUserManagerImpl::GetUserBooleanValue(const std::string& user_id,
324c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                                    const char* key,
325c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                                    bool* out_value) const {
326c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  PrefService* local_state = g_browser_process->local_state();
327c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
328c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return dictionary->GetBooleanWithoutPathExpansion(user_id, out_value);
329c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
330c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::SetUserStringValue(
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id,
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* key,
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& value) {
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DictionaryPrefUpdate update(local_state, key);
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  update->SetStringWithoutPathExpansion(user_id, value);
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::SetUserIntegerValue(
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id,
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const char* key,
3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const int value) {
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DictionaryPrefUpdate update(local_state, key);
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  update->SetIntegerWithoutPathExpansion(user_id, value);
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
349c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SupervisedUserManagerImpl::SetUserBooleanValue(const std::string& user_id,
350c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                                    const char* key,
351c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                                    const bool value) {
352c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  PrefService* local_state = g_browser_process->local_state();
353c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DictionaryPrefUpdate update(local_state, key);
354c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  update->SetBooleanWithoutPathExpansion(user_id, value);
355c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
356c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const user_manager::User* SupervisedUserManagerImpl::FindByDisplayName(
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& display_name) const {
3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const user_manager::UserList& users = owner_->GetUsers();
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (user_manager::UserList::const_iterator it = users.begin();
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != users.end();
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (((*it)->GetType() == user_manager::USER_TYPE_SUPERVISED) &&
3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        ((*it)->display_name() == display_name)) {
3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return *it;
3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return NULL;
3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const user_manager::User* SupervisedUserManagerImpl::FindBySyncId(
3738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& sync_id) const {
3748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const user_manager::UserList& users = owner_->GetUsers();
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (user_manager::UserList::const_iterator it = users.begin();
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != users.end();
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it) {
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (((*it)->GetType() == user_manager::USER_TYPE_SUPERVISED) &&
3808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        (GetUserSyncId((*it)->email()) == sync_id)) {
3818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return *it;
3828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
3838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return NULL;
3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::StartCreationTransaction(
388a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& display_name) {
3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      SetString(kSupervisedUserCreationTransactionDisplayName,
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                base::UTF16ToASCII(display_name));
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::SetCreationTransactionUserId(
3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& email) {
3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
3985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      SetString(kSupervisedUserCreationTransactionUserId,
3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                email);
4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::CommitCreationTransaction() {
4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ClearPref(kSupervisedUserCreationTransactionDisplayName);
4068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ClearPref(kSupervisedUserCreationTransactionUserId);
4088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SupervisedUserManagerImpl::HasFailedUserCreationTransaction() {
4128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return !(g_browser_process->local_state()->
4135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               GetString(kSupervisedUserCreationTransactionDisplayName).
4148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   empty());
4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::RollbackUserCreationTransaction() {
4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
4198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string display_name = prefs->
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetString(kSupervisedUserCreationTransactionDisplayName);
4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string user_id = prefs->
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetString(kSupervisedUserCreationTransactionUserId);
4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  LOG(WARNING) << "Cleaning up transaction for "
4268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << display_name << "/" << user_id;
4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (user_id.empty()) {
4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Not much to do - just remove transaction.
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    prefs->ClearPref(kSupervisedUserCreationTransactionDisplayName);
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    prefs->CommitPendingWrite();
4328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
4338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (gaia::ExtractDomainName(user_id) !=
4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      chromeos::login::kSupervisedUserDomain) {
4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LOG(WARNING) << "Clean up transaction for  non-supervised user found :"
4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 << user_id << ", will not remove data";
4395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    prefs->ClearPref(kSupervisedUserCreationTransactionDisplayName);
4405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    prefs->ClearPref(kSupervisedUserCreationTransactionUserId);
441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    prefs->CommitPendingWrite();
4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
4438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  owner_->RemoveNonOwnerUserInternal(user_id, NULL);
4458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs->ClearPref(kSupervisedUserCreationTransactionDisplayName);
4475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs->ClearPref(kSupervisedUserCreationTransactionUserId);
4488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs->CommitPendingWrite();
4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::RemoveNonCryptohomeData(
4528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& user_id) {
4538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ListPrefUpdate prefs_new_users_update(prefs, kSupervisedUsersFirstRun);
4558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
4568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserSyncId);
458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserManagers);
459f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserManagerNames);
460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserManagerDisplayEmails);
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserPasswordSalt);
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserPasswordSchema);
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserPasswordRevision);
464c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  CleanPref(user_id, kSupervisedUserNeedPasswordUpdate);
465c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  CleanPref(user_id, kSupervisedUserIncompleteKey);
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::CleanPref(const std::string& user_id,
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          const char* key) {
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DictionaryPrefUpdate dict_update(prefs, key);
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dict_update->RemoveWithoutPathExpansion(user_id, NULL);
4738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ListPrefUpdate prefs_new_users_update(g_browser_process->local_state(),
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        kSupervisedUsersFirstRun);
4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
4798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::UpdateManagerName(const std::string& manager_id,
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& new_display_name) {
4838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
4848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* manager_ids =
486f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      local_state->GetDictionary(kSupervisedUserManagers);
4878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DictionaryPrefUpdate manager_name_update(local_state,
489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           kSupervisedUserManagerNames);
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
4918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      it.Advance()) {
4928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string user_id;
4938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    bool has_manager_id = it.value().GetAsString(&user_id);
4948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DCHECK(has_manager_id);
4958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (user_id == manager_id) {
4968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      manager_name_update->SetWithoutPathExpansion(
4978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          it.key(),
4988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          new base::StringValue(new_display_name));
4998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
5008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SupervisedUserAuthentication* SupervisedUserManagerImpl::GetAuthentication() {
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return authentication_.get();
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::LoadSupervisedUserToken(
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* profile,
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const LoadTokenCallback& callback) {
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(antrim): use profile->GetPath() once we sure it is safe.
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath profile_dir = ProfileHelper::GetProfilePathByUserIdHash(
512116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      ProfileHelper::Get()->GetUserByProfile(profile)->username_hash());
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PostTaskAndReplyWithResult(
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::BrowserThread::GetBlockingPool(),
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&LoadSyncToken, profile_dir),
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      callback);
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::ConfigureSyncWithToken(
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* profile,
5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& token) {
5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!token.empty())
524f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SupervisedUserServiceFactory::GetForProfile(profile)->InitSync(token);
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace chromeos
528