Upstream version 5.34.104.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 std::string LoadSyncToken(base::FilePath profile_dir) {
78   std::string token;
79   base::FilePath token_file =
80       profile_dir.Append(chromeos::kManagedUserTokenFilename);
81   VLOG(1) << "Loading" << token_file.value();
82   if (!base::ReadFileToString(token_file, &token))
83     return std::string();
84   return token;
85 }
86
87 } // namespace
88
89 namespace chromeos {
90
91 const char kSchemaVersion[] = "SchemaVersion";
92 const char kPasswordRevision[] = "PasswordRevision";
93 const char kSalt[] = "PasswordSalt";
94 const char kEncryptedPassword[] = "EncryptedPassword";
95 const char kRequirePasswordUpdate[] = "RequirePasswordUpdate";
96 const char kPasswordUpdateFile[] = "password.update";
97 const int kMinPasswordRevision = 1;
98
99 // static
100 void SupervisedUserManager::RegisterPrefs(PrefRegistrySimple* registry) {
101   registry->RegisterListPref(kLocallyManagedUsersFirstRun);
102   registry->RegisterIntegerPref(kLocallyManagedUsersNextId, 0);
103   registry->RegisterStringPref(
104       kLocallyManagedUserCreationTransactionDisplayName, "");
105   registry->RegisterStringPref(
106       kLocallyManagedUserCreationTransactionUserId, "");
107   registry->RegisterDictionaryPref(kManagedUserSyncId);
108   registry->RegisterDictionaryPref(kManagedUserManagers);
109   registry->RegisterDictionaryPref(kManagedUserManagerNames);
110   registry->RegisterDictionaryPref(kManagedUserManagerDisplayEmails);
111
112   registry->RegisterDictionaryPref(kSupervisedUserPasswordSchema);
113   registry->RegisterDictionaryPref(kSupervisedUserPasswordSalt);
114   registry->RegisterDictionaryPref(kSupervisedUserPasswordRevision);
115 }
116
117 SupervisedUserManagerImpl::SupervisedUserManagerImpl(UserManagerImpl* owner)
118     : owner_(owner),
119       cros_settings_(CrosSettings::Get()) {
120   // SupervisedUserManager instance should be used only on UI thread.
121   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
122   authentication_.reset(new SupervisedUserAuthentication(this));
123 }
124
125 SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {
126 }
127
128 std::string SupervisedUserManagerImpl::GenerateUserId() {
129   int counter = g_browser_process->local_state()->
130       GetInteger(kLocallyManagedUsersNextId);
131   std::string id;
132   bool user_exists;
133   do {
134     id = base::StringPrintf("%d@%s", counter,
135         UserManager::kLocallyManagedUserDomain);
136     counter++;
137     user_exists = (NULL != owner_->FindUser(id));
138     DCHECK(!user_exists);
139     if (user_exists) {
140       LOG(ERROR) << "Supervised user with id " << id << " already exists.";
141     }
142   } while (user_exists);
143
144   g_browser_process->local_state()->
145       SetInteger(kLocallyManagedUsersNextId, counter);
146
147   g_browser_process->local_state()->CommitPendingWrite();
148   return id;
149 }
150
151 bool SupervisedUserManagerImpl::HasSupervisedUsers(
152       const std::string& manager_id) const {
153   const UserList& users = owner_->GetUsers();
154   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
155     if ((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
156       if (manager_id == GetManagerUserId((*it)->email()))
157         return true;
158     }
159   }
160   return false;
161 }
162
163 const User* SupervisedUserManagerImpl::CreateUserRecord(
164       const std::string& manager_id,
165       const std::string& local_user_id,
166       const std::string& sync_user_id,
167       const base::string16& display_name) {
168   const User* user = FindByDisplayName(display_name);
169   DCHECK(!user);
170   if (user)
171     return user;
172   const User* manager = owner_->FindUser(manager_id);
173   CHECK(manager);
174
175   PrefService* local_state = g_browser_process->local_state();
176
177   User* new_user = User::CreateLocallyManagedUser(local_user_id);
178
179   owner_->AddUserRecord(new_user);
180
181   ListPrefUpdate prefs_new_users_update(local_state,
182                                         kLocallyManagedUsersFirstRun);
183   DictionaryPrefUpdate sync_id_update(local_state, kManagedUserSyncId);
184   DictionaryPrefUpdate manager_update(local_state, kManagedUserManagers);
185   DictionaryPrefUpdate manager_name_update(local_state,
186                                            kManagedUserManagerNames);
187   DictionaryPrefUpdate manager_email_update(local_state,
188                                             kManagedUserManagerDisplayEmails);
189
190   prefs_new_users_update->Insert(0, new base::StringValue(local_user_id));
191
192   sync_id_update->SetWithoutPathExpansion(local_user_id,
193       new base::StringValue(sync_user_id));
194   manager_update->SetWithoutPathExpansion(local_user_id,
195       new base::StringValue(manager->email()));
196   manager_name_update->SetWithoutPathExpansion(local_user_id,
197       new base::StringValue(manager->GetDisplayName()));
198   manager_email_update->SetWithoutPathExpansion(local_user_id,
199       new base::StringValue(manager->display_email()));
200
201   owner_->SaveUserDisplayName(local_user_id, display_name);
202
203   g_browser_process->local_state()->CommitPendingWrite();
204   return new_user;
205 }
206
207 std::string SupervisedUserManagerImpl::GetUserSyncId(const std::string& user_id)
208     const {
209   std::string result;
210   GetUserStringValue(user_id, kManagedUserSyncId, &result);
211   return result;
212 }
213
214 base::string16 SupervisedUserManagerImpl::GetManagerDisplayName(
215     const std::string& user_id) const {
216   PrefService* local_state = g_browser_process->local_state();
217   const base::DictionaryValue* manager_names =
218       local_state->GetDictionary(kManagedUserManagerNames);
219   base::string16 result;
220   if (manager_names->GetStringWithoutPathExpansion(user_id, &result) &&
221       !result.empty())
222     return result;
223   return base::UTF8ToUTF16(GetManagerDisplayEmail(user_id));
224 }
225
226 std::string SupervisedUserManagerImpl::GetManagerUserId(
227       const std::string& user_id) const {
228   std::string result;
229   GetUserStringValue(user_id, kManagedUserManagers, &result);
230   return result;
231 }
232
233 std::string SupervisedUserManagerImpl::GetManagerDisplayEmail(
234       const std::string& user_id) const {
235   std::string result;
236   if (GetUserStringValue(user_id, kManagedUserManagerDisplayEmails, &result) &&
237       !result.empty())
238     return result;
239   return GetManagerUserId(user_id);
240 }
241
242 void SupervisedUserManagerImpl::GetPasswordInformation(
243     const std::string& user_id,
244     base::DictionaryValue* result) {
245   int value;
246   if (GetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, &value))
247     result->SetIntegerWithoutPathExpansion(kSchemaVersion, value);
248   if (GetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, &value))
249     result->SetIntegerWithoutPathExpansion(kPasswordRevision, value);
250
251   std::string salt;
252   if (GetUserStringValue(user_id, kSupervisedUserPasswordSalt, &salt))
253     result->SetStringWithoutPathExpansion(kSalt, salt);
254 }
255
256 void SupervisedUserManagerImpl::SetPasswordInformation(
257       const std::string& user_id,
258       const base::DictionaryValue* password_info) {
259   int value;
260   if (password_info->GetIntegerWithoutPathExpansion(kSchemaVersion, &value))
261     SetUserIntegerValue(user_id, kSupervisedUserPasswordSchema, value);
262   if (password_info->GetIntegerWithoutPathExpansion(kPasswordRevision, &value))
263     SetUserIntegerValue(user_id, kSupervisedUserPasswordRevision, value);
264
265   std::string salt;
266   if (password_info->GetStringWithoutPathExpansion(kSalt, &salt))
267     SetUserStringValue(user_id, kSupervisedUserPasswordSalt, salt);
268   g_browser_process->local_state()->CommitPendingWrite();
269 }
270
271 bool SupervisedUserManagerImpl::GetUserStringValue(
272     const std::string& user_id,
273     const char* key,
274     std::string* out_value) const {
275   PrefService* local_state = g_browser_process->local_state();
276   const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
277   return dictionary->GetStringWithoutPathExpansion(user_id, out_value);
278 }
279
280 bool SupervisedUserManagerImpl::GetUserIntegerValue(
281     const std::string& user_id,
282     const char* key,
283     int* out_value) const {
284   PrefService* local_state = g_browser_process->local_state();
285   const base::DictionaryValue* dictionary = local_state->GetDictionary(key);
286   return dictionary->GetIntegerWithoutPathExpansion(user_id, out_value);
287 }
288
289 void SupervisedUserManagerImpl::SetUserStringValue(
290     const std::string& user_id,
291     const char* key,
292     const std::string& value) {
293   PrefService* local_state = g_browser_process->local_state();
294   DictionaryPrefUpdate update(local_state, key);
295   update->SetStringWithoutPathExpansion(user_id, value);
296 }
297
298 void SupervisedUserManagerImpl::SetUserIntegerValue(
299     const std::string& user_id,
300     const char* key,
301     const int value) {
302   PrefService* local_state = g_browser_process->local_state();
303   DictionaryPrefUpdate update(local_state, key);
304   update->SetIntegerWithoutPathExpansion(user_id, value);
305 }
306
307 const User* SupervisedUserManagerImpl::FindByDisplayName(
308     const base::string16& display_name) const {
309   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
310   const UserList& users = owner_->GetUsers();
311   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
312     if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
313         ((*it)->display_name() == display_name)) {
314       return *it;
315     }
316   }
317   return NULL;
318 }
319
320 const User* SupervisedUserManagerImpl::FindBySyncId(
321     const std::string& sync_id) const {
322   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
323   const UserList& users = owner_->GetUsers();
324   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
325     if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
326         (GetUserSyncId((*it)->email()) == sync_id)) {
327       return *it;
328     }
329   }
330   return NULL;
331 }
332
333 void SupervisedUserManagerImpl::StartCreationTransaction(
334       const base::string16& display_name) {
335   g_browser_process->local_state()->
336       SetString(kLocallyManagedUserCreationTransactionDisplayName,
337            UTF16ToASCII(display_name));
338   g_browser_process->local_state()->CommitPendingWrite();
339 }
340
341 void SupervisedUserManagerImpl::SetCreationTransactionUserId(
342       const std::string& email) {
343   g_browser_process->local_state()->
344       SetString(kLocallyManagedUserCreationTransactionUserId,
345                 email);
346   g_browser_process->local_state()->CommitPendingWrite();
347 }
348
349 void SupervisedUserManagerImpl::CommitCreationTransaction() {
350   g_browser_process->local_state()->
351       ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
352   g_browser_process->local_state()->
353       ClearPref(kLocallyManagedUserCreationTransactionUserId);
354   g_browser_process->local_state()->CommitPendingWrite();
355 }
356
357 bool SupervisedUserManagerImpl::HasFailedUserCreationTransaction() {
358   return !(g_browser_process->local_state()->
359                GetString(kLocallyManagedUserCreationTransactionDisplayName).
360                    empty());
361 }
362
363 void SupervisedUserManagerImpl::RollbackUserCreationTransaction() {
364   PrefService* prefs = g_browser_process->local_state();
365
366   std::string display_name = prefs->
367       GetString(kLocallyManagedUserCreationTransactionDisplayName);
368   std::string user_id = prefs->
369       GetString(kLocallyManagedUserCreationTransactionUserId);
370
371   LOG(WARNING) << "Cleaning up transaction for "
372                << display_name << "/" << user_id;
373
374   if (user_id.empty()) {
375     // Not much to do - just remove transaction.
376     prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
377     prefs->CommitPendingWrite();
378     return;
379   }
380
381   if (gaia::ExtractDomainName(user_id) !=
382           UserManager::kLocallyManagedUserDomain) {
383     LOG(WARNING) << "Clean up transaction for  non-locally managed user found :"
384                  << user_id << ", will not remove data";
385     prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
386     prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
387     prefs->CommitPendingWrite();
388     return;
389   }
390   owner_->RemoveNonOwnerUserInternal(user_id, NULL);
391
392   prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
393   prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
394   prefs->CommitPendingWrite();
395 }
396
397 void SupervisedUserManagerImpl::RemoveNonCryptohomeData(
398     const std::string& user_id) {
399   PrefService* prefs = g_browser_process->local_state();
400   ListPrefUpdate prefs_new_users_update(prefs, kLocallyManagedUsersFirstRun);
401   prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
402
403   CleanPref(user_id, kManagedUserSyncId);
404   CleanPref(user_id, kManagedUserManagers);
405   CleanPref(user_id, kManagedUserManagerNames);
406   CleanPref(user_id, kManagedUserManagerDisplayEmails);
407   CleanPref(user_id, kSupervisedUserPasswordSalt);
408   CleanPref(user_id, kSupervisedUserPasswordSchema);
409   CleanPref(user_id, kSupervisedUserPasswordRevision);
410 }
411
412 void SupervisedUserManagerImpl::CleanPref(const std::string& user_id,
413                                           const char* key) {
414   PrefService* prefs = g_browser_process->local_state();
415   DictionaryPrefUpdate dict_update(prefs, key);
416   dict_update->RemoveWithoutPathExpansion(user_id, NULL);
417 }
418
419 bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
420   ListPrefUpdate prefs_new_users_update(g_browser_process->local_state(),
421                                         kLocallyManagedUsersFirstRun);
422   return prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
423 }
424
425 void SupervisedUserManagerImpl::UpdateManagerName(const std::string& manager_id,
426     const base::string16& new_display_name) {
427   PrefService* local_state = g_browser_process->local_state();
428
429   const base::DictionaryValue* manager_ids =
430       local_state->GetDictionary(kManagedUserManagers);
431
432   DictionaryPrefUpdate manager_name_update(local_state,
433                                            kManagedUserManagerNames);
434   for (base::DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
435       it.Advance()) {
436     std::string user_id;
437     bool has_manager_id = it.value().GetAsString(&user_id);
438     DCHECK(has_manager_id);
439     if (user_id == manager_id) {
440       manager_name_update->SetWithoutPathExpansion(
441           it.key(),
442           new base::StringValue(new_display_name));
443     }
444   }
445 }
446
447 SupervisedUserAuthentication* SupervisedUserManagerImpl::GetAuthentication() {
448   return authentication_.get();
449 }
450
451 void SupervisedUserManagerImpl::LoadSupervisedUserToken(
452     Profile* profile,
453     const LoadTokenCallback& callback) {
454   // TODO(antrim): use profile->GetPath() once we sure it is safe.
455   base::FilePath profile_dir = ProfileHelper::GetProfilePathByUserIdHash(
456       UserManager::Get()->GetUserByProfile(profile)->username_hash());
457   PostTaskAndReplyWithResult(
458       content::BrowserThread::GetBlockingPool(),
459       FROM_HERE,
460       base::Bind(&LoadSyncToken, profile_dir),
461       callback);
462 }
463
464 void SupervisedUserManagerImpl::ConfigureSyncWithToken(
465     Profile* profile,
466     const std::string& token) {
467   if (!token.empty())
468     ManagedUserServiceFactory::GetForProfile(profile)->InitSync(token);
469 }
470
471 }  // namespace chromeos