• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/user_manager_impl.h"
20 #include "chrome/browser/chromeos/profiles/profile_helper.h"
21 #include "chrome/browser/managed_mode/managed_user_service.h"
22 #include "chrome/browser/managed_mode/managed_user_service_factory.h"
23 #include "chromeos/settings/cros_settings_names.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "google_apis/gaia/gaia_auth_util.h"
26 
27 using content::BrowserThread;
28 
29 namespace {
30 
31 // A map from locally managed user local user id to sync user id.
32 const char kManagedUserSyncId[] =
33     "ManagedUserSyncId";
34 
35 // A map from locally managed user id to manager user id.
36 const char kManagedUserManagers[] =
37     "ManagedUserManagers";
38 
39 // A map from locally managed user id to manager display name.
40 const char kManagedUserManagerNames[] =
41     "ManagedUserManagerNames";
42 
43 // A map from locally managed user id to manager display e-mail.
44 const char kManagedUserManagerDisplayEmails[] =
45     "ManagedUserManagerDisplayEmails";
46 
47 // A vector pref of the locally managed accounts defined on this device, that
48 // had not logged in yet.
49 const char kLocallyManagedUsersFirstRun[] = "LocallyManagedUsersFirstRun";
50 
51 // A pref of the next id for locally managed users generation.
52 const char kLocallyManagedUsersNextId[] =
53     "LocallyManagedUsersNextId";
54 
55 // A pref of the next id for locally managed users generation.
56 const char kLocallyManagedUserCreationTransactionDisplayName[] =
57     "LocallyManagedUserCreationTransactionDisplayName";
58 
59 // A pref of the next id for locally managed users generation.
60 const char kLocallyManagedUserCreationTransactionUserId[] =
61     "LocallyManagedUserCreationTransactionUserId";
62 
LoadSyncToken(base::FilePath profile_dir)63 std::string LoadSyncToken(base::FilePath profile_dir) {
64   std::string token;
65   base::FilePath token_file =
66       profile_dir.Append(chromeos::kManagedUserTokenFilename);
67   VLOG(1) << "Loading" << token_file.value();
68   if (!base::ReadFileToString(token_file, &token))
69     return std::string();
70   return token;
71 }
72 
73 } // namespace
74 
75 namespace chromeos {
76 
77 // static
RegisterPrefs(PrefRegistrySimple * registry)78 void SupervisedUserManager::RegisterPrefs(PrefRegistrySimple* registry) {
79   registry->RegisterListPref(kLocallyManagedUsersFirstRun);
80   registry->RegisterIntegerPref(kLocallyManagedUsersNextId, 0);
81   registry->RegisterStringPref(
82       kLocallyManagedUserCreationTransactionDisplayName, "");
83   registry->RegisterStringPref(
84       kLocallyManagedUserCreationTransactionUserId, "");
85   registry->RegisterDictionaryPref(kManagedUserSyncId);
86   registry->RegisterDictionaryPref(kManagedUserManagers);
87   registry->RegisterDictionaryPref(kManagedUserManagerNames);
88   registry->RegisterDictionaryPref(kManagedUserManagerDisplayEmails);
89 }
90 
SupervisedUserManagerImpl(UserManagerImpl * owner)91 SupervisedUserManagerImpl::SupervisedUserManagerImpl(UserManagerImpl* owner)
92     : owner_(owner),
93       cros_settings_(CrosSettings::Get()) {
94   // SupervisedUserManager instance should be used only on UI thread.
95   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 }
97 
~SupervisedUserManagerImpl()98 SupervisedUserManagerImpl::~SupervisedUserManagerImpl() {
99 }
100 
GenerateUserId()101 std::string SupervisedUserManagerImpl::GenerateUserId() {
102   int counter = g_browser_process->local_state()->
103       GetInteger(kLocallyManagedUsersNextId);
104   std::string id;
105   bool user_exists;
106   do {
107     id = base::StringPrintf("%d@%s", counter,
108         UserManager::kLocallyManagedUserDomain);
109     counter++;
110     user_exists = (NULL != owner_->FindUser(id));
111     DCHECK(!user_exists);
112     if (user_exists) {
113       LOG(ERROR) << "Supervised user with id " << id << " already exists.";
114     }
115   } while (user_exists);
116 
117   g_browser_process->local_state()->
118       SetInteger(kLocallyManagedUsersNextId, counter);
119 
120   g_browser_process->local_state()->CommitPendingWrite();
121   return id;
122 }
123 
CreateUserRecord(const std::string & manager_id,const std::string & local_user_id,const std::string & sync_user_id,const base::string16 & display_name)124 const User* SupervisedUserManagerImpl::CreateUserRecord(
125       const std::string& manager_id,
126       const std::string& local_user_id,
127       const std::string& sync_user_id,
128       const base::string16& display_name) {
129   const User* user = FindByDisplayName(display_name);
130   DCHECK(!user);
131   if (user)
132     return user;
133   const User* manager = owner_->FindUser(manager_id);
134   CHECK(manager);
135 
136   PrefService* local_state = g_browser_process->local_state();
137 
138   User* new_user = User::CreateLocallyManagedUser(local_user_id);
139 
140   owner_->AddUserRecord(new_user);
141 
142   ListPrefUpdate prefs_new_users_update(local_state,
143                                         kLocallyManagedUsersFirstRun);
144   DictionaryPrefUpdate sync_id_update(local_state, kManagedUserSyncId);
145   DictionaryPrefUpdate manager_update(local_state, kManagedUserManagers);
146   DictionaryPrefUpdate manager_name_update(local_state,
147                                            kManagedUserManagerNames);
148   DictionaryPrefUpdate manager_email_update(local_state,
149                                             kManagedUserManagerDisplayEmails);
150 
151   prefs_new_users_update->Insert(0, new base::StringValue(local_user_id));
152 
153   sync_id_update->SetWithoutPathExpansion(local_user_id,
154       new base::StringValue(sync_user_id));
155   manager_update->SetWithoutPathExpansion(local_user_id,
156       new base::StringValue(manager->email()));
157   manager_name_update->SetWithoutPathExpansion(local_user_id,
158       new base::StringValue(manager->GetDisplayName()));
159   manager_email_update->SetWithoutPathExpansion(local_user_id,
160       new base::StringValue(manager->display_email()));
161 
162   owner_->SaveUserDisplayName(local_user_id, display_name);
163 
164   g_browser_process->local_state()->CommitPendingWrite();
165   return new_user;
166 }
167 
GetUserSyncId(const std::string & user_id) const168 std::string SupervisedUserManagerImpl::GetUserSyncId(const std::string& user_id)
169     const {
170   PrefService* local_state = g_browser_process->local_state();
171   const DictionaryValue* sync_ids =
172       local_state->GetDictionary(kManagedUserSyncId);
173   std::string result;
174   sync_ids->GetStringWithoutPathExpansion(user_id, &result);
175   return result;
176 }
177 
GetManagerDisplayName(const std::string & user_id) const178 base::string16 SupervisedUserManagerImpl::GetManagerDisplayName(
179     const std::string& user_id) const {
180   PrefService* local_state = g_browser_process->local_state();
181   const DictionaryValue* manager_names =
182       local_state->GetDictionary(kManagedUserManagerNames);
183   base::string16 result;
184   if (manager_names->GetStringWithoutPathExpansion(user_id, &result) &&
185       !result.empty())
186     return result;
187   return UTF8ToUTF16(GetManagerDisplayEmail(user_id));
188 }
189 
GetManagerUserId(const std::string & user_id) const190 std::string SupervisedUserManagerImpl::GetManagerUserId(
191       const std::string& user_id) const {
192   PrefService* local_state = g_browser_process->local_state();
193   const DictionaryValue* manager_ids =
194       local_state->GetDictionary(kManagedUserManagers);
195   std::string result;
196   manager_ids->GetStringWithoutPathExpansion(user_id, &result);
197   return result;
198 }
199 
GetManagerDisplayEmail(const std::string & user_id) const200 std::string SupervisedUserManagerImpl::GetManagerDisplayEmail(
201       const std::string& user_id) const {
202   PrefService* local_state = g_browser_process->local_state();
203   const DictionaryValue* manager_mails =
204       local_state->GetDictionary(kManagedUserManagerDisplayEmails);
205   std::string result;
206   if (manager_mails->GetStringWithoutPathExpansion(user_id, &result) &&
207       !result.empty()) {
208     return result;
209   }
210   return GetManagerUserId(user_id);
211 }
212 
FindByDisplayName(const base::string16 & display_name) const213 const User* SupervisedUserManagerImpl::FindByDisplayName(
214     const base::string16& display_name) const {
215   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
216   const UserList& users = owner_->GetUsers();
217   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
218     if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
219         ((*it)->display_name() == display_name)) {
220       return *it;
221     }
222   }
223   return NULL;
224 }
225 
FindBySyncId(const std::string & sync_id) const226 const User* SupervisedUserManagerImpl::FindBySyncId(
227     const std::string& sync_id) const {
228   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
229   const UserList& users = owner_->GetUsers();
230   for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
231     if (((*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) &&
232         (GetUserSyncId((*it)->email()) == sync_id)) {
233       return *it;
234     }
235   }
236   return NULL;
237 }
238 
StartCreationTransaction(const base::string16 & display_name)239 void SupervisedUserManagerImpl::StartCreationTransaction(
240       const base::string16& display_name) {
241   g_browser_process->local_state()->
242       SetString(kLocallyManagedUserCreationTransactionDisplayName,
243            UTF16ToASCII(display_name));
244   g_browser_process->local_state()->CommitPendingWrite();
245 }
246 
SetCreationTransactionUserId(const std::string & email)247 void SupervisedUserManagerImpl::SetCreationTransactionUserId(
248       const std::string& email) {
249   g_browser_process->local_state()->
250       SetString(kLocallyManagedUserCreationTransactionUserId,
251                 email);
252   g_browser_process->local_state()->CommitPendingWrite();
253 }
254 
CommitCreationTransaction()255 void SupervisedUserManagerImpl::CommitCreationTransaction() {
256   g_browser_process->local_state()->
257       ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
258   g_browser_process->local_state()->
259       ClearPref(kLocallyManagedUserCreationTransactionUserId);
260   g_browser_process->local_state()->CommitPendingWrite();
261 }
262 
HasFailedUserCreationTransaction()263 bool SupervisedUserManagerImpl::HasFailedUserCreationTransaction() {
264   return !(g_browser_process->local_state()->
265                GetString(kLocallyManagedUserCreationTransactionDisplayName).
266                    empty());
267 }
268 
RollbackUserCreationTransaction()269 void SupervisedUserManagerImpl::RollbackUserCreationTransaction() {
270   PrefService* prefs = g_browser_process->local_state();
271 
272   std::string display_name = prefs->
273       GetString(kLocallyManagedUserCreationTransactionDisplayName);
274   std::string user_id = prefs->
275       GetString(kLocallyManagedUserCreationTransactionUserId);
276 
277   LOG(WARNING) << "Cleaning up transaction for "
278                << display_name << "/" << user_id;
279 
280   if (user_id.empty()) {
281     // Not much to do - just remove transaction.
282     prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
283     prefs->CommitPendingWrite();
284     return;
285   }
286 
287   if (gaia::ExtractDomainName(user_id) !=
288           UserManager::kLocallyManagedUserDomain) {
289     LOG(WARNING) << "Clean up transaction for  non-locally managed user found :"
290                  << user_id << ", will not remove data";
291     prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
292     prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
293     prefs->CommitPendingWrite();
294     return;
295   }
296   owner_->RemoveNonOwnerUserInternal(user_id, NULL);
297 
298   prefs->ClearPref(kLocallyManagedUserCreationTransactionDisplayName);
299   prefs->ClearPref(kLocallyManagedUserCreationTransactionUserId);
300   prefs->CommitPendingWrite();
301 }
302 
RemoveNonCryptohomeData(const std::string & user_id)303 void SupervisedUserManagerImpl::RemoveNonCryptohomeData(
304     const std::string& user_id) {
305   PrefService* prefs = g_browser_process->local_state();
306   ListPrefUpdate prefs_new_users_update(prefs, kLocallyManagedUsersFirstRun);
307   prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
308 
309   DictionaryPrefUpdate synd_id_update(prefs, kManagedUserSyncId);
310   synd_id_update->RemoveWithoutPathExpansion(user_id, NULL);
311 
312   DictionaryPrefUpdate managers_update(prefs, kManagedUserManagers);
313   managers_update->RemoveWithoutPathExpansion(user_id, NULL);
314 
315   DictionaryPrefUpdate manager_names_update(prefs,
316                                             kManagedUserManagerNames);
317   manager_names_update->RemoveWithoutPathExpansion(user_id, NULL);
318 
319   DictionaryPrefUpdate manager_emails_update(prefs,
320                                              kManagedUserManagerDisplayEmails);
321   manager_emails_update->RemoveWithoutPathExpansion(user_id, NULL);
322 }
323 
CheckForFirstRun(const std::string & user_id)324 bool SupervisedUserManagerImpl::CheckForFirstRun(const std::string& user_id) {
325   ListPrefUpdate prefs_new_users_update(g_browser_process->local_state(),
326                                         kLocallyManagedUsersFirstRun);
327   return prefs_new_users_update->Remove(base::StringValue(user_id), NULL);
328 }
329 
UpdateManagerName(const std::string & manager_id,const base::string16 & new_display_name)330 void SupervisedUserManagerImpl::UpdateManagerName(const std::string& manager_id,
331     const base::string16& new_display_name) {
332   PrefService* local_state = g_browser_process->local_state();
333 
334   const DictionaryValue* manager_ids =
335       local_state->GetDictionary(kManagedUserManagers);
336 
337   DictionaryPrefUpdate manager_name_update(local_state,
338                                            kManagedUserManagerNames);
339   for (DictionaryValue::Iterator it(*manager_ids); !it.IsAtEnd();
340       it.Advance()) {
341     std::string user_id;
342     bool has_manager_id = it.value().GetAsString(&user_id);
343     DCHECK(has_manager_id);
344     if (user_id == manager_id) {
345       manager_name_update->SetWithoutPathExpansion(
346           it.key(),
347           new base::StringValue(new_display_name));
348     }
349   }
350 }
351 
LoadSupervisedUserToken(Profile * profile,const LoadTokenCallback & callback)352 void SupervisedUserManagerImpl::LoadSupervisedUserToken(
353     Profile* profile,
354     const LoadTokenCallback& callback) {
355   // TODO(antrim): use profile->GetPath() once we sure it is safe.
356   base::FilePath profile_dir = ProfileHelper::GetProfilePathByUserIdHash(
357       UserManager::Get()->GetUserByProfile(profile)->username_hash());
358   PostTaskAndReplyWithResult(
359       content::BrowserThread::GetBlockingPool(),
360       FROM_HERE,
361       base::Bind(&LoadSyncToken, profile_dir),
362       callback);
363 }
364 
ConfigureSyncWithToken(Profile * profile,const std::string & token)365 void SupervisedUserManagerImpl::ConfigureSyncWithToken(
366     Profile* profile,
367     const std::string& token) {
368   if (!token.empty())
369     ManagedUserServiceFactory::GetForProfile(profile)->InitSync(token);
370 }
371 
372 }  // namespace chromeos
373