Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / supervised_user_manager_impl.cc
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.
4
5 #include "chrome/browser/chromeos/login/supervised_user_manager_impl.h"
6
7 #include "base/file_util.h"
8 #include "base/files/file_path.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/prefs/scoped_user_pref_update.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/threading/sequenced_worker_pool.h"
16 #include "base/values.h"
17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/chromeos/login/managed/locally_managed_user_constants.h"
19 #include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h"
20 #include "chrome/browser/chromeos/login/user_manager_impl.h"
21 #include "chrome/browser/chromeos/profiles/profile_helper.h"
22 #include "chrome/browser/managed_mode/managed_user_service.h"
23 #include "chrome/browser/managed_mode/managed_user_service_factory.h"
24 #include "chromeos/settings/cros_settings_names.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "google_apis/gaia/gaia_auth_util.h"
27
28 using content::BrowserThread;
29
30 namespace {
31
32 // Names for pref keys in Local State.
33 // A map from locally managed user local user id to sync user id.
34 const char kManagedUserSyncId[] =
35     "ManagedUserSyncId";
36
37 // A map from locally managed user id to manager user id.
38 const char kManagedUserManagers[] =
39     "ManagedUserManagers";
40
41 // A map from locally managed user id to manager display name.
42 const char kManagedUserManagerNames[] =
43     "ManagedUserManagerNames";
44
45 // A map from locally managed user id to manager display e-mail.
46 const char kManagedUserManagerDisplayEmails[] =
47     "ManagedUserManagerDisplayEmails";
48
49 // A vector pref of the locally managed accounts defined on this device, that
50 // had not logged in yet.
51 const char kLocallyManagedUsersFirstRun[] = "LocallyManagedUsersFirstRun";
52
53 // A pref of the next id for locally managed users generation.
54 const char kLocallyManagedUsersNextId[] =
55     "LocallyManagedUsersNextId";
56
57 // A pref of the next id for locally managed users generation.
58 const char kLocallyManagedUserCreationTransactionDisplayName[] =
59     "LocallyManagedUserCreationTransactionDisplayName";
60
61 // A pref of the next id for locally managed users generation.
62 const char kLocallyManagedUserCreationTransactionUserId[] =
63     "LocallyManagedUserCreationTransactionUserId";
64
65 // A map from user id to password schema id.
66 const char kSupervisedUserPasswordSchema[] =
67     "SupervisedUserPasswordSchema";
68
69 // A map from user id to password salt.
70 const char kSupervisedUserPasswordSalt[] =
71     "SupervisedUserPasswordSalt";
72
73 // A map from user id to password revision.
74 const char kSupervisedUserPasswordRevision[] =
75     "SupervisedUserPasswordRevision";
76
77 // A map from user id to flag indicating if password should be updated upon
78 // signin.
79 const char kSupervisedUserNeedPasswordUpdate[] =
80     "SupervisedUserNeedPasswordUpdate";
81
82 // A map from user id to flag indicating if cryptohome does not have signature
83 // key.
84 const char kSupervisedUserIncompleteKey[] = "SupervisedUserHasIncompleteKey";
85
86 std::string LoadSyncToken(base::FilePath profile_dir) {
87   std::string token;
88   base::FilePath token_file =
89       profile_dir.Append(chromeos::kManagedUserTokenFilename);
90   VLOG(1) << "Loading" << token_file.value();
91   if (!base::ReadFileToString(token_file, &token))
92     return std::string();
93   return token;
94 }
95
96 } // namespace
97
98 namespace chromeos {
99
100 const char kSchemaVersion[] = "SchemaVersion";
101 const char kPasswordRevision[] = "PasswordRevision";
102 const char kSalt[] = "PasswordSalt";
103 const char kPasswordSignature[] = "PasswordSignature";
104 const char kEncryptedPassword[] = "EncryptedPassword";
105 const char kRequirePasswordUpdate[] = "RequirePasswordUpdate";
106 const char kHasIncompleteKey[] = "HasIncompleteKey";
107 const char kPasswordEncryptionKey[] = "password.hmac.encryption";
108 const char kPasswordSignatureKey[] = "password.hmac.signature";
109
110 const char kPasswordUpdateFile[] = "password.update";
111 const int kMinPasswordRevision = 1;
112
113 // static
114 void SupervisedUserManager::RegisterPrefs(PrefRegistrySimple* registry) {
115   registry->RegisterListPref(kLocallyManagedUsersFirstRun);
116   registry->RegisterIntegerPref(kLocallyManagedUsersNextId, 0);
117   registry->RegisterStringPref(
118       kLocallyManagedUserCreationTransactionDisplayName, "");
119   registry->RegisterStringPref(
120       kLocallyManagedUserCreationTransactionUserId, "");
121   registry->RegisterDictionaryPref(kManagedUserSyncId);
122   registry->RegisterDictionaryPref(kManagedUserManagers);
123   registry->RegisterDictionaryPref(kManagedUserManagerNames);
124   registry->RegisterDictionaryPref(kManagedUserManagerDisplayEmails);
125
126   registry->RegisterDictionaryPref(kSupervisedUserPasswordSchema);
127   registry->RegisterDictionaryPref(kSupervisedUserPasswordSalt);
128   registry->RegisterDictionaryPref(kSupervisedUserPasswordRevision);
129
130   registry->RegisterDictionaryPref(kSupervisedUserNeedPasswordUpdate);
131   registry->RegisterDictionaryPref(kSupervisedUserIncompleteKey);
132 }
133
134 SupervisedUserManagerImpl::SupervisedUserManagerImpl(UserManagerImpl* owner)
135     : owner_(owner),
136       cros_settings_(CrosSettings::Get()) {
137   // SupervisedUserManager instance should be used only on UI thread.
138   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
139   authentication_.reset(new SupervisedUserAuthentication(this));
140 }
141
142 SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {
143 }
144
145 std::string SupervisedUserManagerImpl::GenerateUserId() {
146   int counter = g_browser_process->local_state()->
147       GetInteger(kLocallyManagedUsersNextId);
148   std::string id;
149   bool user_exists;
150   do {
151     id = base::StringPrintf("%d@%s", counter,
152         UserManager::kLocallyManagedUserDomain);
153     counter++;
154     user_exists = (NULL != owner_->FindUser(id));
155     DCHECK(!user_exists);
156     if (user_exists) {
157       LOG(ERROR) << "Supervised user with id " << id << " already exists.";
158     }
159   } while (user_exists);
160
161   g_browser_process->local_state()->
162       SetInteger(kLocallyManagedUsersNextId, counter);
163
164   g_browser_process->local_state()->CommitPendingWrite();
165   return id;
166 }
167
168 bool SupervisedUserManagerImpl::HasSupervisedUsers(
169       const std::string& manager_id) const {
170   const UserList& users = owner_->GetUsers();
171   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
172     if ((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
173       if (manager_id == GetManagerUserId((*it)->email()))
174         return true;
175     }
176   }
177   return false;
178 }
179
180 const User* SupervisedUserManagerImpl::CreateUserRecord(
181       const std::string& manager_id,
182       const std::string& local_user_id,
183       const std::string& sync_user_id,
184       const base::string16& display_name) {
185   const User* user = FindByDisplayName(display_name);
186   DCHECK(!user);
187   if (user)
188     return user;
189   const User* manager = owner_->FindUser(manager_id);
190   CHECK(manager);
191
192   PrefService* local_state = g_browser_process->local_state();
193
194   User* new_user = User::CreateLocallyManagedUser(local_user_id);
195
196   owner_->AddUserRecord(new_user);
197
198   ListPrefUpdate prefs_new_users_update(local_state,
199                                         kLocallyManagedUsersFirstRun);
200   DictionaryPrefUpdate sync_id_update(local_state, kManagedUserSyncId);
201   DictionaryPrefUpdate manager_update(local_state, kManagedUserManagers);
202   DictionaryPrefUpdate manager_name_update(local_state,
203                                            kManagedUserManagerNames);
204   DictionaryPrefUpdate manager_email_update(local_state,
205                                             kManagedUserManagerDisplayEmails);
206
207   prefs_new_users_update->Insert(0, new base::StringValue(local_user_id));
208
209   sync_id_update->SetWithoutPathExpansion(local_user_id,
210       new base::StringValue(sync_user_id));
211   manager_update->SetWithoutPathExpansion(local_user_id,
212       new base::StringValue(manager->email()));
213   manager_name_update->SetWithoutPathExpansion(local_user_id,
214       new base::StringValue(manager->GetDisplayName()));
215   manager_email_update->SetWithoutPathExpansion(local_user_id,
216       new base::StringValue(manager->display_email()));
217
218   owner_->SaveUserDisplayName(local_user_id, display_name);
219
220   g_browser_process->local_state()->CommitPendingWrite();
221   return new_user;
222 }
223
224 std::string SupervisedUserManagerImpl::GetUserSyncId(const std::string& user_id)
225     const {
226   std::string result;
227   GetUserStringValue(user_id, kManagedUserSyncId, &result);
228   return result;
229 }
230
231 base::string16 SupervisedUserManagerImpl::GetManagerDisplayName(
232     const std::string& user_id) const {
233   PrefService* local_state = g_browser_process->local_state();
234   const base::DictionaryValue* manager_names =
235       local_state->GetDictionary(kManagedUserManagerNames);
236   base::string16 result;
237   if (manager_names->GetStringWithoutPathExpansion(user_id, &result) &&
238       !result.empty())
239     return result;
240   return base::UTF8ToUTF16(GetManagerDisplayEmail(user_id));
241 }
242
243 std::string SupervisedUserManagerImpl::GetManagerUserId(
244       const std::string& user_id) const {
245   std::string result;
246   GetUserStringValue(user_id, kManagedUserManagers, &result);
247   return result;
248 }
249
250 std::string SupervisedUserManagerImpl::GetManagerDisplayEmail(
251       const std::string& user_id) const {
252   std::string result;
253   if (GetUserStringValue(user_id, kManagedUserManagerDisplayEmails, &result) &&
254       !result.empty())
255     return result;
256   return GetManagerUserId(user_id);
257 }
258
259 void SupervisedUserManagerImpl::GetPasswordInformation(
260     const std::string& user_id,
261     base::DictionaryValue* result) {
262   int value;
263   if (GetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, &value))
264     result->SetIntegerWithoutPathExpansion(kSchemaVersion, value);
265   if (GetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, &value))
266     result->SetIntegerWithoutPathExpansion(kPasswordRevision, value);
267
268   bool flag;
269   if (GetUserBooleanValue(user_id, kSupervisedUserNeedPasswordUpdate, &flag))
270     result->SetBooleanWithoutPathExpansion(kRequirePasswordUpdate, flag);
271   if (GetUserBooleanValue(user_id, kSupervisedUserIncompleteKey, &flag))
272     result->SetBooleanWithoutPathExpansion(kHasIncompleteKey, flag);
273
274   std::string salt;
275   if (GetUserStringValue(user_id, kSupervisedUserPasswordSalt, &salt))
276     result->SetStringWithoutPathExpansion(kSalt, salt);
277 }
278
279 void SupervisedUserManagerImpl::SetPasswordInformation(
280       const std::string& user_id,
281       const base::DictionaryValue* password_info) {
282   int value;
283   if (password_info->GetIntegerWithoutPathExpansion(kSchemaVersion, &value))
284     SetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, value);
285   if (password_info->GetIntegerWithoutPathExpansion(kPasswordRevision, &value))
286     SetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, value);
287
288   bool flag;
289   if (password_info->GetBooleanWithoutPathExpansion(kRequirePasswordUpdate,
290                                                     &flag)) {
291     SetUserBooleanValue(user_id, kSupervisedUserNeedPasswordUpdate, flag);
292   }
293   if (password_info->GetBooleanWithoutPathExpansion(kHasIncompleteKey, &flag))
294     SetUserBooleanValue(user_id, kSupervisedUserIncompleteKey, flag);
295
296   std::string salt;
297   if (password_info->GetStringWithoutPathExpansion(kSalt, &salt))
298     SetUserStringValue(user_id, kSupervisedUserPasswordSalt, salt);
299   g_browser_process->local_state()->CommitPendingWrite();
300 }
301
302 bool SupervisedUserManagerImpl::GetUserStringValue(
303     const std::string& user_id,
304     const char* key,
305     std::string* out_value) const {
306   PrefService* local_state = g_browser_process->local_state();
307   const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
308   return dictionary->GetStringWithoutPathExpansion(user_id, out_value);
309 }
310
311 bool SupervisedUserManagerImpl::GetUserIntegerValue(
312     const std::string& user_id,
313     const char* key,
314     int* out_value) const {
315   PrefService* local_state = g_browser_process->local_state();
316   const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
317   return dictionary->GetIntegerWithoutPathExpansion(user_id, out_value);
318 }
319
320 bool SupervisedUserManagerImpl::GetUserBooleanValue(const std::string& user_id,
321                                                     const char* key,
322                                                     bool* out_value) const {
323   PrefService* local_state = g_browser_process->local_state();
324   const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
325   return dictionary->GetBooleanWithoutPathExpansion(user_id, out_value);
326 }
327
328 void SupervisedUserManagerImpl::SetUserStringValue(
329     const std::string& user_id,
330     const char* key,
331     const std::string& value) {
332   PrefService* local_state = g_browser_process->local_state();
333   DictionaryPrefUpdate update(local_state, key);
334   update->SetStringWithoutPathExpansion(user_id, value);
335 }
336
337 void SupervisedUserManagerImpl::SetUserIntegerValue(
338     const std::string& user_id,
339     const char* key,
340     const int value) {
341   PrefService* local_state = g_browser_process->local_state();
342   DictionaryPrefUpdate update(local_state, key);
343   update->SetIntegerWithoutPathExpansion(user_id, value);
344 }
345
346 void SupervisedUserManagerImpl::SetUserBooleanValue(const std::string& user_id,
347                                                     const char* key,
348                                                     const bool value) {
349   PrefService* local_state = g_browser_process->local_state();
350   DictionaryPrefUpdate update(local_state, key);
351   update->SetBooleanWithoutPathExpansion(user_id, value);
352 }
353
354 const User* SupervisedUserManagerImpl::FindByDisplayName(
355     const base::string16& display_name) const {
356   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
357   const UserList& users = owner_->GetUsers();
358   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
359     if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
360         ((*it)->display_name() == display_name)) {
361       return *it;
362     }
363   }
364   return NULL;
365 }
366
367 const User* SupervisedUserManagerImpl::FindBySyncId(
368     const std::string& sync_id) const {
369   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
370   const UserList& users = owner_->GetUsers();
371   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
372     if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
373         (GetUserSyncId((*it)->email()) == sync_id)) {
374       return *it;
375     }
376   }
377   return NULL;
378 }
379
380 void SupervisedUserManagerImpl::StartCreationTransaction(
381       const base::string16& display_name) {
382   g_browser_process->local_state()->
383       SetString(kLocallyManagedUserCreationTransactionDisplayName,
384                 base::UTF16ToASCII(display_name));
385   g_browser_process->local_state()->CommitPendingWrite();
386 }
387
388 void SupervisedUserManagerImpl::SetCreationTransactionUserId(
389       const std::string& email) {
390   g_browser_process->local_state()->
391       SetString(kLocallyManagedUserCreationTransactionUserId,
392                 email);
393   g_browser_process->local_state()->CommitPendingWrite();
394 }
395
396 void SupervisedUserManagerImpl::CommitCreationTransaction() {
397   g_browser_process->local_state()->
398       ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
399   g_browser_process->local_state()->
400       ClearPref(kLocallyManagedUserCreationTransactionUserId);
401   g_browser_process->local_state()->CommitPendingWrite();
402 }
403
404 bool SupervisedUserManagerImpl::HasFailedUserCreationTransaction() {
405   return !(g_browser_process->local_state()->
406                GetString(kLocallyManagedUserCreationTransactionDisplayName).
407                    empty());
408 }
409
410 void SupervisedUserManagerImpl::RollbackUserCreationTransaction() {
411   PrefService* prefs = g_browser_process->local_state();
412
413   std::string display_name = prefs->
414       GetString(kLocallyManagedUserCreationTransactionDisplayName);
415   std::string user_id = prefs->
416       GetString(kLocallyManagedUserCreationTransactionUserId);
417
418   LOG(WARNING) << "Cleaning up transaction for "
419                << display_name << "/" << user_id;
420
421   if (user_id.empty()) {
422     // Not much to do - just remove transaction.
423     prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
424     prefs->CommitPendingWrite();
425     return;
426   }
427
428   if (gaia::ExtractDomainName(user_id) !=
429           UserManager::kLocallyManagedUserDomain) {
430     LOG(WARNING) << "Clean up transaction for  non-locally managed user found :"
431                  << user_id << ", will not remove data";
432     prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
433     prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
434     prefs->CommitPendingWrite();
435     return;
436   }
437   owner_->RemoveNonOwnerUserInternal(user_id, NULL);
438
439   prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
440   prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
441   prefs->CommitPendingWrite();
442 }
443
444 void SupervisedUserManagerImpl::RemoveNonCryptohomeData(
445     const std::string& user_id) {
446   PrefService* prefs = g_browser_process->local_state();
447   ListPrefUpdate prefs_new_users_update(prefs, kLocallyManagedUsersFirstRun);
448   prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
449
450   CleanPref(user_id, kManagedUserSyncId);
451   CleanPref(user_id, kManagedUserManagers);
452   CleanPref(user_id, kManagedUserManagerNames);
453   CleanPref(user_id, kManagedUserManagerDisplayEmails);
454   CleanPref(user_id, kSupervisedUserPasswordSalt);
455   CleanPref(user_id, kSupervisedUserPasswordSchema);
456   CleanPref(user_id, kSupervisedUserPasswordRevision);
457   CleanPref(user_id, kSupervisedUserNeedPasswordUpdate);
458   CleanPref(user_id, kSupervisedUserIncompleteKey);
459 }
460
461 void SupervisedUserManagerImpl::CleanPref(const std::string& user_id,
462                                           const char* key) {
463   PrefService* prefs = g_browser_process->local_state();
464   DictionaryPrefUpdate dict_update(prefs, key);
465   dict_update->RemoveWithoutPathExpansion(user_id, NULL);
466 }
467
468 bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
469   ListPrefUpdate prefs_new_users_update(g_browser_process->local_state(),
470                                         kLocallyManagedUsersFirstRun);
471   return prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
472 }
473
474 void SupervisedUserManagerImpl::UpdateManagerName(const std::string& manager_id,
475     const base::string16& new_display_name) {
476   PrefService* local_state = g_browser_process->local_state();
477
478   const base::DictionaryValue* manager_ids =
479       local_state->GetDictionary(kManagedUserManagers);
480
481   DictionaryPrefUpdate manager_name_update(local_state,
482                                            kManagedUserManagerNames);
483   for (base::DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
484       it.Advance()) {
485     std::string user_id;
486     bool has_manager_id = it.value().GetAsString(&user_id);
487     DCHECK(has_manager_id);
488     if (user_id == manager_id) {
489       manager_name_update->SetWithoutPathExpansion(
490           it.key(),
491           new base::StringValue(new_display_name));
492     }
493   }
494 }
495
496 SupervisedUserAuthentication* SupervisedUserManagerImpl::GetAuthentication() {
497   return authentication_.get();
498 }
499
500 void SupervisedUserManagerImpl::LoadSupervisedUserToken(
501     Profile* profile,
502     const LoadTokenCallback& callback) {
503   // TODO(antrim): use profile->GetPath() once we sure it is safe.
504   base::FilePath profile_dir = ProfileHelper::GetProfilePathByUserIdHash(
505       UserManager::Get()->GetUserByProfile(profile)->username_hash());
506   PostTaskAndReplyWithResult(
507       content::BrowserThread::GetBlockingPool(),
508       FROM_HERE,
509       base::Bind(&LoadSyncToken, profile_dir),
510       callback);
511 }
512
513 void SupervisedUserManagerImpl::ConfigureSyncWithToken(
514     Profile* profile,
515     const std::string& token) {
516   if (!token.empty())
517     ManagedUserServiceFactory::GetForProfile(profile)->InitSync(token);
518 }
519
520 }  // namespace chromeos