15132ea3abba57ed8935ec44f18b2832be45d01a
[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/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"
20
21 using content::BrowserThread;
22
23 namespace {
24
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";
29
30 // A map from locally managed user id to manager user id.
31 const char kManagedUserManagers[] =
32     "ManagedUserManagers";
33
34 // A map from locally managed user id to manager display name.
35 const char kManagedUserManagerNames[] =
36     "ManagedUserManagerNames";
37
38 // A map from locally managed user id to manager display e-mail.
39 const char kManagedUserManagerDisplayEmails[] =
40     "ManagedUserManagerDisplayEmails";
41
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";
45
46 // A pref of the next id for locally managed users generation.
47 const char kLocallyManagedUsersNextId[] =
48     "LocallyManagedUsersNextId";
49
50 // A pref of the next id for locally managed users generation.
51 const char kLocallyManagedUserCreationTransactionDisplayName[] =
52     "LocallyManagedUserCreationTransactionDisplayName";
53
54 // A pref of the next id for locally managed users generation.
55 const char kLocallyManagedUserCreationTransactionUserId[] =
56     "LocallyManagedUserCreationTransactionUserId";
57
58 // A map from user id to password schema id.
59 const char kSupervisedUserPasswordSchema[] =
60     "SupervisedUserPasswordSchema";
61
62 // A map from user id to password salt.
63 const char kSupervisedUserPasswordSalt[] =
64     "SupervisedUserPasswordSalt";
65
66 // A map from user id to password revision.
67 const char kSupervisedUserPasswordRevision[] =
68     "SupervisedUserPasswordRevision";
69
70 } // namespace
71
72 namespace chromeos {
73
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;
79
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);
92
93   registry->RegisterDictionaryPref(kSupervisedUserPasswordSchema);
94   registry->RegisterDictionaryPref(kSupervisedUserPasswordSalt);
95   registry->RegisterDictionaryPref(kSupervisedUserPasswordRevision);
96 }
97
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));
104 }
105
106 SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {
107 }
108
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.";
122     }
123   } while (user_exists);
124
125   g_browser_process->local_state()->
126       SetInteger(kLocallyManagedUsersNextId, counter);
127
128   g_browser_process->local_state()->CommitPendingWrite();
129   return id;
130 }
131
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);
143
144   PrefService* local_state = g_browser_process->local_state();
145
146   User* new_user = User::CreateLocallyManagedUser(local_user_id);
147
148   owner_->AddUserRecord(new_user);
149
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);
158
159   prefs_new_users_update->Insert(0, new base::StringValue(local_user_id));
160
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()));
169
170   owner_->SaveUserDisplayName(local_user_id, display_name);
171
172   g_browser_process->local_state()->CommitPendingWrite();
173   return new_user;
174 }
175
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;
181 }
182
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));
193 }
194
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;
200 }
201
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);
209 }
210
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);
219
220   std::string salt;
221   if (GetUserStringValue(user_id, kSupervisedUserPasswordSalt, &salt))
222     result->SetStringWithoutPathExpansion(kSalt, salt);
223 }
224
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);
233
234   std::string salt;
235   if (password_info->GetStringWithoutPathExpansion(kSalt, &salt))
236     SetUserStringValue(user_id, kSupervisedUserPasswordSalt, salt);
237   g_browser_process->local_state()->CommitPendingWrite();
238 }
239
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);
247 }
248
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);
256 }
257
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);
265 }
266
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);
274 }
275
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;
284     }
285   }
286   return NULL;
287 }
288
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;
297     }
298   }
299   return NULL;
300 }
301
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();
308 }
309
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();
316 }
317
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();
324 }
325
326 bool SupervisedUserManagerImpl::HasFailedUserCreationTransaction() {
327   return !(g_browser_process->local_state()->
328                GetString(kLocallyManagedUserCreationTransactionDisplayName).
329                    empty());
330 }
331
332 void SupervisedUserManagerImpl::RollbackUserCreationTransaction() {
333   PrefService* prefs = g_browser_process->local_state();
334
335   std::string display_name = prefs->
336       GetString(kLocallyManagedUserCreationTransactionDisplayName);
337   std::string user_id = prefs->
338       GetString(kLocallyManagedUserCreationTransactionUserId);
339
340   LOG(WARNING) << "Cleaning up transaction for "
341                << display_name << "/" << user_id;
342
343   if (user_id.empty()) {
344     // Not much to do - just remove transaction.
345     prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
346     prefs->CommitPendingWrite();
347     return;
348   }
349
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;
358   }
359   owner_->RemoveNonOwnerUserInternal(user_id, NULL);
360
361   prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
362   prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
363   prefs->CommitPendingWrite();
364 }
365
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);
371
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);
379 }
380
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);
386 }
387
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);
392 }
393
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();
397
398   const base::DictionaryValue* manager_ids =
399       local_state->GetDictionary(kManagedUserManagers);
400
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));
412     }
413   }
414 }
415
416 SupervisedUserAuthentication* SupervisedUserManagerImpl::GetAuthentication() {
417   return authentication_.get();
418 }
419
420 }  // namespace chromeos