#include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/threading/sequenced_worker_pool.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/managed/locally_managed_user_constants.h"
+#include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h"
#include "chrome/browser/chromeos/login/user_manager_impl.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/managed_mode/managed_user_service.h"
+#include "chrome/browser/managed_mode/managed_user_service_factory.h"
#include "chromeos/settings/cros_settings_names.h"
#include "content/public/browser/browser_thread.h"
#include "google_apis/gaia/gaia_auth_util.h"
namespace {
+// Names for pref keys in Local State.
// A map from locally managed user local user id to sync user id.
const char kManagedUserSyncId[] =
"ManagedUserSyncId";
const char kLocallyManagedUserCreationTransactionUserId[] =
"LocallyManagedUserCreationTransactionUserId";
+// A map from user id to password schema id.
+const char kSupervisedUserPasswordSchema[] =
+ "SupervisedUserPasswordSchema";
+
+// A map from user id to password salt.
+const char kSupervisedUserPasswordSalt[] =
+ "SupervisedUserPasswordSalt";
+
+// A map from user id to password revision.
+const char kSupervisedUserPasswordRevision[] =
+ "SupervisedUserPasswordRevision";
+
+std::string LoadSyncToken(base::FilePath profile_dir) {
+ std::string token;
+ base::FilePath token_file =
+ profile_dir.Append(chromeos::kManagedUserTokenFilename);
+ VLOG(1) << "Loading" << token_file.value();
+ if (!base::ReadFileToString(token_file, &token))
+ return std::string();
+ return token;
+}
+
} // namespace
namespace chromeos {
+const char kSchemaVersion[] = "SchemaVersion";
+const char kPasswordRevision[] = "PasswordRevision";
+const char kSalt[] = "PasswordSalt";
+const char kEncryptedPassword[] = "EncryptedPassword";
+const char kRequirePasswordUpdate[] = "RequirePasswordUpdate";
+const char kPasswordUpdateFile[] = "password.update";
+const int kMinPasswordRevision = 1;
+
// static
void SupervisedUserManager::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterListPref(kLocallyManagedUsersFirstRun);
registry->RegisterDictionaryPref(kManagedUserManagers);
registry->RegisterDictionaryPref(kManagedUserManagerNames);
registry->RegisterDictionaryPref(kManagedUserManagerDisplayEmails);
+
+ registry->RegisterDictionaryPref(kSupervisedUserPasswordSchema);
+ registry->RegisterDictionaryPref(kSupervisedUserPasswordSalt);
+ registry->RegisterDictionaryPref(kSupervisedUserPasswordRevision);
}
SupervisedUserManagerImpl::SupervisedUserManagerImpl(UserManagerImpl* owner)
cros_settings_(CrosSettings::Get()) {
// SupervisedUserManager instance should be used only on UI thread.
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ authentication_.reset(new SupervisedUserAuthentication(this));
}
SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {
return id;
}
+bool SupervisedUserManagerImpl::HasSupervisedUsers(
+ const std::string& manager_id) const {
+ const UserList& users = owner_->GetUsers();
+ for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
+ if ((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
+ if (manager_id == GetManagerUserId((*it)->email()))
+ return true;
+ }
+ }
+ return false;
+}
+
const User* SupervisedUserManagerImpl::CreateUserRecord(
const std::string& manager_id,
const std::string& local_user_id,
const std::string& sync_user_id,
- const string16& display_name) {
+ const base::string16& display_name) {
const User* user = FindByDisplayName(display_name);
DCHECK(!user);
if (user)
std::string SupervisedUserManagerImpl::GetUserSyncId(const std::string& user_id)
const {
- PrefService* local_state = g_browser_process->local_state();
- const DictionaryValue* sync_ids =
- local_state->GetDictionary(kManagedUserSyncId);
std::string result;
- sync_ids->GetStringWithoutPathExpansion(user_id, &result);
+ GetUserStringValue(user_id, kManagedUserSyncId, &result);
return result;
}
-string16 SupervisedUserManagerImpl::GetManagerDisplayName(
+base::string16 SupervisedUserManagerImpl::GetManagerDisplayName(
const std::string& user_id) const {
PrefService* local_state = g_browser_process->local_state();
- const DictionaryValue* manager_names =
+ const base::DictionaryValue* manager_names =
local_state->GetDictionary(kManagedUserManagerNames);
- string16 result;
+ base::string16 result;
if (manager_names->GetStringWithoutPathExpansion(user_id, &result) &&
!result.empty())
return result;
- return UTF8ToUTF16(GetManagerDisplayEmail(user_id));
+ return base::UTF8ToUTF16(GetManagerDisplayEmail(user_id));
}
std::string SupervisedUserManagerImpl::GetManagerUserId(
const std::string& user_id) const {
- PrefService* local_state = g_browser_process->local_state();
- const DictionaryValue* manager_ids =
- local_state->GetDictionary(kManagedUserManagers);
std::string result;
- manager_ids->GetStringWithoutPathExpansion(user_id, &result);
+ GetUserStringValue(user_id, kManagedUserManagers, &result);
return result;
}
std::string SupervisedUserManagerImpl::GetManagerDisplayEmail(
const std::string& user_id) const {
- PrefService* local_state = g_browser_process->local_state();
- const DictionaryValue* manager_mails =
- local_state->GetDictionary(kManagedUserManagerDisplayEmails);
std::string result;
- if (manager_mails->GetStringWithoutPathExpansion(user_id, &result) &&
- !result.empty()) {
+ if (GetUserStringValue(user_id, kManagedUserManagerDisplayEmails, &result) &&
+ !result.empty())
return result;
- }
return GetManagerUserId(user_id);
}
+void SupervisedUserManagerImpl::GetPasswordInformation(
+ const std::string& user_id,
+ base::DictionaryValue* result) {
+ int value;
+ if (GetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, &value))
+ result->SetIntegerWithoutPathExpansion(kSchemaVersion, value);
+ if (GetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, &value))
+ result->SetIntegerWithoutPathExpansion(kPasswordRevision, value);
+
+ std::string salt;
+ if (GetUserStringValue(user_id, kSupervisedUserPasswordSalt, &salt))
+ result->SetStringWithoutPathExpansion(kSalt, salt);
+}
+
+void SupervisedUserManagerImpl::SetPasswordInformation(
+ const std::string& user_id,
+ const base::DictionaryValue* password_info) {
+ int value;
+ if (password_info->GetIntegerWithoutPathExpansion(kSchemaVersion, &value))
+ SetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, value);
+ if (password_info->GetIntegerWithoutPathExpansion(kPasswordRevision, &value))
+ SetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, value);
+
+ std::string salt;
+ if (password_info->GetStringWithoutPathExpansion(kSalt, &salt))
+ SetUserStringValue(user_id, kSupervisedUserPasswordSalt, salt);
+ g_browser_process->local_state()->CommitPendingWrite();
+}
+
+bool SupervisedUserManagerImpl::GetUserStringValue(
+ const std::string& user_id,
+ const char* key,
+ std::string* out_value) const {
+ PrefService* local_state = g_browser_process->local_state();
+ const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
+ return dictionary->GetStringWithoutPathExpansion(user_id, out_value);
+}
+
+bool SupervisedUserManagerImpl::GetUserIntegerValue(
+ const std::string& user_id,
+ const char* key,
+ int* out_value) const {
+ PrefService* local_state = g_browser_process->local_state();
+ const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
+ return dictionary->GetIntegerWithoutPathExpansion(user_id, out_value);
+}
+
+void SupervisedUserManagerImpl::SetUserStringValue(
+ const std::string& user_id,
+ const char* key,
+ const std::string& value) {
+ PrefService* local_state = g_browser_process->local_state();
+ DictionaryPrefUpdate update(local_state, key);
+ update->SetStringWithoutPathExpansion(user_id, value);
+}
+
+void SupervisedUserManagerImpl::SetUserIntegerValue(
+ const std::string& user_id,
+ const char* key,
+ const int value) {
+ PrefService* local_state = g_browser_process->local_state();
+ DictionaryPrefUpdate update(local_state, key);
+ update->SetIntegerWithoutPathExpansion(user_id, value);
+}
+
const User* SupervisedUserManagerImpl::FindByDisplayName(
- const string16& display_name) const {
+ const base::string16& display_name) const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const UserList& users = owner_->GetUsers();
for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
}
void SupervisedUserManagerImpl::StartCreationTransaction(
- const string16& display_name) {
+ const base::string16& display_name) {
g_browser_process->local_state()->
SetString(kLocallyManagedUserCreationTransactionDisplayName,
UTF16ToASCII(display_name));
if (user_id.empty()) {
// Not much to do - just remove transaction.
prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
+ prefs->CommitPendingWrite();
return;
}
<< user_id << ", will not remove data";
prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
+ prefs->CommitPendingWrite();
return;
}
-
- owner_->RemoveUser(user_id, NULL);
+ owner_->RemoveNonOwnerUserInternal(user_id, NULL);
prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
ListPrefUpdate prefs_new_users_update(prefs, kLocallyManagedUsersFirstRun);
prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
- DictionaryPrefUpdate managers_update(prefs, kManagedUserManagers);
- managers_update->RemoveWithoutPathExpansion(user_id, NULL);
-
- DictionaryPrefUpdate manager_names_update(prefs,
- kManagedUserManagerNames);
- manager_names_update->RemoveWithoutPathExpansion(user_id, NULL);
+ CleanPref(user_id, kManagedUserSyncId);
+ CleanPref(user_id, kManagedUserManagers);
+ CleanPref(user_id, kManagedUserManagerNames);
+ CleanPref(user_id, kManagedUserManagerDisplayEmails);
+ CleanPref(user_id, kSupervisedUserPasswordSalt);
+ CleanPref(user_id, kSupervisedUserPasswordSchema);
+ CleanPref(user_id, kSupervisedUserPasswordRevision);
+}
- DictionaryPrefUpdate manager_emails_update(prefs,
- kManagedUserManagerDisplayEmails);
- manager_emails_update->RemoveWithoutPathExpansion(user_id, NULL);
+void SupervisedUserManagerImpl::CleanPref(const std::string& user_id,
+ const char* key) {
+ PrefService* prefs = g_browser_process->local_state();
+ DictionaryPrefUpdate dict_update(prefs, key);
+ dict_update->RemoveWithoutPathExpansion(user_id, NULL);
}
bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
}
void SupervisedUserManagerImpl::UpdateManagerName(const std::string& manager_id,
- const string16& new_display_name) {
+ const base::string16& new_display_name) {
PrefService* local_state = g_browser_process->local_state();
- const DictionaryValue* manager_ids =
+ const base::DictionaryValue* manager_ids =
local_state->GetDictionary(kManagedUserManagers);
DictionaryPrefUpdate manager_name_update(local_state,
kManagedUserManagerNames);
- for (DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
+ for (base::DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
it.Advance()) {
std::string user_id;
bool has_manager_id = it.value().GetAsString(&user_id);
}
}
+SupervisedUserAuthentication* SupervisedUserManagerImpl::GetAuthentication() {
+ return authentication_.get();
+}
+
+void SupervisedUserManagerImpl::LoadSupervisedUserToken(
+ Profile* profile,
+ const LoadTokenCallback& callback) {
+ // TODO(antrim): use profile->GetPath() once we sure it is safe.
+ base::FilePath profile_dir = ProfileHelper::GetProfilePathByUserIdHash(
+ UserManager::Get()->GetUserByProfile(profile)->username_hash());
+ PostTaskAndReplyWithResult(
+ content::BrowserThread::GetBlockingPool(),
+ FROM_HERE,
+ base::Bind(&LoadSyncToken, profile_dir),
+ callback);
+}
+
+void SupervisedUserManagerImpl::ConfigureSyncWithToken(
+ Profile* profile,
+ const std::string& token) {
+ if (!token.empty())
+ ManagedUserServiceFactory::GetForProfile(profile)->InitSync(token);
+}
} // namespace chromeos