1 // Copyright 2014 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/users/user_manager_impl.h"
6
7 #include <cstddef>
8 #include <set>
9
10 #include "ash/multi_profile_uma.h"
11 #include "base/base_paths.h"
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/command_line.h"
15 #include "base/compiler_specific.h"
16 #include "base/files/file_path.h"
17 #include "base/format_macros.h"
18 #include "base/logging.h"
19 #include "base/metrics/histogram.h"
20 #include "base/path_service.h"
21 #include "base/prefs/pref_registry_simple.h"
22 #include "base/prefs/pref_service.h"
23 #include "base/prefs/scoped_user_pref_update.h"
24 #include "base/rand_util.h"
25 #include "base/strings/string_util.h"
26 #include "base/strings/stringprintf.h"
27 #include "base/strings/utf_string_conversions.h"
28 #include "base/sys_info.h"
29 #include "base/threading/worker_pool.h"
30 #include "base/values.h"
31 #include "chrome/browser/app_mode/app_mode_utils.h"
32 #include "chrome/browser/browser_process.h"
33 #include "chrome/browser/chrome_notification_types.h"
34 #include "chrome/browser/chromeos/base/locale_util.h"
35 #include "chrome/browser/chromeos/login/auth/user_context.h"
36 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
37 #include "chrome/browser/chromeos/login/login_utils.h"
38 #include "chrome/browser/chromeos/login/session/session_manager.h"
39 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h"
40 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h"
41 #include "chrome/browser/chromeos/login/ui/login_display.h"
42 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
43 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
44 #include "chrome/browser/chromeos/login/users/remove_user_delegate.h"
45 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
46 #include "chrome/browser/chromeos/login/wizard_controller.h"
47 #include "chrome/browser/chromeos/net/network_portal_detector.h"
48 #include "chrome/browser/chromeos/net/network_portal_detector_strategy.h"
49 #include "chrome/browser/chromeos/ownership/owner_settings_service_factory.h"
50 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
51 #include "chrome/browser/chromeos/policy/device_local_account.h"
52 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
53 #include "chrome/browser/chromeos/profiles/profile_helper.h"
54 #include "chrome/browser/chromeos/session_length_limiter.h"
55 #include "chrome/browser/net/nss_context.h"
56 #include "chrome/browser/profiles/profile.h"
57 #include "chrome/browser/profiles/profile_manager.h"
58 #include "chrome/browser/profiles/profiles_state.h"
59 #include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
60 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
61 #include "chrome/browser/sync/profile_sync_service.h"
62 #include "chrome/browser/sync/profile_sync_service_factory.h"
63 #include "chrome/common/chrome_constants.h"
64 #include "chrome/common/chrome_paths.h"
65 #include "chrome/common/chrome_switches.h"
66 #include "chrome/common/crash_keys.h"
67 #include "chrome/common/pref_names.h"
68 #include "chromeos/cert_loader.h"
69 #include "chromeos/chromeos_switches.h"
70 #include "chromeos/cryptohome/async_method_caller.h"
71 #include "chromeos/dbus/dbus_thread_manager.h"
72 #include "chromeos/login/login_state.h"
73 #include "chromeos/settings/cros_settings_names.h"
74 #include "content/public/browser/browser_thread.h"
75 #include "content/public/browser/notification_service.h"
76 #include "google_apis/gaia/gaia_auth_util.h"
77 #include "google_apis/gaia/google_service_auth_error.h"
78 #include "policy/policy_constants.h"
79 #include "ui/base/l10n/l10n_util.h"
80 #include "ui/wm/core/wm_core_switches.h"
81
82 using content::BrowserThread;
83
84 namespace chromeos {
85 namespace {
86
87 // A vector pref of the the regular users known on this device, arranged in LRU
88 // order.
89 const char kRegularUsers[] = "LoggedInUsers";
90
91 // A vector pref of the public accounts defined on this device.
92 const char kPublicAccounts[] = "PublicAccounts";
93
94 // A string pref that gets set when a public account is removed but a user is
95 // currently logged into that account, requiring the account's data to be
96 // removed after logout.
97 const char kPublicAccountPendingDataRemoval[] =
98 "PublicAccountPendingDataRemoval";
99
100 // A dictionary that maps user IDs to the displayed name.
101 const char kUserDisplayName[] = "UserDisplayName";
102
103 // A dictionary that maps user IDs to the user's given name.
104 const char kUserGivenName[] = "UserGivenName";
105
106 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
107 const char kUserDisplayEmail[] = "UserDisplayEmail";
108
109 // A dictionary that maps user IDs to OAuth token presence flag.
110 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus";
111
112 // A dictionary that maps user IDs to a flag indicating whether online
113 // authentication against GAIA should be enforced during the next sign-in.
114 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin";
115
116 // A string pref containing the ID of the last user who logged in if it was
117 // a regular user or an empty string if it was another type of user (guest,
118 // kiosk, public account, etc.).
119 const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser";
120
121 // Upper bound for a histogram metric reporting the amount of time between
122 // one regular user logging out and a different regular user logging in.
123 const int kLogoutToLoginDelayMaxSec = 1800;
124
125 // Callback that is called after user removal is complete.
OnRemoveUserComplete(const std::string & user_email,bool success,cryptohome::MountError return_code)126 void OnRemoveUserComplete(const std::string& user_email,
127 bool success,
128 cryptohome::MountError return_code) {
129 // Log the error, but there's not much we can do.
130 if (!success) {
131 LOG(ERROR) << "Removal of cryptohome for " << user_email
132 << " failed, return code: " << return_code;
133 }
134 }
135
136 // Helper function that copies users from |users_list| to |users_vector| and
137 // |users_set|. Duplicates and users already present in |existing_users| are
138 // skipped.
ParseUserList(const base::ListValue & users_list,const std::set<std::string> & existing_users,std::vector<std::string> * users_vector,std::set<std::string> * users_set)139 void ParseUserList(const base::ListValue& users_list,
140 const std::set<std::string>& existing_users,
141 std::vector<std::string>* users_vector,
142 std::set<std::string>* users_set) {
143 users_vector->clear();
144 users_set->clear();
145 for (size_t i = 0; i < users_list.GetSize(); ++i) {
146 std::string email;
147 if (!users_list.GetString(i, &email) || email.empty()) {
148 LOG(ERROR) << "Corrupt entry in user list at index " << i << ".";
149 continue;
150 }
151 if (existing_users.find(email) != existing_users.end() ||
152 !users_set->insert(email).second) {
153 LOG(ERROR) << "Duplicate user: " << email;
154 continue;
155 }
156 users_vector->push_back(email);
157 }
158 }
159
160 class UserHashMatcher {
161 public:
UserHashMatcher(const std::string & h)162 explicit UserHashMatcher(const std::string& h) : username_hash(h) {}
operator ()(const User * user) const163 bool operator()(const User* user) const {
164 return user->username_hash() == username_hash;
165 }
166
167 private:
168 const std::string& username_hash;
169 };
170
171 // Runs on SequencedWorkerPool thread. Passes resolved locale to
172 // |on_resolve_callback| on UI thread.
ResolveLocale(const std::string & raw_locale,base::Callback<void (const std::string &)> on_resolve_callback)173 void ResolveLocale(
174 const std::string& raw_locale,
175 base::Callback<void(const std::string&)> on_resolve_callback) {
176 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
177 std::string resolved_locale;
178 // Ignore result
179 l10n_util::CheckAndResolveLocale(raw_locale, &resolved_locale);
180 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
181 base::Bind(on_resolve_callback, resolved_locale));
182 }
183
184 // Callback to GetNSSCertDatabaseForProfile. It starts CertLoader using the
185 // provided NSS database. It must be called for primary user only.
OnGetNSSCertDatabaseForUser(net::NSSCertDatabase * database)186 void OnGetNSSCertDatabaseForUser(net::NSSCertDatabase* database) {
187 if (!CertLoader::IsInitialized())
188 return;
189
190 CertLoader::Get()->StartWithNSSDB(database);
191 }
192
193 } // namespace
194
195 // static
RegisterPrefs(PrefRegistrySimple * registry)196 void UserManager::RegisterPrefs(PrefRegistrySimple* registry) {
197 registry->RegisterListPref(kRegularUsers);
198 registry->RegisterListPref(kPublicAccounts);
199 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, "");
200 registry->RegisterStringPref(kLastLoggedInRegularUser, "");
201 registry->RegisterDictionaryPref(kUserDisplayName);
202 registry->RegisterDictionaryPref(kUserGivenName);
203 registry->RegisterDictionaryPref(kUserDisplayEmail);
204 registry->RegisterDictionaryPref(kUserOAuthTokenStatus);
205 registry->RegisterDictionaryPref(kUserForceOnlineSignin);
206 SupervisedUserManager::RegisterPrefs(registry);
207 SessionLengthLimiter::RegisterPrefs(registry);
208 }
209
UserManagerImpl()210 UserManagerImpl::UserManagerImpl()
211 : cros_settings_(CrosSettings::Get()),
212 device_local_account_policy_service_(NULL),
213 user_loading_stage_(STAGE_NOT_LOADED),
214 active_user_(NULL),
215 primary_user_(NULL),
216 session_started_(false),
217 user_sessions_restored_(false),
218 is_current_user_owner_(false),
219 is_current_user_new_(false),
220 is_current_user_ephemeral_regular_user_(false),
221 ephemeral_users_enabled_(false),
222 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
223 manager_creation_time_(base::TimeTicks::Now()) {
224 UpdateNumberOfUsers();
225 // UserManager instance should be used only on UI thread.
226 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
227 registrar_.Add(this, chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
228 content::NotificationService::AllSources());
229 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
230 content::NotificationService::AllSources());
231 registrar_.Add(this,
232 chrome::NOTIFICATION_PROFILE_CREATED,
233 content::NotificationService::AllSources());
234 RetrieveTrustedDevicePolicies();
235 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
236 kAccountsPrefDeviceLocalAccounts,
237 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
238 base::Unretained(this)));
239 multi_profile_user_controller_.reset(new MultiProfileUserController(
240 this, g_browser_process->local_state()));
241
242 policy::BrowserPolicyConnectorChromeOS* connector =
243 g_browser_process->platform_part()->browser_policy_connector_chromeos();
244 avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
245 cros_settings_,
246 this,
247 connector->GetDeviceLocalAccountPolicyService(),
248 policy::key::kUserAvatarImage,
249 this));
250 avatar_policy_observer_->Init();
251
252 wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
253 cros_settings_,
254 this,
255 connector->GetDeviceLocalAccountPolicyService(),
256 policy::key::kWallpaperImage,
257 this));
258 wallpaper_policy_observer_->Init();
259
260 UpdateLoginState();
261 }
262
~UserManagerImpl()263 UserManagerImpl::~UserManagerImpl() {
264 // Can't use STLDeleteElements because of the private destructor of User.
265 for (UserList::iterator it = users_.begin(); it != users_.end();
266 it = users_.erase(it)) {
267 DeleteUser(*it);
268 }
269 // These are pointers to the same User instances that were in users_ list.
270 logged_in_users_.clear();
271 lru_logged_in_users_.clear();
272
273 DeleteUser(active_user_);
274 }
275
Shutdown()276 void UserManagerImpl::Shutdown() {
277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
278 local_accounts_subscription_.reset();
279 // Stop the session length limiter.
280 session_length_limiter_.reset();
281
282 if (device_local_account_policy_service_)
283 device_local_account_policy_service_->RemoveObserver(this);
284
285 for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
286 ie = user_image_managers_.end();
287 it != ie; ++it) {
288 it->second->Shutdown();
289 }
290 multi_profile_user_controller_.reset();
291 avatar_policy_observer_.reset();
292 wallpaper_policy_observer_.reset();
293 registrar_.RemoveAll();
294 }
295
GetMultiProfileUserController()296 MultiProfileUserController* UserManagerImpl::GetMultiProfileUserController() {
297 return multi_profile_user_controller_.get();
298 }
299
GetUserImageManager(const std::string & user_id)300 UserImageManager* UserManagerImpl::GetUserImageManager(
301 const std::string& user_id) {
302 UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
303 if (ui != user_image_managers_.end())
304 return ui->second.get();
305 linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
306 user_image_managers_[user_id] = mgr;
307 return mgr.get();
308 }
309
GetSupervisedUserManager()310 SupervisedUserManager* UserManagerImpl::GetSupervisedUserManager() {
311 return supervised_user_manager_.get();
312 }
313
GetUsers() const314 const UserList& UserManagerImpl::GetUsers() const {
315 const_cast<UserManagerImpl*>(this)->EnsureUsersLoaded();
316 return users_;
317 }
318
GetUsersAdmittedForMultiProfile() const319 UserList UserManagerImpl::GetUsersAdmittedForMultiProfile() const {
320 // Supervised users are not allowed to use multi-profiles.
321 if (logged_in_users_.size() == 1 &&
322 GetPrimaryUser()->GetType() != User::USER_TYPE_REGULAR) {
323 return UserList();
324 }
325
326 UserList result;
327 const UserList& users = GetUsers();
328 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
329 if ((*it)->GetType() == User::USER_TYPE_REGULAR && !(*it)->is_logged_in()) {
330 MultiProfileUserController::UserAllowedInSessionResult check =
331 multi_profile_user_controller_->
332 IsUserAllowedInSession((*it)->email());
333 if (check == MultiProfileUserController::
334 NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
335 return UserList();
336 }
337
338 // Users with a policy that prevents them being added to a session will be
339 // shown in login UI but will be grayed out.
340 // Same applies to owner account (see http://crbug.com/385034).
341 if (check == MultiProfileUserController::ALLOWED ||
342 check == MultiProfileUserController::NOT_ALLOWED_POLICY_FORBIDS ||
343 check == MultiProfileUserController::NOT_ALLOWED_OWNER_AS_SECONDARY) {
344 result.push_back(*it);
345 }
346 }
347 }
348
349 return result;
350 }
351
GetLoggedInUsers() const352 const UserList& UserManagerImpl::GetLoggedInUsers() const {
353 return logged_in_users_;
354 }
355
GetLRULoggedInUsers()356 const UserList& UserManagerImpl::GetLRULoggedInUsers() {
357 // If there is no user logged in, we return the active user as the only one.
358 if (lru_logged_in_users_.empty() && active_user_) {
359 temp_single_logged_in_users_.clear();
360 temp_single_logged_in_users_.insert(temp_single_logged_in_users_.begin(),
361 active_user_);
362 return temp_single_logged_in_users_;
363 }
364 return lru_logged_in_users_;
365 }
366
GetUnlockUsers() const367 UserList UserManagerImpl::GetUnlockUsers() const {
368 const UserList& logged_in_users = GetLoggedInUsers();
369 if (logged_in_users.empty())
370 return UserList();
371
372 UserList unlock_users;
373 Profile* profile = GetProfileByUser(primary_user_);
374 std::string primary_behavior =
375 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
376
377 // Specific case: only one logged in user or
378 // primary user has primary-only multi-profile policy.
379 if (logged_in_users.size() == 1 ||
380 primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
381 if (primary_user_->can_lock())
382 unlock_users.push_back(primary_user_);
383 } else {
384 // Fill list of potential unlock users based on multi-profile policy state.
385 for (UserList::const_iterator it = logged_in_users.begin();
386 it != logged_in_users.end(); ++it) {
387 User* user = (*it);
388 Profile* profile = GetProfileByUser(user);
389 const std::string behavior =
390 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
391 if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
392 user->can_lock()) {
393 unlock_users.push_back(user);
394 } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
395 NOTREACHED()
396 << "Spotted primary-only multi-profile policy for non-primary user";
397 }
398 }
399 }
400
401 return unlock_users;
402 }
403
GetOwnerEmail()404 const std::string& UserManagerImpl::GetOwnerEmail() {
405 return owner_email_;
406 }
407
UserLoggedIn(const std::string & user_id,const std::string & username_hash,bool browser_restart)408 void UserManagerImpl::UserLoggedIn(const std::string& user_id,
409 const std::string& username_hash,
410 bool browser_restart) {
411 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
412
413 User* user = FindUserInListAndModify(user_id);
414 if (active_user_ && user) {
415 user->set_is_logged_in(true);
416 user->set_username_hash(username_hash);
417 logged_in_users_.push_back(user);
418 lru_logged_in_users_.push_back(user);
419 // Reset the new user flag if the user already exists.
420 is_current_user_new_ = false;
421 NotifyUserAddedToSession(user);
422 // Remember that we need to switch to this user as soon as profile ready.
423 pending_user_switch_ = user_id;
424 return;
425 }
426
427 policy::DeviceLocalAccount::Type device_local_account_type;
428 if (user_id == UserManager::kGuestUserName) {
429 GuestUserLoggedIn();
430 } else if (user_id == UserManager::kRetailModeUserName) {
431 RetailModeUserLoggedIn();
432 } else if (policy::IsDeviceLocalAccountUser(user_id,
433 &device_local_account_type) &&
434 device_local_account_type ==
435 policy::DeviceLocalAccount::TYPE_KIOSK_APP) {
436 KioskAppLoggedIn(user_id);
437 } else if (DemoAppLauncher::IsDemoAppSession(user_id)) {
438 DemoAccountLoggedIn();
439 } else {
440 EnsureUsersLoaded();
441
442 if (user && user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
443 PublicAccountUserLoggedIn(user);
444 } else if ((user && user->GetType() == User::USER_TYPE_LOCALLY_MANAGED) ||
445 (!user && gaia::ExtractDomainName(user_id) ==
446 UserManager::kLocallyManagedUserDomain)) {
447 LocallyManagedUserLoggedIn(user_id);
448 } else if (browser_restart && user_id == g_browser_process->local_state()->
449 GetString(kPublicAccountPendingDataRemoval)) {
450 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id));
451 } else if (user_id != owner_email_ && !user &&
452 (AreEphemeralUsersEnabled() || browser_restart)) {
453 RegularUserLoggedInAsEphemeral(user_id);
454 } else {
455 RegularUserLoggedIn(user_id);
456 }
457
458 // Initialize the session length limiter and start it only if
459 // session limit is defined by the policy.
460 session_length_limiter_.reset(new SessionLengthLimiter(NULL,
461 browser_restart));
462 }
463 DCHECK(active_user_);
464 active_user_->set_is_logged_in(true);
465 active_user_->set_is_active(true);
466 active_user_->set_username_hash(username_hash);
467
468 // Place user who just signed in to the top of the logged in users.
469 logged_in_users_.insert(logged_in_users_.begin(), active_user_);
470 SetLRUUser(active_user_);
471
472 if (!primary_user_) {
473 primary_user_ = active_user_;
474 if (primary_user_->GetType() == User::USER_TYPE_REGULAR)
475 SendRegularUserLoginMetrics(user_id);
476 }
477
478 UMA_HISTOGRAM_ENUMERATION("UserManager.LoginUserType",
479 active_user_->GetType(), User::NUM_USER_TYPES);
480
481 g_browser_process->local_state()->SetString(kLastLoggedInRegularUser,
482 (active_user_->GetType() == User::USER_TYPE_REGULAR) ? user_id : "");
483
484 NotifyOnLogin();
485 }
486
SwitchActiveUser(const std::string & user_id)487 void UserManagerImpl::SwitchActiveUser(const std::string& user_id) {
488 User* user = FindUserAndModify(user_id);
489 if (!user) {
490 NOTREACHED() << "Switching to a non-existing user";
491 return;
492 }
493 if (user == active_user_) {
494 NOTREACHED() << "Switching to a user who is already active";
495 return;
496 }
497 if (!user->is_logged_in()) {
498 NOTREACHED() << "Switching to a user that is not logged in";
499 return;
500 }
501 if (user->GetType() != User::USER_TYPE_REGULAR) {
502 NOTREACHED() << "Switching to a non-regular user";
503 return;
504 }
505 if (user->username_hash().empty()) {
506 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
507 return;
508 }
509
510 DCHECK(active_user_);
511 active_user_->set_is_active(false);
512 user->set_is_active(true);
513 active_user_ = user;
514
515 // Move the user to the front.
516 SetLRUUser(active_user_);
517
518 NotifyActiveUserHashChanged(active_user_->username_hash());
519 NotifyActiveUserChanged(active_user_);
520 }
521
RestoreActiveSessions()522 void UserManagerImpl::RestoreActiveSessions() {
523 DBusThreadManager::Get()->GetSessionManagerClient()->RetrieveActiveSessions(
524 base::Bind(&UserManagerImpl::OnRestoreActiveSessions,
525 base::Unretained(this)));
526 }
527
SessionStarted()528 void UserManagerImpl::SessionStarted() {
529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
530 session_started_ = true;
531 UpdateLoginState();
532 content::NotificationService::current()->Notify(
533 chrome::NOTIFICATION_SESSION_STARTED,
534 content::Source<UserManager>(this),
535 content::Details<const User>(active_user_));
536 if (is_current_user_new_) {
537 // Make sure that the new user's data is persisted to Local State.
538 g_browser_process->local_state()->CommitPendingWrite();
539 }
540 }
541
RemoveUser(const std::string & user_id,RemoveUserDelegate * delegate)542 void UserManagerImpl::RemoveUser(const std::string& user_id,
543 RemoveUserDelegate* delegate) {
544 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
545
546 const User* user = FindUser(user_id);
547 if (!user || (user->GetType() != User::USER_TYPE_REGULAR &&
548 user->GetType() != User::USER_TYPE_LOCALLY_MANAGED))
549 return;
550
551 // Sanity check: we must not remove single user unless it's an enterprise
552 // device. This check may seem redundant at a first sight because
553 // this single user must be an owner and we perform special check later
554 // in order not to remove an owner. However due to non-instant nature of
555 // ownership assignment this later check may sometimes fail.
556 // See http://crosbug.com/12723
557 policy::BrowserPolicyConnectorChromeOS* connector =
558 g_browser_process->platform_part()
559 ->browser_policy_connector_chromeos();
560 if (users_.size() < 2 && !connector->IsEnterpriseManaged())
561 return;
562
563 // Sanity check: do not allow any of the the logged in users to be removed.
564 for (UserList::const_iterator it = logged_in_users_.begin();
565 it != logged_in_users_.end(); ++it) {
566 if ((*it)->email() == user_id)
567 return;
568 }
569
570 RemoveUserInternal(user_id, delegate);
571 }
572
RemoveUserInternal(const std::string & user_email,RemoveUserDelegate * delegate)573 void UserManagerImpl::RemoveUserInternal(const std::string& user_email,
574 RemoveUserDelegate* delegate) {
575 CrosSettings* cros_settings = CrosSettings::Get();
576
577 // Ensure the value of owner email has been fetched.
578 if (CrosSettingsProvider::TRUSTED != cros_settings->PrepareTrustedValues(
579 base::Bind(&UserManagerImpl::RemoveUserInternal,
580 base::Unretained(this),
581 user_email, delegate))) {
582 // Value of owner email is not fetched yet. RemoveUserInternal will be
583 // called again after fetch completion.
584 return;
585 }
586 std::string owner;
587 cros_settings->GetString(kDeviceOwner, &owner);
588 if (user_email == owner) {
589 // Owner is not allowed to be removed from the device.
590 return;
591 }
592 RemoveNonOwnerUserInternal(user_email, delegate);
593 }
594
RemoveNonOwnerUserInternal(const std::string & user_email,RemoveUserDelegate * delegate)595 void UserManagerImpl::RemoveNonOwnerUserInternal(const std::string& user_email,
596 RemoveUserDelegate* delegate) {
597 if (delegate)
598 delegate->OnBeforeUserRemoved(user_email);
599 RemoveUserFromList(user_email);
600 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
601 user_email, base::Bind(&OnRemoveUserComplete, user_email));
602
603 if (delegate)
604 delegate->OnUserRemoved(user_email);
605 }
606
RemoveUserFromList(const std::string & user_id)607 void UserManagerImpl::RemoveUserFromList(const std::string& user_id) {
608 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
609 RemoveNonCryptohomeData(user_id);
610 if (user_loading_stage_ == STAGE_LOADED) {
611 DeleteUser(RemoveRegularOrLocallyManagedUserFromList(user_id));
612 } else if (user_loading_stage_ == STAGE_LOADING) {
613 DCHECK(gaia::ExtractDomainName(user_id) ==
614 UserManager::kLocallyManagedUserDomain);
615 // Special case, removing partially-constructed supervised user during user
616 // list loading.
617 ListPrefUpdate users_update(g_browser_process->local_state(),
618 kRegularUsers);
619 users_update->Remove(base::StringValue(user_id), NULL);
620 } else {
621 NOTREACHED() << "Users are not loaded yet.";
622 return;
623 }
624 // Make sure that new data is persisted to Local State.
625 g_browser_process->local_state()->CommitPendingWrite();
626 }
627
IsKnownUser(const std::string & user_id) const628 bool UserManagerImpl::IsKnownUser(const std::string& user_id) const {
629 return FindUser(user_id) != NULL;
630 }
631
FindUser(const std::string & user_id) const632 const User* UserManagerImpl::FindUser(const std::string& user_id) const {
633 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
634 if (active_user_ && active_user_->email() == user_id)
635 return active_user_;
636 return FindUserInList(user_id);
637 }
638
FindUserAndModify(const std::string & user_id)639 User* UserManagerImpl::FindUserAndModify(const std::string& user_id) {
640 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
641 if (active_user_ && active_user_->email() == user_id)
642 return active_user_;
643 return FindUserInListAndModify(user_id);
644 }
645
GetLoggedInUser() const646 const User* UserManagerImpl::GetLoggedInUser() const {
647 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
648 return active_user_;
649 }
650
GetLoggedInUser()651 User* UserManagerImpl::GetLoggedInUser() {
652 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
653 return active_user_;
654 }
655
GetActiveUser() const656 const User* UserManagerImpl::GetActiveUser() const {
657 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
658 return active_user_;
659 }
660
GetActiveUser()661 User* UserManagerImpl::GetActiveUser() {
662 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
663 return active_user_;
664 }
665
GetPrimaryUser() const666 const User* UserManagerImpl::GetPrimaryUser() const {
667 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
668 return primary_user_;
669 }
670
GetUserByProfile(Profile * profile) const671 User* UserManagerImpl::GetUserByProfile(Profile* profile) const {
672 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
673 if (ProfileHelper::IsSigninProfile(profile))
674 return NULL;
675
676 // Special case for non-CrOS tests that do create several profiles
677 // and don't really care about mapping to the real user.
678 // Without multi-profiles on Chrome OS such tests always got active_user_.
679 // Now these tests will specify special flag to continue working.
680 // In future those tests can get a proper CrOS configuration i.e. register
681 // and login several users if they want to work with an additional profile.
682 if (CommandLine::ForCurrentProcess()->HasSwitch(
683 switches::kIgnoreUserProfileMappingForTests)) {
684 return active_user_;
685 }
686
687 const std::string username_hash =
688 ProfileHelper::GetUserIdHashFromProfile(profile);
689 const UserList& users = GetUsers();
690 const UserList::const_iterator pos = std::find_if(
691 users.begin(), users.end(), UserHashMatcher(username_hash));
692 if (pos != users.end())
693 return *pos;
694
695 // Many tests do not have their users registered with UserManager and
696 // runs here. If |active_user_| matches |profile|, returns it.
697 return active_user_ &&
698 ProfileHelper::GetProfilePathByUserIdHash(
699 active_user_->username_hash()) == profile->GetPath()
700 ? active_user_
701 : NULL;
702 }
703
GetProfileByUser(const User * user) const704 Profile* UserManagerImpl::GetProfileByUser(const User* user) const {
705 Profile* profile = NULL;
706 if (user->is_profile_created())
707 profile = ProfileHelper::GetProfileByUserIdHash(user->username_hash());
708 else
709 profile = ProfileManager::GetActiveUserProfile();
710
711 // GetActiveUserProfile() or GetProfileByUserIdHash() returns a new instance
712 // of ProfileImpl(), but actually its OffTheRecordProfile() should be used.
713 if (profile && IsLoggedInAsGuest())
714 profile = profile->GetOffTheRecordProfile();
715 return profile;
716 }
717
SaveUserOAuthStatus(const std::string & user_id,User::OAuthTokenStatus oauth_token_status)718 void UserManagerImpl::SaveUserOAuthStatus(
719 const std::string& user_id,
720 User::OAuthTokenStatus oauth_token_status) {
721 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
722
723 DVLOG(1) << "Saving user OAuth token status in Local State";
724 User* user = FindUserAndModify(user_id);
725 if (user)
726 user->set_oauth_token_status(oauth_token_status);
727
728 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
729
730 // Do not update local state if data stored or cached outside the user's
731 // cryptohome is to be treated as ephemeral.
732 if (IsUserNonCryptohomeDataEphemeral(user_id))
733 return;
734
735 PrefService* local_state = g_browser_process->local_state();
736
737 DictionaryPrefUpdate oauth_status_update(local_state, kUserOAuthTokenStatus);
738 oauth_status_update->SetWithoutPathExpansion(user_id,
739 new base::FundamentalValue(static_cast<int>(oauth_token_status)));
740 }
741
SaveForceOnlineSignin(const std::string & user_id,bool force_online_signin)742 void UserManagerImpl::SaveForceOnlineSignin(const std::string& user_id,
743 bool force_online_signin) {
744 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
745
746 // Do not update local state if data stored or cached outside the user's
747 // cryptohome is to be treated as ephemeral.
748 if (IsUserNonCryptohomeDataEphemeral(user_id))
749 return;
750
751 DictionaryPrefUpdate force_online_update(g_browser_process->local_state(),
752 kUserForceOnlineSignin);
753 force_online_update->SetBooleanWithoutPathExpansion(user_id,
754 force_online_signin);
755 }
756
SaveUserDisplayName(const std::string & user_id,const base::string16 & display_name)757 void UserManagerImpl::SaveUserDisplayName(const std::string& user_id,
758 const base::string16& display_name) {
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
760
761 if (User* user = FindUserAndModify(user_id)) {
762 user->set_display_name(display_name);
763
764 // Do not update local state if data stored or cached outside the user's
765 // cryptohome is to be treated as ephemeral.
766 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
767 PrefService* local_state = g_browser_process->local_state();
768
769 DictionaryPrefUpdate display_name_update(local_state, kUserDisplayName);
770 display_name_update->SetWithoutPathExpansion(
771 user_id,
772 new base::StringValue(display_name));
773
774 supervised_user_manager_->UpdateManagerName(user_id, display_name);
775 }
776 }
777 }
778
GetUserDisplayName(const std::string & user_id) const779 base::string16 UserManagerImpl::GetUserDisplayName(
780 const std::string& user_id) const {
781 const User* user = FindUser(user_id);
782 return user ? user->display_name() : base::string16();
783 }
784
SaveUserDisplayEmail(const std::string & user_id,const std::string & display_email)785 void UserManagerImpl::SaveUserDisplayEmail(const std::string& user_id,
786 const std::string& display_email) {
787 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
788
789 User* user = FindUserAndModify(user_id);
790 if (!user)
791 return; // Ignore if there is no such user.
792
793 user->set_display_email(display_email);
794
795 // Do not update local state if data stored or cached outside the user's
796 // cryptohome is to be treated as ephemeral.
797 if (IsUserNonCryptohomeDataEphemeral(user_id))
798 return;
799
800 PrefService* local_state = g_browser_process->local_state();
801
802 DictionaryPrefUpdate display_email_update(local_state, kUserDisplayEmail);
803 display_email_update->SetWithoutPathExpansion(
804 user_id,
805 new base::StringValue(display_email));
806 }
807
GetUserDisplayEmail(const std::string & user_id) const808 std::string UserManagerImpl::GetUserDisplayEmail(
809 const std::string& user_id) const {
810 const User* user = FindUser(user_id);
811 return user ? user->display_email() : user_id;
812 }
813
UpdateUserAccountData(const std::string & user_id,const UserAccountData & account_data)814 void UserManagerImpl::UpdateUserAccountData(
815 const std::string& user_id,
816 const UserAccountData& account_data) {
817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
818
819 SaveUserDisplayName(user_id, account_data.display_name());
820
821 if (User* user = FindUserAndModify(user_id)) {
822 base::string16 given_name = account_data.given_name();
823 user->set_given_name(given_name);
824 if (!IsUserNonCryptohomeDataEphemeral(user_id)) {
825 PrefService* local_state = g_browser_process->local_state();
826
827 DictionaryPrefUpdate given_name_update(local_state, kUserGivenName);
828 given_name_update->SetWithoutPathExpansion(
829 user_id,
830 new base::StringValue(given_name));
831 }
832 }
833
834 UpdateUserAccountLocale(user_id, account_data.locale());
835 }
836
837 // TODO(alemate): http://crbug.com/288941 : Respect preferred language list in
838 // the Google user profile.
839 //
840 // Returns true if callback will be called.
RespectLocalePreference(Profile * profile,const User * user,scoped_ptr<locale_util::SwitchLanguageCallback> callback) const841 bool UserManagerImpl::RespectLocalePreference(
842 Profile* profile,
843 const User* user,
844 scoped_ptr<locale_util::SwitchLanguageCallback> callback) const {
845 if (g_browser_process == NULL)
846 return false;
847 if ((user == NULL) || (user != GetPrimaryUser()) ||
848 (!user->is_profile_created()))
849 return false;
850
851 // In case of Multi Profile mode we don't apply profile locale because it is
852 // unsafe.
853 if (GetLoggedInUsers().size() != 1)
854 return false;
855 const PrefService* prefs = profile->GetPrefs();
856 if (prefs == NULL)
857 return false;
858
859 std::string pref_locale;
860 const std::string pref_app_locale =
861 prefs->GetString(prefs::kApplicationLocale);
862 const std::string pref_bkup_locale =
863 prefs->GetString(prefs::kApplicationLocaleBackup);
864
865 pref_locale = pref_app_locale;
866 if (pref_locale.empty())
867 pref_locale = pref_bkup_locale;
868
869 const std::string* account_locale = NULL;
870 if (pref_locale.empty() && user->has_gaia_account()) {
871 if (user->GetAccountLocale() == NULL)
872 return false; // wait until Account profile is loaded.
873 account_locale = user->GetAccountLocale();
874 pref_locale = *account_locale;
875 }
876 const std::string global_app_locale =
877 g_browser_process->GetApplicationLocale();
878 if (pref_locale.empty())
879 pref_locale = global_app_locale;
880 DCHECK(!pref_locale.empty());
881 LOG(WARNING) << "RespectLocalePreference: "
882 << "app_locale='" << pref_app_locale << "', "
883 << "bkup_locale='" << pref_bkup_locale << "', "
884 << (account_locale != NULL
885 ? (std::string("account_locale='") + (*account_locale) +
886 "'. ")
887 : (std::string("account_locale - unused. ")))
888 << " Selected '" << pref_locale << "'";
889 profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN);
890
891 // Here we don't enable keyboard layouts for normal users. Input methods
892 // are set up when the user first logs in. Then the user may customize the
893 // input methods. Hence changing input methods here, just because the user's
894 // UI language is different from the login screen UI language, is not
895 // desirable. Note that input method preferences are synced, so users can use
896 // their farovite input methods as soon as the preferences are synced.
897 //
898 // For Guest mode, user locale preferences will never get initialized.
899 // So input methods should be enabled somewhere.
900 const bool enable_layouts = UserManager::Get()->IsLoggedInAsGuest();
901 locale_util::SwitchLanguage(pref_locale,
902 enable_layouts,
903 false /* login_layouts_only */,
904 callback.Pass());
905
906 return true;
907 }
908
StopPolicyObserverForTesting()909 void UserManagerImpl::StopPolicyObserverForTesting() {
910 avatar_policy_observer_.reset();
911 wallpaper_policy_observer_.reset();
912 }
913
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)914 void UserManagerImpl::Observe(int type,
915 const content::NotificationSource& source,
916 const content::NotificationDetails& details) {
917 switch (type) {
918 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
919 if (!device_local_account_policy_service_) {
920 policy::BrowserPolicyConnectorChromeOS* connector =
921 g_browser_process->platform_part()
922 ->browser_policy_connector_chromeos();
923 device_local_account_policy_service_ =
924 connector->GetDeviceLocalAccountPolicyService();
925 if (device_local_account_policy_service_)
926 device_local_account_policy_service_->AddObserver(this);
927 }
928 RetrieveTrustedDevicePolicies();
929 UpdateOwnership();
930 break;
931 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
932 Profile* profile = content::Details<Profile>(details).ptr();
933 if (IsUserLoggedIn() &&
934 !IsLoggedInAsGuest() &&
935 !IsLoggedInAsKioskApp()) {
936 if (IsLoggedInAsLocallyManagedUser())
937 SupervisedUserPasswordServiceFactory::GetForProfile(profile);
938 if (IsLoggedInAsRegularUser())
939 ManagerPasswordServiceFactory::GetForProfile(profile);
940
941 if (!profile->IsOffTheRecord()) {
942 AuthSyncObserver* sync_observer =
943 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
944 sync_observer->StartObserving();
945 multi_profile_user_controller_->StartObserving(profile);
946 }
947 }
948
949 // Now that the user profile has been initialized and
950 // |GetNSSCertDatabaseForProfile| is safe to be used, get the NSS cert
951 // database for the primary user and start certificate loader with it.
952 if (IsUserLoggedIn() &&
953 GetPrimaryUser() &&
954 profile == GetProfileByUser(GetPrimaryUser()) &&
955 CertLoader::IsInitialized() &&
956 base::SysInfo::IsRunningOnChromeOS()) {
957 GetNSSCertDatabaseForProfile(profile,
958 base::Bind(&OnGetNSSCertDatabaseForUser));
959 }
960 break;
961 }
962 case chrome::NOTIFICATION_PROFILE_CREATED: {
963 Profile* profile = content::Source<Profile>(source).ptr();
964 User* user = GetUserByProfile(profile);
965 if (user != NULL)
966 user->set_profile_is_created();
967 // If there is pending user switch, do it now.
968 if (!pending_user_switch_.empty()) {
969 // Call SwitchActiveUser async because otherwise it may cause
970 // ProfileManager::GetProfile before the profile gets registered
971 // in ProfileManager. It happens in case of sync profile load when
972 // NOTIFICATION_PROFILE_CREATED is called synchronously.
973 base::MessageLoop::current()->PostTask(FROM_HERE,
974 base::Bind(&UserManagerImpl::SwitchActiveUser,
975 base::Unretained(this),
976 pending_user_switch_));
977 pending_user_switch_.clear();
978 }
979 break;
980 }
981 default:
982 NOTREACHED();
983 }
984 }
985
OnExternalDataSet(const std::string & policy,const std::string & user_id)986 void UserManagerImpl::OnExternalDataSet(const std::string& policy,
987 const std::string& user_id) {
988 if (policy == policy::key::kUserAvatarImage)
989 GetUserImageManager(user_id)->OnExternalDataSet(policy);
990 else if (policy == policy::key::kWallpaperImage)
991 WallpaperManager::Get()->OnPolicySet(policy, user_id);
992 else
993 NOTREACHED();
994 }
995
OnExternalDataCleared(const std::string & policy,const std::string & user_id)996 void UserManagerImpl::OnExternalDataCleared(const std::string& policy,
997 const std::string& user_id) {
998 if (policy == policy::key::kUserAvatarImage)
999 GetUserImageManager(user_id)->OnExternalDataCleared(policy);
1000 else if (policy == policy::key::kWallpaperImage)
1001 WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
1002 else
1003 NOTREACHED();
1004 }
1005
OnExternalDataFetched(const std::string & policy,const std::string & user_id,scoped_ptr<std::string> data)1006 void UserManagerImpl::OnExternalDataFetched(const std::string& policy,
1007 const std::string& user_id,
1008 scoped_ptr<std::string> data) {
1009 if (policy == policy::key::kUserAvatarImage)
1010 GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
1011 else if (policy == policy::key::kWallpaperImage)
1012 WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
1013 else
1014 NOTREACHED();
1015 }
1016
OnPolicyUpdated(const std::string & user_id)1017 void UserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
1018 const User* user = FindUserInList(user_id);
1019 if (!user || user->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
1020 return;
1021 UpdatePublicAccountDisplayName(user_id);
1022 NotifyUserListChanged();
1023 }
1024
OnDeviceLocalAccountsChanged()1025 void UserManagerImpl::OnDeviceLocalAccountsChanged() {
1026 // No action needed here, changes to the list of device-local accounts get
1027 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
1028 }
1029
IsCurrentUserOwner() const1030 bool UserManagerImpl::IsCurrentUserOwner() const {
1031 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1032 base::AutoLock lk(is_current_user_owner_lock_);
1033 return is_current_user_owner_;
1034 }
1035
SetCurrentUserIsOwner(bool is_current_user_owner)1036 void UserManagerImpl::SetCurrentUserIsOwner(bool is_current_user_owner) {
1037 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1038 {
1039 base::AutoLock lk(is_current_user_owner_lock_);
1040 is_current_user_owner_ = is_current_user_owner;
1041 }
1042 UpdateLoginState();
1043 }
1044
IsCurrentUserNew() const1045 bool UserManagerImpl::IsCurrentUserNew() const {
1046 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1047 return is_current_user_new_;
1048 }
1049
IsCurrentUserNonCryptohomeDataEphemeral() const1050 bool UserManagerImpl::IsCurrentUserNonCryptohomeDataEphemeral() const {
1051 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1052 return IsUserLoggedIn() &&
1053 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
1054 }
1055
CanCurrentUserLock() const1056 bool UserManagerImpl::CanCurrentUserLock() const {
1057 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1058 return IsUserLoggedIn() && active_user_->can_lock() &&
1059 GetCurrentUserFlow()->CanLockScreen();
1060 }
1061
IsUserLoggedIn() const1062 bool UserManagerImpl::IsUserLoggedIn() const {
1063 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1064 return active_user_;
1065 }
1066
IsLoggedInAsRegularUser() const1067 bool UserManagerImpl::IsLoggedInAsRegularUser() const {
1068 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1069 return IsUserLoggedIn() &&
1070 active_user_->GetType() == User::USER_TYPE_REGULAR;
1071 }
1072
IsLoggedInAsDemoUser() const1073 bool UserManagerImpl::IsLoggedInAsDemoUser() const {
1074 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1075 return IsUserLoggedIn() &&
1076 active_user_->GetType() == User::USER_TYPE_RETAIL_MODE;
1077 }
1078
IsLoggedInAsPublicAccount() const1079 bool UserManagerImpl::IsLoggedInAsPublicAccount() const {
1080 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1081 return IsUserLoggedIn() &&
1082 active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT;
1083 }
1084
IsLoggedInAsGuest() const1085 bool UserManagerImpl::IsLoggedInAsGuest() const {
1086 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1087 return IsUserLoggedIn() &&
1088 active_user_->GetType() == User::USER_TYPE_GUEST;
1089 }
1090
IsLoggedInAsLocallyManagedUser() const1091 bool UserManagerImpl::IsLoggedInAsLocallyManagedUser() const {
1092 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1093 return IsUserLoggedIn() &&
1094 active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED;
1095 }
1096
IsLoggedInAsKioskApp() const1097 bool UserManagerImpl::IsLoggedInAsKioskApp() const {
1098 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1099 return IsUserLoggedIn() &&
1100 active_user_->GetType() == User::USER_TYPE_KIOSK_APP;
1101 }
1102
IsLoggedInAsStub() const1103 bool UserManagerImpl::IsLoggedInAsStub() const {
1104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1105 return IsUserLoggedIn() && active_user_->email() == kStubUser;
1106 }
1107
IsSessionStarted() const1108 bool UserManagerImpl::IsSessionStarted() const {
1109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1110 return session_started_;
1111 }
1112
UserSessionsRestored() const1113 bool UserManagerImpl::UserSessionsRestored() const {
1114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1115 return user_sessions_restored_;
1116 }
1117
HasBrowserRestarted() const1118 bool UserManagerImpl::HasBrowserRestarted() const {
1119 CommandLine* command_line = CommandLine::ForCurrentProcess();
1120 return base::SysInfo::IsRunningOnChromeOS() &&
1121 command_line->HasSwitch(switches::kLoginUser) &&
1122 !command_line->HasSwitch(switches::kLoginPassword);
1123 }
1124
IsUserNonCryptohomeDataEphemeral(const std::string & user_id) const1125 bool UserManagerImpl::IsUserNonCryptohomeDataEphemeral(
1126 const std::string& user_id) const {
1127 // Data belonging to the guest, retail mode and stub users is always
1128 // ephemeral.
1129 if (user_id == UserManager::kGuestUserName ||
1130 user_id == UserManager::kRetailModeUserName ||
1131 user_id == kStubUser) {
1132 return true;
1133 }
1134
1135 // Data belonging to the owner, anyone found on the user list and obsolete
1136 // public accounts whose data has not been removed yet is not ephemeral.
1137 if (user_id == owner_email_ || UserExistsInList(user_id) ||
1138 user_id == g_browser_process->local_state()->
1139 GetString(kPublicAccountPendingDataRemoval)) {
1140 return false;
1141 }
1142
1143 // Data belonging to the currently logged-in user is ephemeral when:
1144 // a) The user logged into a regular account while the ephemeral users policy
1145 // was enabled.
1146 // - or -
1147 // b) The user logged into any other account type.
1148 if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) &&
1149 (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) {
1150 return true;
1151 }
1152
1153 // Data belonging to any other user is ephemeral when:
1154 // a) Going through the regular login flow and the ephemeral users policy is
1155 // enabled.
1156 // - or -
1157 // b) The browser is restarting after a crash.
1158 return AreEphemeralUsersEnabled() || HasBrowserRestarted();
1159 }
1160
AddObserver(UserManager::Observer * obs)1161 void UserManagerImpl::AddObserver(UserManager::Observer* obs) {
1162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1163 observer_list_.AddObserver(obs);
1164 }
1165
RemoveObserver(UserManager::Observer * obs)1166 void UserManagerImpl::RemoveObserver(UserManager::Observer* obs) {
1167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1168 observer_list_.RemoveObserver(obs);
1169 }
1170
AddSessionStateObserver(UserManager::UserSessionStateObserver * obs)1171 void UserManagerImpl::AddSessionStateObserver(
1172 UserManager::UserSessionStateObserver* obs) {
1173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1174 session_state_observer_list_.AddObserver(obs);
1175 }
1176
RemoveSessionStateObserver(UserManager::UserSessionStateObserver * obs)1177 void UserManagerImpl::RemoveSessionStateObserver(
1178 UserManager::UserSessionStateObserver* obs) {
1179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1180 session_state_observer_list_.RemoveObserver(obs);
1181 }
1182
NotifyLocalStateChanged()1183 void UserManagerImpl::NotifyLocalStateChanged() {
1184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1185 FOR_EACH_OBSERVER(UserManager::Observer, observer_list_,
1186 LocalStateChanged(this));
1187 }
1188
OnProfilePrepared(Profile * profile)1189 void UserManagerImpl::OnProfilePrepared(Profile* profile) {
1190 LoginUtils::Get()->DoBrowserLaunch(profile,
1191 NULL); // host_, not needed here
1192
1193 if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
1194 // Did not log in (we crashed or are debugging), need to restore Sync.
1195 // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
1196 // users once it is fully multi-profile aware. http://crbug.com/238987
1197 // For now if we have other user pending sessions they'll override OAuth
1198 // session restore for previous users.
1199 SessionManager::GetInstance()->RestoreAuthenticationSession(profile);
1200 }
1201
1202 // Restore other user sessions if any.
1203 RestorePendingUserSessions();
1204 }
1205
EnsureUsersLoaded()1206 void UserManagerImpl::EnsureUsersLoaded() {
1207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1208 if (!g_browser_process || !g_browser_process->local_state())
1209 return;
1210
1211 if (user_loading_stage_ != STAGE_NOT_LOADED)
1212 return;
1213 user_loading_stage_ = STAGE_LOADING;
1214 // Clean up user list first. All code down the path should be synchronous,
1215 // so that local state after transaction rollback is in consistent state.
1216 // This process also should not trigger EnsureUsersLoaded again.
1217 if (supervised_user_manager_->HasFailedUserCreationTransaction())
1218 supervised_user_manager_->RollbackUserCreationTransaction();
1219
1220 PrefService* local_state = g_browser_process->local_state();
1221 const base::ListValue* prefs_regular_users =
1222 local_state->GetList(kRegularUsers);
1223 const base::ListValue* prefs_public_sessions =
1224 local_state->GetList(kPublicAccounts);
1225 const base::DictionaryValue* prefs_display_names =
1226 local_state->GetDictionary(kUserDisplayName);
1227 const base::DictionaryValue* prefs_given_names =
1228 local_state->GetDictionary(kUserGivenName);
1229 const base::DictionaryValue* prefs_display_emails =
1230 local_state->GetDictionary(kUserDisplayEmail);
1231
1232 // Load public sessions first.
1233 std::vector<std::string> public_sessions;
1234 std::set<std::string> public_sessions_set;
1235 ParseUserList(*prefs_public_sessions, std::set<std::string>(),
1236 &public_sessions, &public_sessions_set);
1237 for (std::vector<std::string>::const_iterator it = public_sessions.begin();
1238 it != public_sessions.end(); ++it) {
1239 users_.push_back(User::CreatePublicAccountUser(*it));
1240 UpdatePublicAccountDisplayName(*it);
1241 }
1242
1243 // Load regular users and locally managed users.
1244 std::vector<std::string> regular_users;
1245 std::set<std::string> regular_users_set;
1246 ParseUserList(*prefs_regular_users, public_sessions_set,
1247 ®ular_users, ®ular_users_set);
1248 for (std::vector<std::string>::const_iterator it = regular_users.begin();
1249 it != regular_users.end(); ++it) {
1250 User* user = NULL;
1251 const std::string domain = gaia::ExtractDomainName(*it);
1252 if (domain == UserManager::kLocallyManagedUserDomain)
1253 user = User::CreateLocallyManagedUser(*it);
1254 else
1255 user = User::CreateRegularUser(*it);
1256 user->set_oauth_token_status(LoadUserOAuthStatus(*it));
1257 user->set_force_online_signin(LoadForceOnlineSignin(*it));
1258 users_.push_back(user);
1259
1260 base::string16 display_name;
1261 if (prefs_display_names->GetStringWithoutPathExpansion(*it,
1262 &display_name)) {
1263 user->set_display_name(display_name);
1264 }
1265
1266 base::string16 given_name;
1267 if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) {
1268 user->set_given_name(given_name);
1269 }
1270
1271 std::string display_email;
1272 if (prefs_display_emails->GetStringWithoutPathExpansion(*it,
1273 &display_email)) {
1274 user->set_display_email(display_email);
1275 }
1276 }
1277
1278 user_loading_stage_ = STAGE_LOADED;
1279
1280 for (UserList::iterator ui = users_.begin(), ue = users_.end();
1281 ui != ue; ++ui) {
1282 GetUserImageManager((*ui)->email())->LoadUserImage();
1283 }
1284 }
1285
RetrieveTrustedDevicePolicies()1286 void UserManagerImpl::RetrieveTrustedDevicePolicies() {
1287 ephemeral_users_enabled_ = false;
1288 owner_email_.clear();
1289
1290 // Schedule a callback if device policy has not yet been verified.
1291 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
1292 base::Bind(&UserManagerImpl::RetrieveTrustedDevicePolicies,
1293 base::Unretained(this)))) {
1294 return;
1295 }
1296
1297 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
1298 &ephemeral_users_enabled_);
1299 cros_settings_->GetString(kDeviceOwner, &owner_email_);
1300
1301 EnsureUsersLoaded();
1302
1303 bool changed = UpdateAndCleanUpPublicAccounts(
1304 policy::GetDeviceLocalAccounts(cros_settings_));
1305
1306 // If ephemeral users are enabled and we are on the login screen, take this
1307 // opportunity to clean up by removing all regular users except the owner.
1308 if (ephemeral_users_enabled_ && !IsUserLoggedIn()) {
1309 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1310 kRegularUsers);
1311 prefs_users_update->Clear();
1312 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1313 const std::string user_email = (*it)->email();
1314 if ((*it)->GetType() == User::USER_TYPE_REGULAR &&
1315 user_email != owner_email_) {
1316 RemoveNonCryptohomeData(user_email);
1317 DeleteUser(*it);
1318 it = users_.erase(it);
1319 changed = true;
1320 } else {
1321 if ((*it)->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
1322 prefs_users_update->Append(new base::StringValue(user_email));
1323 ++it;
1324 }
1325 }
1326 }
1327
1328 if (changed)
1329 NotifyUserListChanged();
1330 }
1331
AreEphemeralUsersEnabled() const1332 bool UserManagerImpl::AreEphemeralUsersEnabled() const {
1333 policy::BrowserPolicyConnectorChromeOS* connector =
1334 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1335 return ephemeral_users_enabled_ &&
1336 (connector->IsEnterpriseManaged() || !owner_email_.empty());
1337 }
1338
GetUsersAndModify()1339 UserList& UserManagerImpl::GetUsersAndModify() {
1340 EnsureUsersLoaded();
1341 return users_;
1342 }
1343
FindUserInList(const std::string & user_id) const1344 const User* UserManagerImpl::FindUserInList(const std::string& user_id) const {
1345 const UserList& users = GetUsers();
1346 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
1347 if ((*it)->email() == user_id)
1348 return *it;
1349 }
1350 return NULL;
1351 }
1352
UserExistsInList(const std::string & user_id) const1353 const bool UserManagerImpl::UserExistsInList(const std::string& user_id) const {
1354 PrefService* local_state = g_browser_process->local_state();
1355 const base::ListValue* user_list = local_state->GetList(kRegularUsers);
1356 for (size_t i = 0; i < user_list->GetSize(); ++i) {
1357 std::string email;
1358 if (user_list->GetString(i, &email) && (user_id == email))
1359 return true;
1360 }
1361 return false;
1362 }
1363
FindUserInListAndModify(const std::string & user_id)1364 User* UserManagerImpl::FindUserInListAndModify(const std::string& user_id) {
1365 UserList& users = GetUsersAndModify();
1366 for (UserList::iterator it = users.begin(); it != users.end(); ++it) {
1367 if ((*it)->email() == user_id)
1368 return *it;
1369 }
1370 return NULL;
1371 }
1372
GuestUserLoggedIn()1373 void UserManagerImpl::GuestUserLoggedIn() {
1374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1375 active_user_ = User::CreateGuestUser();
1376 // TODO(nkostylev): Add support for passing guest session cryptohome
1377 // mount point. Legacy (--login-profile) value will be used for now.
1378 // http://crosbug.com/230859
1379 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1380 // Initializes wallpaper after active_user_ is set.
1381 WallpaperManager::Get()->SetUserWallpaperNow(UserManager::kGuestUserName);
1382 }
1383
AddUserRecord(User * user)1384 void UserManagerImpl::AddUserRecord(User* user) {
1385 // Add the user to the front of the user list.
1386 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1387 kRegularUsers);
1388 prefs_users_update->Insert(0, new base::StringValue(user->email()));
1389 users_.insert(users_.begin(), user);
1390 }
1391
RegularUserLoggedIn(const std::string & user_id)1392 void UserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
1393 // Remove the user from the user list.
1394 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1395
1396 // If the user was not found on the user list, create a new user.
1397 is_current_user_new_ = !active_user_;
1398 if (!active_user_) {
1399 active_user_ = User::CreateRegularUser(user_id);
1400 active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id));
1401 SaveUserDisplayName(active_user_->email(),
1402 base::UTF8ToUTF16(active_user_->GetAccountName(true)));
1403 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1404 }
1405
1406 AddUserRecord(active_user_);
1407
1408 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1409
1410 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1411
1412 // Make sure that new data is persisted to Local State.
1413 g_browser_process->local_state()->CommitPendingWrite();
1414 }
1415
RegularUserLoggedInAsEphemeral(const std::string & user_id)1416 void UserManagerImpl::RegularUserLoggedInAsEphemeral(
1417 const std::string& user_id) {
1418 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1419 is_current_user_new_ = true;
1420 is_current_user_ephemeral_regular_user_ = true;
1421 active_user_ = User::CreateRegularUser(user_id);
1422 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, false);
1423 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1424 }
1425
LocallyManagedUserLoggedIn(const std::string & user_id)1426 void UserManagerImpl::LocallyManagedUserLoggedIn(
1427 const std::string& user_id) {
1428 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
1429
1430 // Remove the user from the user list.
1431 active_user_ = RemoveRegularOrLocallyManagedUserFromList(user_id);
1432 // If the user was not found on the user list, create a new user.
1433 if (!active_user_) {
1434 is_current_user_new_ = true;
1435 active_user_ = User::CreateLocallyManagedUser(user_id);
1436 // Leaving OAuth token status at the default state = unknown.
1437 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1438 } else {
1439 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
1440 is_current_user_new_ = true;
1441 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
1442 } else {
1443 is_current_user_new_ = false;
1444 }
1445 }
1446
1447 // Add the user to the front of the user list.
1448 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1449 kRegularUsers);
1450 prefs_users_update->Insert(0, new base::StringValue(user_id));
1451 users_.insert(users_.begin(), active_user_);
1452
1453 // Now that user is in the list, save display name.
1454 if (is_current_user_new_) {
1455 SaveUserDisplayName(active_user_->email(),
1456 active_user_->GetDisplayName());
1457 }
1458
1459 GetUserImageManager(user_id)->UserLoggedIn(is_current_user_new_, true);
1460 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1461
1462 // Make sure that new data is persisted to Local State.
1463 g_browser_process->local_state()->CommitPendingWrite();
1464 }
1465
PublicAccountUserLoggedIn(User * user)1466 void UserManagerImpl::PublicAccountUserLoggedIn(User* user) {
1467 is_current_user_new_ = true;
1468 active_user_ = user;
1469 // The UserImageManager chooses a random avatar picture when a user logs in
1470 // for the first time. Tell the UserImageManager that this user is not new to
1471 // prevent the avatar from getting changed.
1472 GetUserImageManager(user->email())->UserLoggedIn(false, true);
1473 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
1474 }
1475
KioskAppLoggedIn(const std::string & app_id)1476 void UserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
1477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1478 policy::DeviceLocalAccount::Type device_local_account_type;
1479 DCHECK(policy::IsDeviceLocalAccountUser(app_id,
1480 &device_local_account_type));
1481 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
1482 device_local_account_type);
1483
1484 active_user_ = User::CreateKioskAppUser(app_id);
1485 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1486
1487 WallpaperManager::Get()->SetUserWallpaperNow(app_id);
1488
1489 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
1490 // the kiosk_app_id in these objects, removing the need to re-parse the
1491 // device-local account list here to extract the kiosk_app_id.
1492 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
1493 policy::GetDeviceLocalAccounts(cros_settings_);
1494 const policy::DeviceLocalAccount* account = NULL;
1495 for (std::vector<policy::DeviceLocalAccount>::const_iterator
1496 it = device_local_accounts.begin();
1497 it != device_local_accounts.end(); ++it) {
1498 if (it->user_id == app_id) {
1499 account = &*it;
1500 break;
1501 }
1502 }
1503 std::string kiosk_app_id;
1504 if (account) {
1505 kiosk_app_id = account->kiosk_app_id;
1506 } else {
1507 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
1508 NOTREACHED();
1509 }
1510
1511 CommandLine* command_line = CommandLine::ForCurrentProcess();
1512 command_line->AppendSwitch(::switches::kForceAppMode);
1513 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
1514
1515 // Disable window animation since kiosk app runs in a single full screen
1516 // window and window animation causes start-up janks.
1517 command_line->AppendSwitch(
1518 wm::switches::kWindowAnimationsDisabled);
1519 }
1520
DemoAccountLoggedIn()1521 void UserManagerImpl::DemoAccountLoggedIn() {
1522 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1523 active_user_ = User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
1524 active_user_->SetStubImage(User::kInvalidImageIndex, false);
1525 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
1526
1527 CommandLine* command_line = CommandLine::ForCurrentProcess();
1528 command_line->AppendSwitch(::switches::kForceAppMode);
1529 command_line->AppendSwitchASCII(::switches::kAppId,
1530 DemoAppLauncher::kDemoAppId);
1531
1532 // Disable window animation since the demo app runs in a single full screen
1533 // window and window animation causes start-up janks.
1534 CommandLine::ForCurrentProcess()->AppendSwitch(
1535 wm::switches::kWindowAnimationsDisabled);
1536 }
1537
RetailModeUserLoggedIn()1538 void UserManagerImpl::RetailModeUserLoggedIn() {
1539 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1540 is_current_user_new_ = true;
1541 active_user_ = User::CreateRetailModeUser();
1542 GetUserImageManager(UserManager::kRetailModeUserName)->UserLoggedIn(
1543 is_current_user_new_,
1544 true);
1545 WallpaperManager::Get()->SetUserWallpaperNow(
1546 UserManager::kRetailModeUserName);
1547 }
1548
NotifyOnLogin()1549 void UserManagerImpl::NotifyOnLogin() {
1550 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1551
1552 // Override user homedir, check for ProfileManager being initialized as
1553 // it may not exist in unit tests.
1554 if (g_browser_process->profile_manager()) {
1555 if (GetLoggedInUsers().size() == 1) {
1556 base::FilePath homedir = ProfileHelper::GetProfilePathByUserIdHash(
1557 primary_user_->username_hash());
1558 // This path has been either created by cryptohome (on real Chrome OS
1559 // device) or by ProfileManager (on chromeos=1 desktop builds).
1560 PathService::OverrideAndCreateIfNeeded(base::DIR_HOME,
1561 homedir,
1562 true /* path is absolute */,
1563 false /* don't create */);
1564 }
1565 }
1566
1567 UpdateNumberOfUsers();
1568 NotifyActiveUserHashChanged(active_user_->username_hash());
1569 NotifyActiveUserChanged(active_user_);
1570 UpdateLoginState();
1571
1572 // TODO(nkostylev): Deprecate this notification in favor of
1573 // ActiveUserChanged() observer call.
1574 content::NotificationService::current()->Notify(
1575 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
1576 content::Source<UserManager>(this),
1577 content::Details<const User>(active_user_));
1578
1579 // Owner must be first user in session. DeviceSettingsService can't deal with
1580 // multiple user and will mix up ownership, crbug.com/230018.
1581 if (GetLoggedInUsers().size() == 1) {
1582 OwnerSettingsServiceFactory::GetInstance()->SetUsername(
1583 active_user_->email());
1584 if (NetworkPortalDetector::IsInitialized()) {
1585 NetworkPortalDetector::Get()->SetStrategy(
1586 PortalDetectorStrategy::STRATEGY_ID_SESSION);
1587 }
1588 }
1589 }
1590
LoadUserOAuthStatus(const std::string & user_id) const1591 User::OAuthTokenStatus UserManagerImpl::LoadUserOAuthStatus(
1592 const std::string& user_id) const {
1593 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1594
1595 PrefService* local_state = g_browser_process->local_state();
1596 const base::DictionaryValue* prefs_oauth_status =
1597 local_state->GetDictionary(kUserOAuthTokenStatus);
1598 int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN;
1599 if (prefs_oauth_status &&
1600 prefs_oauth_status->GetIntegerWithoutPathExpansion(
1601 user_id, &oauth_token_status)) {
1602 User::OAuthTokenStatus result =
1603 static_cast<User::OAuthTokenStatus>(oauth_token_status);
1604 if (result == User::OAUTH2_TOKEN_STATUS_INVALID)
1605 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(result);
1606 return result;
1607 }
1608 return User::OAUTH_TOKEN_STATUS_UNKNOWN;
1609 }
1610
LoadForceOnlineSignin(const std::string & user_id) const1611 bool UserManagerImpl::LoadForceOnlineSignin(const std::string& user_id) const {
1612 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1613
1614 PrefService* local_state = g_browser_process->local_state();
1615 const base::DictionaryValue* prefs_force_online =
1616 local_state->GetDictionary(kUserForceOnlineSignin);
1617 bool force_online_signin = false;
1618 if (prefs_force_online) {
1619 prefs_force_online->GetBooleanWithoutPathExpansion(user_id,
1620 &force_online_signin);
1621 }
1622 return force_online_signin;
1623 }
1624
UpdateOwnership()1625 void UserManagerImpl::UpdateOwnership() {
1626 bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
1627 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
1628
1629 SetCurrentUserIsOwner(is_owner);
1630 }
1631
RemoveNonCryptohomeData(const std::string & user_id)1632 void UserManagerImpl::RemoveNonCryptohomeData(const std::string& user_id) {
1633 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
1634 GetUserImageManager(user_id)->DeleteUserImage();
1635
1636 PrefService* prefs = g_browser_process->local_state();
1637 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName);
1638 prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1639
1640 DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName);
1641 prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL);
1642
1643 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail);
1644 prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL);
1645
1646 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus);
1647 prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL);
1648
1649 DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin);
1650 prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL);
1651
1652 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
1653
1654 multi_profile_user_controller_->RemoveCachedValues(user_id);
1655 }
1656
RemoveRegularOrLocallyManagedUserFromList(const std::string & user_id)1657 User* UserManagerImpl::RemoveRegularOrLocallyManagedUserFromList(
1658 const std::string& user_id) {
1659 ListPrefUpdate prefs_users_update(g_browser_process->local_state(),
1660 kRegularUsers);
1661 prefs_users_update->Clear();
1662 User* user = NULL;
1663 for (UserList::iterator it = users_.begin(); it != users_.end(); ) {
1664 const std::string user_email = (*it)->email();
1665 if (user_email == user_id) {
1666 user = *it;
1667 it = users_.erase(it);
1668 } else {
1669 if ((*it)->GetType() == User::USER_TYPE_REGULAR ||
1670 (*it)->GetType() == User::USER_TYPE_LOCALLY_MANAGED) {
1671 prefs_users_update->Append(new base::StringValue(user_email));
1672 }
1673 ++it;
1674 }
1675 }
1676 return user;
1677 }
1678
CleanUpPublicAccountNonCryptohomeDataPendingRemoval()1679 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
1680 PrefService* local_state = g_browser_process->local_state();
1681 const std::string public_account_pending_data_removal =
1682 local_state->GetString(kPublicAccountPendingDataRemoval);
1683 if (public_account_pending_data_removal.empty() ||
1684 (IsUserLoggedIn() &&
1685 public_account_pending_data_removal == GetActiveUser()->email())) {
1686 return;
1687 }
1688
1689 RemoveNonCryptohomeData(public_account_pending_data_removal);
1690 local_state->ClearPref(kPublicAccountPendingDataRemoval);
1691 }
1692
CleanUpPublicAccountNonCryptohomeData(const std::vector<std::string> & old_public_accounts)1693 void UserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
1694 const std::vector<std::string>& old_public_accounts) {
1695 std::set<std::string> users;
1696 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it)
1697 users.insert((*it)->email());
1698
1699 // If the user is logged into a public account that has been removed from the
1700 // user list, mark the account's data as pending removal after logout.
1701 if (IsLoggedInAsPublicAccount()) {
1702 const std::string active_user_id = GetActiveUser()->email();
1703 if (users.find(active_user_id) == users.end()) {
1704 g_browser_process->local_state()->SetString(
1705 kPublicAccountPendingDataRemoval, active_user_id);
1706 users.insert(active_user_id);
1707 }
1708 }
1709
1710 // Remove the data belonging to any other public accounts that are no longer
1711 // found on the user list.
1712 for (std::vector<std::string>::const_iterator
1713 it = old_public_accounts.begin();
1714 it != old_public_accounts.end(); ++it) {
1715 if (users.find(*it) == users.end())
1716 RemoveNonCryptohomeData(*it);
1717 }
1718 }
1719
UpdateAndCleanUpPublicAccounts(const std::vector<policy::DeviceLocalAccount> & device_local_accounts)1720 bool UserManagerImpl::UpdateAndCleanUpPublicAccounts(
1721 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
1722 // Try to remove any public account data marked as pending removal.
1723 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
1724
1725 // Get the current list of public accounts.
1726 std::vector<std::string> old_public_accounts;
1727 for (UserList::const_iterator it = users_.begin(); it != users_.end(); ++it) {
1728 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1729 old_public_accounts.push_back((*it)->email());
1730 }
1731
1732 // Get the new list of public accounts from policy.
1733 std::vector<std::string> new_public_accounts;
1734 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
1735 device_local_accounts.begin();
1736 it != device_local_accounts.end(); ++it) {
1737 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
1738 // standard login framework: http://crbug.com/234694
1739 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
1740 new_public_accounts.push_back(it->user_id);
1741 }
1742
1743 // If the list of public accounts has not changed, return.
1744 if (new_public_accounts.size() == old_public_accounts.size()) {
1745 bool changed = false;
1746 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
1747 if (new_public_accounts[i] != old_public_accounts[i]) {
1748 changed = true;
1749 break;
1750 }
1751 }
1752 if (!changed)
1753 return false;
1754 }
1755
1756 // Persist the new list of public accounts in a pref.
1757 ListPrefUpdate prefs_public_accounts_update(g_browser_process->local_state(),
1758 kPublicAccounts);
1759 prefs_public_accounts_update->Clear();
1760 for (std::vector<std::string>::const_iterator it =
1761 new_public_accounts.begin();
1762 it != new_public_accounts.end(); ++it) {
1763 prefs_public_accounts_update->AppendString(*it);
1764 }
1765
1766 // Remove the old public accounts from the user list.
1767 for (UserList::iterator it = users_.begin(); it != users_.end();) {
1768 if ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT) {
1769 if (*it != GetLoggedInUser())
1770 DeleteUser(*it);
1771 it = users_.erase(it);
1772 } else {
1773 ++it;
1774 }
1775 }
1776
1777 // Add the new public accounts to the front of the user list.
1778 for (std::vector<std::string>::const_reverse_iterator it =
1779 new_public_accounts.rbegin();
1780 it != new_public_accounts.rend(); ++it) {
1781 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
1782 users_.insert(users_.begin(), GetLoggedInUser());
1783 else
1784 users_.insert(users_.begin(), User::CreatePublicAccountUser(*it));
1785 UpdatePublicAccountDisplayName(*it);
1786 }
1787
1788 for (UserList::iterator ui = users_.begin(),
1789 ue = users_.begin() + new_public_accounts.size();
1790 ui != ue; ++ui) {
1791 GetUserImageManager((*ui)->email())->LoadUserImage();
1792 }
1793
1794 // Remove data belonging to public accounts that are no longer found on the
1795 // user list.
1796 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
1797
1798 return true;
1799 }
1800
UpdatePublicAccountDisplayName(const std::string & user_id)1801 void UserManagerImpl::UpdatePublicAccountDisplayName(
1802 const std::string& user_id) {
1803 std::string display_name;
1804
1805 if (device_local_account_policy_service_) {
1806 policy::DeviceLocalAccountPolicyBroker* broker =
1807 device_local_account_policy_service_->GetBrokerForUser(user_id);
1808 if (broker)
1809 display_name = broker->GetDisplayName();
1810 }
1811
1812 // Set or clear the display name.
1813 SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
1814 }
1815
GetCurrentUserFlow() const1816 UserFlow* UserManagerImpl::GetCurrentUserFlow() const {
1817 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1818 if (!IsUserLoggedIn())
1819 return GetDefaultUserFlow();
1820 return GetUserFlow(GetLoggedInUser()->email());
1821 }
1822
GetUserFlow(const std::string & user_id) const1823 UserFlow* UserManagerImpl::GetUserFlow(const std::string& user_id) const {
1824 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1825 FlowMap::const_iterator it = specific_flows_.find(user_id);
1826 if (it != specific_flows_.end())
1827 return it->second;
1828 return GetDefaultUserFlow();
1829 }
1830
SetUserFlow(const std::string & user_id,UserFlow * flow)1831 void UserManagerImpl::SetUserFlow(const std::string& user_id, UserFlow* flow) {
1832 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1833 ResetUserFlow(user_id);
1834 specific_flows_[user_id] = flow;
1835 }
1836
ResetUserFlow(const std::string & user_id)1837 void UserManagerImpl::ResetUserFlow(const std::string& user_id) {
1838 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1839 FlowMap::iterator it = specific_flows_.find(user_id);
1840 if (it != specific_flows_.end()) {
1841 delete it->second;
1842 specific_flows_.erase(it);
1843 }
1844 }
1845
GetAppModeChromeClientOAuthInfo(std::string * chrome_client_id,std::string * chrome_client_secret)1846 bool UserManagerImpl::GetAppModeChromeClientOAuthInfo(
1847 std::string* chrome_client_id, std::string* chrome_client_secret) {
1848 if (!chrome::IsRunningInForcedAppMode() ||
1849 chrome_client_id_.empty() ||
1850 chrome_client_secret_.empty()) {
1851 return false;
1852 }
1853
1854 *chrome_client_id = chrome_client_id_;
1855 *chrome_client_secret = chrome_client_secret_;
1856 return true;
1857 }
1858
SetAppModeChromeClientOAuthInfo(const std::string & chrome_client_id,const std::string & chrome_client_secret)1859 void UserManagerImpl::SetAppModeChromeClientOAuthInfo(
1860 const std::string& chrome_client_id,
1861 const std::string& chrome_client_secret) {
1862 if (!chrome::IsRunningInForcedAppMode())
1863 return;
1864
1865 chrome_client_id_ = chrome_client_id;
1866 chrome_client_secret_ = chrome_client_secret;
1867 }
1868
AreLocallyManagedUsersAllowed() const1869 bool UserManagerImpl::AreLocallyManagedUsersAllowed() const {
1870 bool locally_managed_users_allowed = false;
1871 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
1872 &locally_managed_users_allowed);
1873 return locally_managed_users_allowed;
1874 }
1875
GetUserProfileDir(const std::string & user_id) const1876 base::FilePath UserManagerImpl::GetUserProfileDir(
1877 const std::string& user_id) const {
1878 // TODO(dpolukhin): Remove Chrome OS specific profile path logic from
1879 // ProfileManager and use only this function to construct profile path.
1880 // TODO(nkostylev): Cleanup profile dir related code paths crbug.com/294233
1881 base::FilePath profile_dir;
1882 const User* user = FindUser(user_id);
1883 if (user && !user->username_hash().empty())
1884 profile_dir = ProfileHelper::GetUserProfileDir(user->username_hash());
1885
1886 ProfileManager* profile_manager = g_browser_process->profile_manager();
1887 profile_dir = profile_manager->user_data_dir().Append(profile_dir);
1888
1889 return profile_dir;
1890 }
1891
GetDefaultUserFlow() const1892 UserFlow* UserManagerImpl::GetDefaultUserFlow() const {
1893 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1894 if (!default_flow_.get())
1895 default_flow_.reset(new DefaultUserFlow());
1896 return default_flow_.get();
1897 }
1898
NotifyUserListChanged()1899 void UserManagerImpl::NotifyUserListChanged() {
1900 content::NotificationService::current()->Notify(
1901 chrome::NOTIFICATION_USER_LIST_CHANGED,
1902 content::Source<UserManager>(this),
1903 content::NotificationService::NoDetails());
1904 }
1905
NotifyActiveUserChanged(const User * active_user)1906 void UserManagerImpl::NotifyActiveUserChanged(const User* active_user) {
1907 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1908 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1909 session_state_observer_list_,
1910 ActiveUserChanged(active_user));
1911 }
1912
NotifyUserAddedToSession(const User * added_user)1913 void UserManagerImpl::NotifyUserAddedToSession(const User* added_user) {
1914 UpdateNumberOfUsers();
1915 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1916 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1917 session_state_observer_list_,
1918 UserAddedToSession(added_user));
1919 }
1920
NotifyActiveUserHashChanged(const std::string & hash)1921 void UserManagerImpl::NotifyActiveUserHashChanged(const std::string& hash) {
1922 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1923 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1924 session_state_observer_list_,
1925 ActiveUserHashChanged(hash));
1926 }
1927
NotifyPendingUserSessionsRestoreFinished()1928 void UserManagerImpl::NotifyPendingUserSessionsRestoreFinished() {
1929 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1930 user_sessions_restored_ = true;
1931 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver,
1932 session_state_observer_list_,
1933 PendingUserSessionsRestoreFinished());
1934 }
1935
UpdateLoginState()1936 void UserManagerImpl::UpdateLoginState() {
1937 if (!LoginState::IsInitialized())
1938 return; // LoginState may not be intialized in tests.
1939 LoginState::LoggedInState logged_in_state;
1940 logged_in_state = active_user_ ? LoginState::LOGGED_IN_ACTIVE
1941 : LoginState::LOGGED_IN_NONE;
1942
1943 LoginState::LoggedInUserType login_user_type;
1944 if (logged_in_state == LoginState::LOGGED_IN_NONE)
1945 login_user_type = LoginState::LOGGED_IN_USER_NONE;
1946 else if (is_current_user_owner_)
1947 login_user_type = LoginState::LOGGED_IN_USER_OWNER;
1948 else if (active_user_->GetType() == User::USER_TYPE_GUEST)
1949 login_user_type = LoginState::LOGGED_IN_USER_GUEST;
1950 else if (active_user_->GetType() == User::USER_TYPE_RETAIL_MODE)
1951 login_user_type = LoginState::LOGGED_IN_USER_RETAIL_MODE;
1952 else if (active_user_->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT)
1953 login_user_type = LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT;
1954 else if (active_user_->GetType() == User::USER_TYPE_LOCALLY_MANAGED)
1955 login_user_type = LoginState::LOGGED_IN_USER_LOCALLY_MANAGED;
1956 else if (active_user_->GetType() == User::USER_TYPE_KIOSK_APP)
1957 login_user_type = LoginState::LOGGED_IN_USER_KIOSK_APP;
1958 else
1959 login_user_type = LoginState::LOGGED_IN_USER_REGULAR;
1960
1961 if (primary_user_) {
1962 LoginState::Get()->SetLoggedInStateAndPrimaryUser(
1963 logged_in_state, login_user_type, primary_user_->username_hash());
1964 } else {
1965 LoginState::Get()->SetLoggedInState(logged_in_state, login_user_type);
1966 }
1967 }
1968
SetLRUUser(User * user)1969 void UserManagerImpl::SetLRUUser(User* user) {
1970 UserList::iterator it = std::find(lru_logged_in_users_.begin(),
1971 lru_logged_in_users_.end(),
1972 user);
1973 if (it != lru_logged_in_users_.end())
1974 lru_logged_in_users_.erase(it);
1975 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user);
1976 }
1977
OnRestoreActiveSessions(const SessionManagerClient::ActiveSessionsMap & sessions,bool success)1978 void UserManagerImpl::OnRestoreActiveSessions(
1979 const SessionManagerClient::ActiveSessionsMap& sessions,
1980 bool success) {
1981 if (!success) {
1982 LOG(ERROR) << "Could not get list of active user sessions after crash.";
1983 // If we could not get list of active user sessions it is safer to just
1984 // sign out so that we don't get in the inconsistent state.
1985 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
1986 return;
1987 }
1988
1989 // One profile has been already loaded on browser start.
1990 DCHECK(GetLoggedInUsers().size() == 1);
1991 DCHECK(GetActiveUser());
1992 std::string active_user_id = GetActiveUser()->email();
1993
1994 SessionManagerClient::ActiveSessionsMap::const_iterator it;
1995 for (it = sessions.begin(); it != sessions.end(); ++it) {
1996 if (active_user_id == it->first)
1997 continue;
1998 pending_user_sessions_[it->first] = it->second;
1999 }
2000 RestorePendingUserSessions();
2001 }
2002
RestorePendingUserSessions()2003 void UserManagerImpl::RestorePendingUserSessions() {
2004 if (pending_user_sessions_.empty()) {
2005 NotifyPendingUserSessionsRestoreFinished();
2006 return;
2007 }
2008
2009 // Get next user to restore sessions and delete it from list.
2010 SessionManagerClient::ActiveSessionsMap::const_iterator it =
2011 pending_user_sessions_.begin();
2012 std::string user_id = it->first;
2013 std::string user_id_hash = it->second;
2014 DCHECK(!user_id.empty());
2015 DCHECK(!user_id_hash.empty());
2016 pending_user_sessions_.erase(user_id);
2017
2018 // Check that this user is not logged in yet.
2019 UserList logged_in_users = GetLoggedInUsers();
2020 bool user_already_logged_in = false;
2021 for (UserList::const_iterator it = logged_in_users.begin();
2022 it != logged_in_users.end(); ++it) {
2023 const User* user = (*it);
2024 if (user->email() == user_id) {
2025 user_already_logged_in = true;
2026 break;
2027 }
2028 }
2029 DCHECK(!user_already_logged_in);
2030
2031 if (!user_already_logged_in) {
2032 UserContext user_context(user_id);
2033 user_context.SetUserIDHash(user_id_hash);
2034 user_context.SetIsUsingOAuth(false);
2035 // Will call OnProfilePrepared() once profile has been loaded.
2036 LoginUtils::Get()->PrepareProfile(user_context,
2037 false, // has_cookies
2038 true, // has_active_session
2039 this);
2040 } else {
2041 RestorePendingUserSessions();
2042 }
2043 }
2044
SendRegularUserLoginMetrics(const std::string & user_id)2045 void UserManagerImpl::SendRegularUserLoginMetrics(const std::string& user_id) {
2046 // If this isn't the first time Chrome was run after the system booted,
2047 // assume that Chrome was restarted because a previous session ended.
2048 if (!CommandLine::ForCurrentProcess()->HasSwitch(
2049 switches::kFirstExecAfterBoot)) {
2050 const std::string last_email =
2051 g_browser_process->local_state()->GetString(kLastLoggedInRegularUser);
2052 const base::TimeDelta time_to_login =
2053 base::TimeTicks::Now() - manager_creation_time_;
2054 if (!last_email.empty() && user_id != last_email &&
2055 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) {
2056 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
2057 time_to_login.InSeconds(), 0, kLogoutToLoginDelayMaxSec, 50);
2058 }
2059 }
2060 }
2061
OnUserNotAllowed(const std::string & user_email)2062 void UserManagerImpl::OnUserNotAllowed(const std::string& user_email) {
2063 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
2064 "current session";
2065 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
2066 }
2067
UpdateUserAccountLocale(const std::string & user_id,const std::string & locale)2068 void UserManagerImpl::UpdateUserAccountLocale(const std::string& user_id,
2069 const std::string& locale) {
2070 if (!locale.empty() &&
2071 locale != g_browser_process->GetApplicationLocale()) {
2072 BrowserThread::PostBlockingPoolTask(
2073 FROM_HERE,
2074 base::Bind(ResolveLocale, locale,
2075 base::Bind(&UserManagerImpl::DoUpdateAccountLocale,
2076 base::Unretained(this),
2077 user_id)));
2078 } else {
2079 DoUpdateAccountLocale(user_id, locale);
2080 }
2081 }
2082
DoUpdateAccountLocale(const std::string & user_id,const std::string & resolved_locale)2083 void UserManagerImpl::DoUpdateAccountLocale(
2084 const std::string& user_id,
2085 const std::string& resolved_locale) {
2086 if (User* user = FindUserAndModify(user_id))
2087 user->SetAccountLocale(resolved_locale);
2088 }
2089
UpdateNumberOfUsers()2090 void UserManagerImpl::UpdateNumberOfUsers() {
2091 size_t users = GetLoggedInUsers().size();
2092 if (users) {
2093 // Write the user number as UMA stat when a multi user session is possible.
2094 if ((users + GetUsersAdmittedForMultiProfile().size()) > 1)
2095 ash::MultiProfileUMA::RecordUserCount(users);
2096 }
2097
2098 base::debug::SetCrashKeyValue(crash_keys::kNumberOfUsers,
2099 base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
2100 }
2101
DeleteUser(User * user)2102 void UserManagerImpl::DeleteUser(User* user) {
2103 const bool is_active_user = (user == active_user_);
2104 delete user;
2105 if (is_active_user)
2106 active_user_ = NULL;
2107 }
2108
2109 } // namespace chromeos
2110