Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / supervised_user_manager_impl.cc
blob15132ea3abba57ed8935ec44f18b2832be45d01a
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
7 #include "base/prefs/pref_registry_simple.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/prefs/scoped_user_pref_update.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h"
16 #include "chrome/browser/chromeos/login/user_manager_impl.h"
17 #include "chromeos/settings/cros_settings_names.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "google_apis/gaia/gaia_auth_util.h"
21 using content::BrowserThread;
23 namespace {
25 // Names for pref keys in Local State.
26 // A map from locally managed user local user id to sync user id.
27 const char kManagedUserSyncId[] =
28 "ManagedUserSyncId";
30 // A map from locally managed user id to manager user id.
31 const char kManagedUserManagers[] =
32 "ManagedUserManagers";
34 // A map from locally managed user id to manager display name.
35 const char kManagedUserManagerNames[] =
36 "ManagedUserManagerNames";
38 // A map from locally managed user id to manager display e-mail.
39 const char kManagedUserManagerDisplayEmails[] =
40 "ManagedUserManagerDisplayEmails";
42 // A vector pref of the locally managed accounts defined on this device, that
43 // had not logged in yet.
44 const char kLocallyManagedUsersFirstRun[] = "LocallyManagedUsersFirstRun";
46 // A pref of the next id for locally managed users generation.
47 const char kLocallyManagedUsersNextId[] =
48 "LocallyManagedUsersNextId";
50 // A pref of the next id for locally managed users generation.
51 const char kLocallyManagedUserCreationTransactionDisplayName[] =
52 "LocallyManagedUserCreationTransactionDisplayName";
54 // A pref of the next id for locally managed users generation.
55 const char kLocallyManagedUserCreationTransactionUserId[] =
56 "LocallyManagedUserCreationTransactionUserId";
58 // A map from user id to password schema id.
59 const char kSupervisedUserPasswordSchema[] =
60 "SupervisedUserPasswordSchema";
62 // A map from user id to password salt.
63 const char kSupervisedUserPasswordSalt[] =
64 "SupervisedUserPasswordSalt";
66 // A map from user id to password revision.
67 const char kSupervisedUserPasswordRevision[] =
68 "SupervisedUserPasswordRevision";
70 } // namespace
72 namespace chromeos {
74 const char kSchemaVersion[] = "SchemaVersion";
75 const char kPasswordRevision[] = "PasswordRevision";
76 const char kSalt[] = "PasswordSalt";
77 const char kEncryptedPassword[] = "EncryptedPassword";
78 const int kMinPasswordRevision = 1;
80 // static
81 void SupervisedUserManager::RegisterPrefs(PrefRegistrySimple* registry) {
82 registry->RegisterListPref(kLocallyManagedUsersFirstRun);
83 registry->RegisterIntegerPref(kLocallyManagedUsersNextId, 0);
84 registry->RegisterStringPref(
85 kLocallyManagedUserCreationTransactionDisplayName, "");
86 registry->RegisterStringPref(
87 kLocallyManagedUserCreationTransactionUserId, "");
88 registry->RegisterDictionaryPref(kManagedUserSyncId);
89 registry->RegisterDictionaryPref(kManagedUserManagers);
90 registry->RegisterDictionaryPref(kManagedUserManagerNames);
91 registry->RegisterDictionaryPref(kManagedUserManagerDisplayEmails);
93 registry->RegisterDictionaryPref(kSupervisedUserPasswordSchema);
94 registry->RegisterDictionaryPref(kSupervisedUserPasswordSalt);
95 registry->RegisterDictionaryPref(kSupervisedUserPasswordRevision);
98 SupervisedUserManagerImpl::SupervisedUserManagerImpl(UserManagerImpl* owner)
99 : owner_(owner),
100 cros_settings_(CrosSettings::Get()) {
101 // SupervisedUserManager instance should be used only on UI thread.
102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
103 authentication_.reset(new SupervisedUserAuthentication(this));
106 SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {
109 std::string SupervisedUserManagerImpl::GenerateUserId() {
110 int counter = g_browser_process->local_state()->
111 GetInteger(kLocallyManagedUsersNextId);
112 std::string id;
113 bool user_exists;
114 do {
115 id = base::StringPrintf("%d@%s", counter,
116 UserManager::kLocallyManagedUserDomain);
117 counter++;
118 user_exists = (NULL != owner_->FindUser(id));
119 DCHECK(!user_exists);
120 if (user_exists) {
121 LOG(ERROR) << "Supervised user with id " << id << " already exists.";
123 } while (user_exists);
125 g_browser_process->local_state()->
126 SetInteger(kLocallyManagedUsersNextId, counter);
128 g_browser_process->local_state()->CommitPendingWrite();
129 return id;
132 const User* SupervisedUserManagerImpl::CreateUserRecord(
133 const std::string& manager_id,
134 const std::string& local_user_id,
135 const std::string& sync_user_id,
136 const base::string16& display_name) {
137 const User* user = FindByDisplayName(display_name);
138 DCHECK(!user);
139 if (user)
140 return user;
141 const User* manager = owner_->FindUser(manager_id);
142 CHECK(manager);
144 PrefService* local_state = g_browser_process->local_state();
146 User* new_user = User::CreateLocallyManagedUser(local_user_id);
148 owner_->AddUserRecord(new_user);
150 ListPrefUpdate prefs_new_users_update(local_state,
151 kLocallyManagedUsersFirstRun);
152 DictionaryPrefUpdate sync_id_update(local_state, kManagedUserSyncId);
153 DictionaryPrefUpdate manager_update(local_state, kManagedUserManagers);
154 DictionaryPrefUpdate manager_name_update(local_state,
155 kManagedUserManagerNames);
156 DictionaryPrefUpdate manager_email_update(local_state,
157 kManagedUserManagerDisplayEmails);
159 prefs_new_users_update->Insert(0, new base::StringValue(local_user_id));
161 sync_id_update->SetWithoutPathExpansion(local_user_id,
162 new base::StringValue(sync_user_id));
163 manager_update->SetWithoutPathExpansion(local_user_id,
164 new base::StringValue(manager->email()));
165 manager_name_update->SetWithoutPathExpansion(local_user_id,
166 new base::StringValue(manager->GetDisplayName()));
167 manager_email_update->SetWithoutPathExpansion(local_user_id,
168 new base::StringValue(manager->display_email()));
170 owner_->SaveUserDisplayName(local_user_id, display_name);
172 g_browser_process->local_state()->CommitPendingWrite();
173 return new_user;
176 std::string SupervisedUserManagerImpl::GetUserSyncId(const std::string& user_id)
177 const {
178 std::string result;
179 GetUserStringValue(user_id, kManagedUserSyncId, &result);
180 return result;
183 base::string16 SupervisedUserManagerImpl::GetManagerDisplayName(
184 const std::string& user_id) const {
185 PrefService* local_state = g_browser_process->local_state();
186 const base::DictionaryValue* manager_names =
187 local_state->GetDictionary(kManagedUserManagerNames);
188 base::string16 result;
189 if (manager_names->GetStringWithoutPathExpansion(user_id, &result) &&
190 !result.empty())
191 return result;
192 return base::UTF8ToUTF16(GetManagerDisplayEmail(user_id));
195 std::string SupervisedUserManagerImpl::GetManagerUserId(
196 const std::string& user_id) const {
197 std::string result;
198 GetUserStringValue(user_id, kManagedUserManagers, &result);
199 return result;
202 std::string SupervisedUserManagerImpl::GetManagerDisplayEmail(
203 const std::string& user_id) const {
204 std::string result;
205 if (GetUserStringValue(user_id, kManagedUserManagerDisplayEmails, &result) &&
206 !result.empty())
207 return result;
208 return GetManagerUserId(user_id);
211 void SupervisedUserManagerImpl::GetPasswordInformation(
212 const std::string& user_id,
213 base::DictionaryValue* result) {
214 int value;
215 if (GetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, &value))
216 result->SetIntegerWithoutPathExpansion(kSchemaVersion, value);
217 if (GetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, &value))
218 result->SetIntegerWithoutPathExpansion(kPasswordRevision, value);
220 std::string salt;
221 if (GetUserStringValue(user_id, kSupervisedUserPasswordSalt, &salt))
222 result->SetStringWithoutPathExpansion(kSalt, salt);
225 void SupervisedUserManagerImpl::SetPasswordInformation(
226 const std::string& user_id,
227 const base::DictionaryValue* password_info) {
228 int value;
229 if (password_info->GetIntegerWithoutPathExpansion(kSchemaVersion, &value))
230 SetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, value);
231 if (password_info->GetIntegerWithoutPathExpansion(kPasswordRevision, &value))
232 SetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, value);
234 std::string salt;
235 if (password_info->GetStringWithoutPathExpansion(kSalt, &salt))
236 SetUserStringValue(user_id, kSupervisedUserPasswordSalt, salt);
237 g_browser_process->local_state()->CommitPendingWrite();
240 bool SupervisedUserManagerImpl::GetUserStringValue(
241 const std::string& user_id,
242 const char* key,
243 std::string* out_value) const {
244 PrefService* local_state = g_browser_process->local_state();
245 const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
246 return dictionary->GetStringWithoutPathExpansion(user_id, out_value);
249 bool SupervisedUserManagerImpl::GetUserIntegerValue(
250 const std::string& user_id,
251 const char* key,
252 int* out_value) const {
253 PrefService* local_state = g_browser_process->local_state();
254 const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
255 return dictionary->GetIntegerWithoutPathExpansion(user_id, out_value);
258 void SupervisedUserManagerImpl::SetUserStringValue(
259 const std::string& user_id,
260 const char* key,
261 const std::string& value) {
262 PrefService* local_state = g_browser_process->local_state();
263 DictionaryPrefUpdate update(local_state, key);
264 update->SetStringWithoutPathExpansion(user_id, value);
267 void SupervisedUserManagerImpl::SetUserIntegerValue(
268 const std::string& user_id,
269 const char* key,
270 const int value) {
271 PrefService* local_state = g_browser_process->local_state();
272 DictionaryPrefUpdate update(local_state, key);
273 update->SetIntegerWithoutPathExpansion(user_id, value);
276 const User* SupervisedUserManagerImpl::FindByDisplayName(
277 const base::string16& display_name) const {
278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
279 const UserList& users = owner_->GetUsers();
280 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
281 if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
282 ((*it)->display_name() == display_name)) {
283 return *it;
286 return NULL;
289 const User* SupervisedUserManagerImpl::FindBySyncId(
290 const std::string& sync_id) const {
291 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
292 const UserList& users = owner_->GetUsers();
293 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
294 if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
295 (GetUserSyncId((*it)->email()) == sync_id)) {
296 return *it;
299 return NULL;
302 void SupervisedUserManagerImpl::StartCreationTransaction(
303 const base::string16& display_name) {
304 g_browser_process->local_state()->
305 SetString(kLocallyManagedUserCreationTransactionDisplayName,
306 UTF16ToASCII(display_name));
307 g_browser_process->local_state()->CommitPendingWrite();
310 void SupervisedUserManagerImpl::SetCreationTransactionUserId(
311 const std::string& email) {
312 g_browser_process->local_state()->
313 SetString(kLocallyManagedUserCreationTransactionUserId,
314 email);
315 g_browser_process->local_state()->CommitPendingWrite();
318 void SupervisedUserManagerImpl::CommitCreationTransaction() {
319 g_browser_process->local_state()->
320 ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
321 g_browser_process->local_state()->
322 ClearPref(kLocallyManagedUserCreationTransactionUserId);
323 g_browser_process->local_state()->CommitPendingWrite();
326 bool SupervisedUserManagerImpl::HasFailedUserCreationTransaction() {
327 return !(g_browser_process->local_state()->
328 GetString(kLocallyManagedUserCreationTransactionDisplayName).
329 empty());
332 void SupervisedUserManagerImpl::RollbackUserCreationTransaction() {
333 PrefService* prefs = g_browser_process->local_state();
335 std::string display_name = prefs->
336 GetString(kLocallyManagedUserCreationTransactionDisplayName);
337 std::string user_id = prefs->
338 GetString(kLocallyManagedUserCreationTransactionUserId);
340 LOG(WARNING) << "Cleaning up transaction for "
341 << display_name << "/" << user_id;
343 if (user_id.empty()) {
344 // Not much to do - just remove transaction.
345 prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
346 prefs->CommitPendingWrite();
347 return;
350 if (gaia::ExtractDomainName(user_id) !=
351 UserManager::kLocallyManagedUserDomain) {
352 LOG(WARNING) << "Clean up transaction for non-locally managed user found :"
353 << user_id << ", will not remove data";
354 prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
355 prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
356 prefs->CommitPendingWrite();
357 return;
359 owner_->RemoveNonOwnerUserInternal(user_id, NULL);
361 prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
362 prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
363 prefs->CommitPendingWrite();
366 void SupervisedUserManagerImpl::RemoveNonCryptohomeData(
367 const std::string& user_id) {
368 PrefService* prefs = g_browser_process->local_state();
369 ListPrefUpdate prefs_new_users_update(prefs, kLocallyManagedUsersFirstRun);
370 prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
372 CleanPref(user_id, kManagedUserSyncId);
373 CleanPref(user_id, kManagedUserManagers);
374 CleanPref(user_id, kManagedUserManagerNames);
375 CleanPref(user_id, kManagedUserManagerDisplayEmails);
376 CleanPref(user_id, kSupervisedUserPasswordSalt);
377 CleanPref(user_id, kSupervisedUserPasswordSchema);
378 CleanPref(user_id, kSupervisedUserPasswordRevision);
381 void SupervisedUserManagerImpl::CleanPref(const std::string& user_id,
382 const char* key) {
383 PrefService* prefs = g_browser_process->local_state();
384 DictionaryPrefUpdate dict_update(prefs, key);
385 dict_update->RemoveWithoutPathExpansion(user_id, NULL);
388 bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
389 ListPrefUpdate prefs_new_users_update(g_browser_process->local_state(),
390 kLocallyManagedUsersFirstRun);
391 return prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
394 void SupervisedUserManagerImpl::UpdateManagerName(const std::string& manager_id,
395 const base::string16& new_display_name) {
396 PrefService* local_state = g_browser_process->local_state();
398 const base::DictionaryValue* manager_ids =
399 local_state->GetDictionary(kManagedUserManagers);
401 DictionaryPrefUpdate manager_name_update(local_state,
402 kManagedUserManagerNames);
403 for (base::DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
404 it.Advance()) {
405 std::string user_id;
406 bool has_manager_id = it.value().GetAsString(&user_id);
407 DCHECK(has_manager_id);
408 if (user_id == manager_id) {
409 manager_name_update->SetWithoutPathExpansion(
410 it.key(),
411 new base::StringValue(new_display_name));
416 SupervisedUserAuthentication* SupervisedUserManagerImpl::GetAuthentication() {
417 return authentication_.get();
420 } // namespace chromeos