supervised_user_manager_impl.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/login/managed/locally_managed_user_constants.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/user_manager_impl.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"
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chromeos/settings/cros_settings_names.h"
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)using content::BrowserThread;
298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace {
318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Names for pref keys in Local State.
338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A map from locally managed user local user id to sync user id.
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const char kSupervisedUserSyncId[] =
358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "ManagedUserSyncId";
368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A map from locally managed user id to manager user id.
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const char kSupervisedUserManagers[] =
398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "ManagedUserManagers";
408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A map from locally managed user id to manager display name.
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const char kSupervisedUserManagerNames[] =
438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "ManagedUserManagerNames";
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A map from locally managed user id to manager display e-mail.
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const char kSupervisedUserManagerDisplayEmails[] =
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "ManagedUserManagerDisplayEmails";
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A vector pref of the locally managed accounts defined on this device, that
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// had not logged in yet.
518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kLocallyManagedUsersFirstRun[] = "LocallyManagedUsersFirstRun";
528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A pref of the next id for locally managed users generation.
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kLocallyManagedUsersNextId[] =
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "LocallyManagedUsersNextId";
568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A pref of the next id for locally managed users generation.
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kLocallyManagedUserCreationTransactionDisplayName[] =
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "LocallyManagedUserCreationTransactionDisplayName";
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// A pref of the next id for locally managed users generation.
628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kLocallyManagedUserCreationTransactionUserId[] =
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    "LocallyManagedUserCreationTransactionUserId";
648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A map from user id to password schema id.
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSupervisedUserPasswordSchema[] =
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "SupervisedUserPasswordSchema";
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A map from user id to password salt.
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSupervisedUserPasswordSalt[] =
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "SupervisedUserPasswordSalt";
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A map from user id to password revision.
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSupervisedUserPasswordRevision[] =
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "SupervisedUserPasswordRevision";
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// A map from user id to flag indicating if password should be updated upon
78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// signin.
79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kSupervisedUserNeedPasswordUpdate[] =
80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    "SupervisedUserNeedPasswordUpdate";
81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// A map from user id to flag indicating if cryptohome does not have signature
83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// key.
84c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char kSupervisedUserIncompleteKey[] = "SupervisedUserHasIncompleteKey";
85c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string LoadSyncToken(base::FilePath profile_dir) {
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string token;
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath token_file =
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      profile_dir.Append(chromeos::kSupervisedUserTokenFilename);
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VLOG(1) << "Loading" << token_file.value();
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!base::ReadFileToString(token_file, &token))
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return std::string();
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return token;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace chromeos {
998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSchemaVersion[] = "SchemaVersion";
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kPasswordRevision[] = "PasswordRevision";
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSalt[] = "PasswordSalt";
10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const char kPasswordSignature[] = "PasswordSignature";
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kEncryptedPassword[] = "EncryptedPassword";
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kRequirePasswordUpdate[] = "RequirePasswordUpdate";
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char kHasIncompleteKey[] = "HasIncompleteKey";
10723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const char kPasswordEncryptionKey[] = "password.hmac.encryption";
10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const char kPasswordSignatureKey[] = "password.hmac.signature";
10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kPasswordUpdateFile[] = "password.update";
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kMinPasswordRevision = 1;
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// static
1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManager::RegisterPrefs(PrefRegistrySimple* registry) {
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  registry->RegisterListPref(kLocallyManagedUsersFirstRun);
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  registry->RegisterIntegerPref(kLocallyManagedUsersNextId, 0);
1178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  registry->RegisterStringPref(
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      kLocallyManagedUserCreationTransactionDisplayName, "");
1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  registry->RegisterStringPref(
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      kLocallyManagedUserCreationTransactionUserId, "");
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserSyncId);
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserManagers);
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserManagerNames);
124f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserManagerDisplayEmails);
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserPasswordSchema);
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserPasswordSalt);
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  registry->RegisterDictionaryPref(kSupervisedUserPasswordRevision);
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  registry->RegisterDictionaryPref(kSupervisedUserNeedPasswordUpdate);
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  registry->RegisterDictionaryPref(kSupervisedUserIncompleteKey);
1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SupervisedUserManagerImpl::SupervisedUserManagerImpl(UserManagerImpl* owner)
1358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    : owner_(owner),
1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      cros_settings_(CrosSettings::Get()) {
1378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // SupervisedUserManager instance should be used only on UI thread.
1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  authentication_.reset(new SupervisedUserAuthentication(this));
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {
1438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string SupervisedUserManagerImpl::GenerateUserId() {
1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int counter = g_browser_process->local_state()->
1478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetInteger(kLocallyManagedUsersNextId);
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string id;
1498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool user_exists;
1508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  do {
1518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    id = base::StringPrintf("%d@%s", counter,
1528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        UserManager::kLocallyManagedUserDomain);
1538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    counter++;
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    user_exists = (NULL != owner_->FindUser(id));
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DCHECK(!user_exists);
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (user_exists) {
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      LOG(ERROR) << "Supervised user with id " << id << " already exists.";
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  } while (user_exists);
1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      SetInteger(kLocallyManagedUsersNextId, counter);
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return id;
1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SupervisedUserManagerImpl::HasSupervisedUsers(
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const std::string& manager_id) const {
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const UserList& users = owner_->GetUsers();
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if ((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (manager_id == GetManagerUserId((*it)->email()))
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return true;
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const User* SupervisedUserManagerImpl::CreateUserRecord(
1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& manager_id,
1828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& local_user_id,
1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& sync_user_id,
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& display_name) {
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const User* user = FindByDisplayName(display_name);
1868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(!user);
1878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (user)
1888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return user;
1898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const User* manager = owner_->FindUser(manager_id);
1908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  CHECK(manager);
1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  User* new_user = User::CreateLocallyManagedUser(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,
1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                        kLocallyManagedUsersFirstRun);
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
3578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const User* SupervisedUserManagerImpl::FindByDisplayName(
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& display_name) const {
3598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const UserList& users = owner_->GetUsers();
3618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
3628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
3638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        ((*it)->display_name() == display_name)) {
3648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return *it;
3658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
3668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return NULL;
3688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const User* SupervisedUserManagerImpl::FindBySyncId(
3718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& sync_id) const {
3728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  const UserList& users = owner_->GetUsers();
3748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
3758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
3768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        (GetUserSyncId((*it)->email()) == sync_id)) {
3778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return *it;
3788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
3798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
3808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return NULL;
3818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::StartCreationTransaction(
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& display_name) {
3858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
3868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      SetString(kLocallyManagedUserCreationTransactionDisplayName,
387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                base::UTF16ToASCII(display_name));
3888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
3898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::SetCreationTransactionUserId(
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& email) {
3938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      SetString(kLocallyManagedUserCreationTransactionUserId,
3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                email);
3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
3988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
3998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::CommitCreationTransaction() {
4008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
4028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->
4038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ClearPref(kLocallyManagedUserCreationTransactionUserId);
4048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  g_browser_process->local_state()->CommitPendingWrite();
4058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SupervisedUserManagerImpl::HasFailedUserCreationTransaction() {
4088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return !(g_browser_process->local_state()->
4098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               GetString(kLocallyManagedUserCreationTransactionDisplayName).
4108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                   empty());
4118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::RollbackUserCreationTransaction() {
4148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string display_name = prefs->
4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetString(kLocallyManagedUserCreationTransactionDisplayName);
4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::string user_id = prefs->
4198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      GetString(kLocallyManagedUserCreationTransactionUserId);
4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  LOG(WARNING) << "Cleaning up transaction for "
4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)               << display_name << "/" << user_id;
4238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (user_id.empty()) {
4258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    // Not much to do - just remove transaction.
4268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    prefs->CommitPendingWrite();
4288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (gaia::ExtractDomainName(user_id) !=
4328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          UserManager::kLocallyManagedUserDomain) {
4338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    LOG(WARNING) << "Clean up transaction for  non-locally managed user found :"
4348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                 << user_id << ", will not remove data";
4358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
4368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    prefs->CommitPendingWrite();
4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return;
4398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  owner_->RemoveNonOwnerUserInternal(user_id, NULL);
4418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
4438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
4448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs->CommitPendingWrite();
4458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::RemoveNonCryptohomeData(
4488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const std::string& user_id) {
4498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
4508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ListPrefUpdate prefs_new_users_update(prefs, kLocallyManagedUsersFirstRun);
4518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
4528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserSyncId);
454f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserManagers);
455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserManagerNames);
456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserManagerDisplayEmails);
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserPasswordSalt);
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserPasswordSchema);
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CleanPref(user_id, kSupervisedUserPasswordRevision);
460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  CleanPref(user_id, kSupervisedUserNeedPasswordUpdate);
461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  CleanPref(user_id, kSupervisedUserIncompleteKey);
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::CleanPref(const std::string& user_id,
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          const char* key) {
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DictionaryPrefUpdate dict_update(prefs, key);
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  dict_update->RemoveWithoutPathExpansion(user_id, NULL);
4698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
4728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ListPrefUpdate prefs_new_users_update(g_browser_process->local_state(),
4738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                        kLocallyManagedUsersFirstRun);
4748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
4758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SupervisedUserManagerImpl::UpdateManagerName(const std::string& manager_id,
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::string16& new_display_name) {
4798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
4808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::DictionaryValue* manager_ids =
482f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      local_state->GetDictionary(kSupervisedUserManagers);
4838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  DictionaryPrefUpdate manager_name_update(local_state,
485f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           kSupervisedUserManagerNames);
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (base::DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
4878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      it.Advance()) {
4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    std::string user_id;
4898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    bool has_manager_id = it.value().GetAsString(&user_id);
4908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    DCHECK(has_manager_id);
4918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (user_id == manager_id) {
4928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      manager_name_update->SetWithoutPathExpansion(
4938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          it.key(),
4948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          new base::StringValue(new_display_name));
4958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    }
4968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
4978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SupervisedUserAuthentication* SupervisedUserManagerImpl::GetAuthentication() {
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return authentication_.get();
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::LoadSupervisedUserToken(
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* profile,
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const LoadTokenCallback& callback) {
5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // TODO(antrim): use profile->GetPath() once we sure it is safe.
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath profile_dir = ProfileHelper::GetProfilePathByUserIdHash(
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      UserManager::Get()->GetUserByProfile(profile)->username_hash());
5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PostTaskAndReplyWithResult(
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      content::BrowserThread::GetBlockingPool(),
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&LoadSyncToken, profile_dir),
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      callback);
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SupervisedUserManagerImpl::ConfigureSyncWithToken(
5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    Profile* profile,
5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& token) {
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!token.empty())
520f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SupervisedUserServiceFactory::GetForProfile(profile)->InitSync(token);
5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}  // namespace chromeos
524