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 "components/user_manager/user_manager_base.h" 6 7 #include <cstddef> 8 #include <set> 9 10 #include "base/bind.h" 11 #include "base/bind_helpers.h" 12 #include "base/command_line.h" 13 #include "base/compiler_specific.h" 14 #include "base/format_macros.h" 15 #include "base/location.h" 16 #include "base/logging.h" 17 #include "base/macros.h" 18 #include "base/metrics/histogram.h" 19 #include "base/prefs/pref_registry_simple.h" 20 #include "base/prefs/pref_service.h" 21 #include "base/prefs/scoped_user_pref_update.h" 22 #include "base/strings/string_util.h" 23 #include "base/strings/stringprintf.h" 24 #include "base/strings/utf_string_conversions.h" 25 #include "base/task_runner.h" 26 #include "base/values.h" 27 #include "chromeos/chromeos_switches.h" 28 #include "chromeos/cryptohome/async_method_caller.h" 29 #include "chromeos/login/login_state.h" 30 #include "chromeos/login/user_names.h" 31 #include "components/session_manager/core/session_manager.h" 32 #include "components/user_manager/remove_user_delegate.h" 33 #include "components/user_manager/user_type.h" 34 #include "google_apis/gaia/gaia_auth_util.h" 35 #include "ui/base/l10n/l10n_util.h" 36 37 namespace user_manager { 38 namespace { 39 40 // A vector pref of the the regular users known on this device, arranged in LRU 41 // order. 42 const char kRegularUsers[] = "LoggedInUsers"; 43 44 // A dictionary that maps user IDs to the displayed name. 45 const char kUserDisplayName[] = "UserDisplayName"; 46 47 // A dictionary that maps user IDs to the user's given name. 48 const char kUserGivenName[] = "UserGivenName"; 49 50 // A dictionary that maps user IDs to the displayed (non-canonical) emails. 51 const char kUserDisplayEmail[] = "UserDisplayEmail"; 52 53 // A dictionary that maps user IDs to OAuth token presence flag. 54 const char kUserOAuthTokenStatus[] = "OAuthTokenStatus"; 55 56 // A dictionary that maps user IDs to a flag indicating whether online 57 // authentication against GAIA should be enforced during the next sign-in. 58 const char kUserForceOnlineSignin[] = "UserForceOnlineSignin"; 59 60 // A string pref containing the ID of the last user who logged in if it was 61 // a regular user or an empty string if it was another type of user (guest, 62 // kiosk, public account, etc.). 63 const char kLastLoggedInRegularUser[] = "LastLoggedInRegularUser"; 64 65 // A string pref containing the ID of the last active user. 66 // In case of browser crash, this pref will be used to set active user after 67 // session restore. 68 const char kLastActiveUser[] = "LastActiveUser"; 69 70 // Upper bound for a histogram metric reporting the amount of time between 71 // one regular user logging out and a different regular user logging in. 72 const int kLogoutToLoginDelayMaxSec = 1800; 73 74 // Callback that is called after user removal is complete. 75 void OnRemoveUserComplete(const std::string& user_email, 76 bool success, 77 cryptohome::MountError return_code) { 78 // Log the error, but there's not much we can do. 79 if (!success) { 80 LOG(ERROR) << "Removal of cryptohome for " << user_email 81 << " failed, return code: " << return_code; 82 } 83 } 84 85 // Runs on SequencedWorkerPool thread. Passes resolved locale to UI thread. 86 void ResolveLocale(const std::string& raw_locale, 87 std::string* resolved_locale) { 88 ignore_result(l10n_util::CheckAndResolveLocale(raw_locale, resolved_locale)); 89 } 90 91 } // namespace 92 93 // static 94 void UserManagerBase::RegisterPrefs(PrefRegistrySimple* registry) { 95 registry->RegisterListPref(kRegularUsers); 96 registry->RegisterStringPref(kLastLoggedInRegularUser, std::string()); 97 registry->RegisterDictionaryPref(kUserDisplayName); 98 registry->RegisterDictionaryPref(kUserGivenName); 99 registry->RegisterDictionaryPref(kUserDisplayEmail); 100 registry->RegisterDictionaryPref(kUserOAuthTokenStatus); 101 registry->RegisterDictionaryPref(kUserForceOnlineSignin); 102 registry->RegisterStringPref(kLastActiveUser, std::string()); 103 } 104 105 UserManagerBase::UserManagerBase( 106 scoped_refptr<base::TaskRunner> task_runner, 107 scoped_refptr<base::TaskRunner> blocking_task_runner) 108 : active_user_(NULL), 109 primary_user_(NULL), 110 user_loading_stage_(STAGE_NOT_LOADED), 111 session_started_(false), 112 is_current_user_owner_(false), 113 is_current_user_new_(false), 114 is_current_user_ephemeral_regular_user_(false), 115 ephemeral_users_enabled_(false), 116 manager_creation_time_(base::TimeTicks::Now()), 117 last_session_active_user_initialized_(false), 118 task_runner_(task_runner), 119 blocking_task_runner_(blocking_task_runner), 120 weak_factory_(this) { 121 UpdateLoginState(); 122 } 123 124 UserManagerBase::~UserManagerBase() { 125 // Can't use STLDeleteElements because of the private destructor of User. 126 for (UserList::iterator it = users_.begin(); it != users_.end(); 127 it = users_.erase(it)) { 128 DeleteUser(*it); 129 } 130 // These are pointers to the same User instances that were in users_ list. 131 logged_in_users_.clear(); 132 lru_logged_in_users_.clear(); 133 134 DeleteUser(active_user_); 135 } 136 137 void UserManagerBase::Shutdown() { 138 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 139 } 140 141 const UserList& UserManagerBase::GetUsers() const { 142 const_cast<UserManagerBase*>(this)->EnsureUsersLoaded(); 143 return users_; 144 } 145 146 const UserList& UserManagerBase::GetLoggedInUsers() const { 147 return logged_in_users_; 148 } 149 150 const UserList& UserManagerBase::GetLRULoggedInUsers() const { 151 return lru_logged_in_users_; 152 } 153 154 const std::string& UserManagerBase::GetOwnerEmail() const { 155 return owner_email_; 156 } 157 158 void UserManagerBase::UserLoggedIn(const std::string& user_id, 159 const std::string& username_hash, 160 bool browser_restart) { 161 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 162 163 if (!last_session_active_user_initialized_) { 164 last_session_active_user_ = GetLocalState()->GetString(kLastActiveUser); 165 last_session_active_user_initialized_ = true; 166 } 167 168 User* user = FindUserInListAndModify(user_id); 169 if (active_user_ && user) { 170 user->set_is_logged_in(true); 171 user->set_username_hash(username_hash); 172 logged_in_users_.push_back(user); 173 lru_logged_in_users_.push_back(user); 174 175 // Reset the new user flag if the user already exists. 176 SetIsCurrentUserNew(false); 177 NotifyUserAddedToSession(user, true /* user switch pending */); 178 179 return; 180 } 181 182 if (user_id == chromeos::login::kGuestUserName) { 183 GuestUserLoggedIn(); 184 } else if (user_id == chromeos::login::kRetailModeUserName) { 185 RetailModeUserLoggedIn(); 186 } else if (IsKioskApp(user_id)) { 187 KioskAppLoggedIn(user_id); 188 } else if (IsDemoApp(user_id)) { 189 DemoAccountLoggedIn(); 190 } else { 191 EnsureUsersLoaded(); 192 193 if (user && user->GetType() == USER_TYPE_PUBLIC_ACCOUNT) { 194 PublicAccountUserLoggedIn(user); 195 } else if ((user && user->GetType() == USER_TYPE_SUPERVISED) || 196 (!user && 197 gaia::ExtractDomainName(user_id) == 198 chromeos::login::kSupervisedUserDomain)) { 199 SupervisedUserLoggedIn(user_id); 200 } else if (browser_restart && IsPublicAccountMarkedForRemoval(user_id)) { 201 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id)); 202 } else if (user_id != GetOwnerEmail() && !user && 203 (AreEphemeralUsersEnabled() || browser_restart)) { 204 RegularUserLoggedInAsEphemeral(user_id); 205 } else { 206 RegularUserLoggedIn(user_id); 207 } 208 } 209 210 DCHECK(active_user_); 211 active_user_->set_is_logged_in(true); 212 active_user_->set_is_active(true); 213 active_user_->set_username_hash(username_hash); 214 215 // Place user who just signed in to the top of the logged in users. 216 logged_in_users_.insert(logged_in_users_.begin(), active_user_); 217 SetLRUUser(active_user_); 218 219 if (!primary_user_) { 220 primary_user_ = active_user_; 221 if (primary_user_->GetType() == USER_TYPE_REGULAR) 222 SendRegularUserLoginMetrics(user_id); 223 } 224 225 UMA_HISTOGRAM_ENUMERATION( 226 "UserManager.LoginUserType", active_user_->GetType(), NUM_USER_TYPES); 227 228 GetLocalState()->SetString( 229 kLastLoggedInRegularUser, 230 (active_user_->GetType() == USER_TYPE_REGULAR) ? user_id : ""); 231 232 NotifyOnLogin(); 233 PerformPostUserLoggedInActions(browser_restart); 234 } 235 236 void UserManagerBase::SwitchActiveUser(const std::string& user_id) { 237 User* user = FindUserAndModify(user_id); 238 if (!user) { 239 NOTREACHED() << "Switching to a non-existing user"; 240 return; 241 } 242 if (user == active_user_) { 243 NOTREACHED() << "Switching to a user who is already active"; 244 return; 245 } 246 if (!user->is_logged_in()) { 247 NOTREACHED() << "Switching to a user that is not logged in"; 248 return; 249 } 250 if (user->GetType() != USER_TYPE_REGULAR) { 251 NOTREACHED() << "Switching to a non-regular user"; 252 return; 253 } 254 if (user->username_hash().empty()) { 255 NOTREACHED() << "Switching to a user that doesn't have username_hash set"; 256 return; 257 } 258 259 DCHECK(active_user_); 260 active_user_->set_is_active(false); 261 user->set_is_active(true); 262 active_user_ = user; 263 264 // Move the user to the front. 265 SetLRUUser(active_user_); 266 267 NotifyActiveUserHashChanged(active_user_->username_hash()); 268 NotifyActiveUserChanged(active_user_); 269 } 270 271 void UserManagerBase::SwitchToLastActiveUser() { 272 if (last_session_active_user_.empty()) 273 return; 274 275 if (GetActiveUser()->email() != last_session_active_user_) 276 SwitchActiveUser(last_session_active_user_); 277 278 // Make sure that this function gets run only once. 279 last_session_active_user_.clear(); 280 } 281 282 void UserManagerBase::SessionStarted() { 283 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 284 session_started_ = true; 285 286 UpdateLoginState(); 287 session_manager::SessionManager::Get()->SetSessionState( 288 session_manager::SESSION_STATE_ACTIVE); 289 290 if (IsCurrentUserNew()) { 291 // Make sure that the new user's data is persisted to Local State. 292 GetLocalState()->CommitPendingWrite(); 293 } 294 } 295 296 void UserManagerBase::RemoveUser(const std::string& user_id, 297 RemoveUserDelegate* delegate) { 298 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 299 300 if (!CanUserBeRemoved(FindUser(user_id))) 301 return; 302 303 RemoveUserInternal(user_id, delegate); 304 } 305 306 void UserManagerBase::RemoveUserInternal(const std::string& user_email, 307 RemoveUserDelegate* delegate) { 308 RemoveNonOwnerUserInternal(user_email, delegate); 309 } 310 311 void UserManagerBase::RemoveNonOwnerUserInternal(const std::string& user_email, 312 RemoveUserDelegate* delegate) { 313 if (delegate) 314 delegate->OnBeforeUserRemoved(user_email); 315 RemoveUserFromList(user_email); 316 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove( 317 user_email, base::Bind(&OnRemoveUserComplete, user_email)); 318 319 if (delegate) 320 delegate->OnUserRemoved(user_email); 321 } 322 323 void UserManagerBase::RemoveUserFromList(const std::string& user_id) { 324 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 325 RemoveNonCryptohomeData(user_id); 326 if (user_loading_stage_ == STAGE_LOADED) { 327 DeleteUser(RemoveRegularOrSupervisedUserFromList(user_id)); 328 } else if (user_loading_stage_ == STAGE_LOADING) { 329 DCHECK(gaia::ExtractDomainName(user_id) == 330 chromeos::login::kSupervisedUserDomain); 331 // Special case, removing partially-constructed supervised user during user 332 // list loading. 333 ListPrefUpdate users_update(GetLocalState(), kRegularUsers); 334 users_update->Remove(base::StringValue(user_id), NULL); 335 } else { 336 NOTREACHED() << "Users are not loaded yet."; 337 return; 338 } 339 340 // Make sure that new data is persisted to Local State. 341 GetLocalState()->CommitPendingWrite(); 342 } 343 344 bool UserManagerBase::IsKnownUser(const std::string& user_id) const { 345 return FindUser(user_id) != NULL; 346 } 347 348 const User* UserManagerBase::FindUser(const std::string& user_id) const { 349 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 350 if (active_user_ && active_user_->email() == user_id) 351 return active_user_; 352 return FindUserInList(user_id); 353 } 354 355 User* UserManagerBase::FindUserAndModify(const std::string& user_id) { 356 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 357 if (active_user_ && active_user_->email() == user_id) 358 return active_user_; 359 return FindUserInListAndModify(user_id); 360 } 361 362 const User* UserManagerBase::GetLoggedInUser() const { 363 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 364 return active_user_; 365 } 366 367 User* UserManagerBase::GetLoggedInUser() { 368 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 369 return active_user_; 370 } 371 372 const User* UserManagerBase::GetActiveUser() const { 373 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 374 return active_user_; 375 } 376 377 User* UserManagerBase::GetActiveUser() { 378 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 379 return active_user_; 380 } 381 382 const User* UserManagerBase::GetPrimaryUser() const { 383 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 384 return primary_user_; 385 } 386 387 void UserManagerBase::SaveUserOAuthStatus( 388 const std::string& user_id, 389 User::OAuthTokenStatus oauth_token_status) { 390 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 391 392 DVLOG(1) << "Saving user OAuth token status in Local State"; 393 User* user = FindUserAndModify(user_id); 394 if (user) 395 user->set_oauth_token_status(oauth_token_status); 396 397 // Do not update local state if data stored or cached outside the user's 398 // cryptohome is to be treated as ephemeral. 399 if (IsUserNonCryptohomeDataEphemeral(user_id)) 400 return; 401 402 DictionaryPrefUpdate oauth_status_update(GetLocalState(), 403 kUserOAuthTokenStatus); 404 oauth_status_update->SetWithoutPathExpansion( 405 user_id, 406 new base::FundamentalValue(static_cast<int>(oauth_token_status))); 407 } 408 409 void UserManagerBase::SaveForceOnlineSignin(const std::string& user_id, 410 bool force_online_signin) { 411 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 412 413 // Do not update local state if data stored or cached outside the user's 414 // cryptohome is to be treated as ephemeral. 415 if (IsUserNonCryptohomeDataEphemeral(user_id)) 416 return; 417 418 DictionaryPrefUpdate force_online_update(GetLocalState(), 419 kUserForceOnlineSignin); 420 force_online_update->SetBooleanWithoutPathExpansion(user_id, 421 force_online_signin); 422 } 423 424 void UserManagerBase::SaveUserDisplayName(const std::string& user_id, 425 const base::string16& display_name) { 426 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 427 428 if (User* user = FindUserAndModify(user_id)) { 429 user->set_display_name(display_name); 430 431 // Do not update local state if data stored or cached outside the user's 432 // cryptohome is to be treated as ephemeral. 433 if (!IsUserNonCryptohomeDataEphemeral(user_id)) { 434 DictionaryPrefUpdate display_name_update(GetLocalState(), 435 kUserDisplayName); 436 display_name_update->SetWithoutPathExpansion( 437 user_id, new base::StringValue(display_name)); 438 } 439 } 440 } 441 442 base::string16 UserManagerBase::GetUserDisplayName( 443 const std::string& user_id) const { 444 const User* user = FindUser(user_id); 445 return user ? user->display_name() : base::string16(); 446 } 447 448 void UserManagerBase::SaveUserDisplayEmail(const std::string& user_id, 449 const std::string& display_email) { 450 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 451 452 User* user = FindUserAndModify(user_id); 453 if (!user) { 454 LOG(ERROR) << "User not found: " << user_id; 455 return; // Ignore if there is no such user. 456 } 457 458 user->set_display_email(display_email); 459 460 // Do not update local state if data stored or cached outside the user's 461 // cryptohome is to be treated as ephemeral. 462 if (IsUserNonCryptohomeDataEphemeral(user_id)) 463 return; 464 465 DictionaryPrefUpdate display_email_update(GetLocalState(), kUserDisplayEmail); 466 display_email_update->SetWithoutPathExpansion( 467 user_id, new base::StringValue(display_email)); 468 } 469 470 std::string UserManagerBase::GetUserDisplayEmail( 471 const std::string& user_id) const { 472 const User* user = FindUser(user_id); 473 return user ? user->display_email() : user_id; 474 } 475 476 void UserManagerBase::UpdateUserAccountData( 477 const std::string& user_id, 478 const UserAccountData& account_data) { 479 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 480 481 SaveUserDisplayName(user_id, account_data.display_name()); 482 483 if (User* user = FindUserAndModify(user_id)) { 484 base::string16 given_name = account_data.given_name(); 485 user->set_given_name(given_name); 486 if (!IsUserNonCryptohomeDataEphemeral(user_id)) { 487 DictionaryPrefUpdate given_name_update(GetLocalState(), kUserGivenName); 488 given_name_update->SetWithoutPathExpansion( 489 user_id, new base::StringValue(given_name)); 490 } 491 } 492 493 UpdateUserAccountLocale(user_id, account_data.locale()); 494 } 495 496 // static 497 void UserManagerBase::ParseUserList(const base::ListValue& users_list, 498 const std::set<std::string>& existing_users, 499 std::vector<std::string>* users_vector, 500 std::set<std::string>* users_set) { 501 users_vector->clear(); 502 users_set->clear(); 503 for (size_t i = 0; i < users_list.GetSize(); ++i) { 504 std::string email; 505 if (!users_list.GetString(i, &email) || email.empty()) { 506 LOG(ERROR) << "Corrupt entry in user list at index " << i << "."; 507 continue; 508 } 509 if (existing_users.find(email) != existing_users.end() || 510 !users_set->insert(email).second) { 511 LOG(ERROR) << "Duplicate user: " << email; 512 continue; 513 } 514 users_vector->push_back(email); 515 } 516 } 517 518 bool UserManagerBase::IsCurrentUserOwner() const { 519 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 520 base::AutoLock lk(is_current_user_owner_lock_); 521 return is_current_user_owner_; 522 } 523 524 void UserManagerBase::SetCurrentUserIsOwner(bool is_current_user_owner) { 525 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 526 { 527 base::AutoLock lk(is_current_user_owner_lock_); 528 is_current_user_owner_ = is_current_user_owner; 529 } 530 UpdateLoginState(); 531 } 532 533 bool UserManagerBase::IsCurrentUserNew() const { 534 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 535 return is_current_user_new_; 536 } 537 538 bool UserManagerBase::IsCurrentUserNonCryptohomeDataEphemeral() const { 539 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 540 return IsUserLoggedIn() && 541 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email()); 542 } 543 544 bool UserManagerBase::CanCurrentUserLock() const { 545 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 546 return IsUserLoggedIn() && active_user_->can_lock(); 547 } 548 549 bool UserManagerBase::IsUserLoggedIn() const { 550 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 551 return active_user_; 552 } 553 554 bool UserManagerBase::IsLoggedInAsRegularUser() const { 555 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 556 return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_REGULAR; 557 } 558 559 bool UserManagerBase::IsLoggedInAsDemoUser() const { 560 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 561 return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_RETAIL_MODE; 562 } 563 564 bool UserManagerBase::IsLoggedInAsPublicAccount() const { 565 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 566 return IsUserLoggedIn() && 567 active_user_->GetType() == USER_TYPE_PUBLIC_ACCOUNT; 568 } 569 570 bool UserManagerBase::IsLoggedInAsGuest() const { 571 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 572 return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_GUEST; 573 } 574 575 bool UserManagerBase::IsLoggedInAsSupervisedUser() const { 576 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 577 return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_SUPERVISED; 578 } 579 580 bool UserManagerBase::IsLoggedInAsKioskApp() const { 581 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 582 return IsUserLoggedIn() && active_user_->GetType() == USER_TYPE_KIOSK_APP; 583 } 584 585 bool UserManagerBase::IsLoggedInAsStub() const { 586 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 587 return IsUserLoggedIn() && 588 active_user_->email() == chromeos::login::kStubUser; 589 } 590 591 bool UserManagerBase::IsSessionStarted() const { 592 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 593 return session_started_; 594 } 595 596 bool UserManagerBase::IsUserNonCryptohomeDataEphemeral( 597 const std::string& user_id) const { 598 // Data belonging to the guest, retail mode and stub users is always 599 // ephemeral. 600 if (user_id == chromeos::login::kGuestUserName || 601 user_id == chromeos::login::kRetailModeUserName || 602 user_id == chromeos::login::kStubUser) { 603 return true; 604 } 605 606 // Data belonging to the owner, anyone found on the user list and obsolete 607 // public accounts whose data has not been removed yet is not ephemeral. 608 if (user_id == GetOwnerEmail() || UserExistsInList(user_id) || 609 IsPublicAccountMarkedForRemoval(user_id)) { 610 return false; 611 } 612 613 // Data belonging to the currently logged-in user is ephemeral when: 614 // a) The user logged into a regular account while the ephemeral users policy 615 // was enabled. 616 // - or - 617 // b) The user logged into any other account type. 618 if (IsUserLoggedIn() && (user_id == GetLoggedInUser()->email()) && 619 (is_current_user_ephemeral_regular_user_ || !IsLoggedInAsRegularUser())) { 620 return true; 621 } 622 623 // Data belonging to any other user is ephemeral when: 624 // a) Going through the regular login flow and the ephemeral users policy is 625 // enabled. 626 // - or - 627 // b) The browser is restarting after a crash. 628 return AreEphemeralUsersEnabled() || 629 session_manager::SessionManager::HasBrowserRestarted(); 630 } 631 632 void UserManagerBase::AddObserver(UserManager::Observer* obs) { 633 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 634 observer_list_.AddObserver(obs); 635 } 636 637 void UserManagerBase::RemoveObserver(UserManager::Observer* obs) { 638 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 639 observer_list_.RemoveObserver(obs); 640 } 641 642 void UserManagerBase::AddSessionStateObserver( 643 UserManager::UserSessionStateObserver* obs) { 644 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 645 session_state_observer_list_.AddObserver(obs); 646 } 647 648 void UserManagerBase::RemoveSessionStateObserver( 649 UserManager::UserSessionStateObserver* obs) { 650 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 651 session_state_observer_list_.RemoveObserver(obs); 652 } 653 654 void UserManagerBase::NotifyLocalStateChanged() { 655 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 656 FOR_EACH_OBSERVER( 657 UserManager::Observer, observer_list_, LocalStateChanged(this)); 658 } 659 660 void UserManagerBase::ForceUpdateState() { 661 UpdateLoginState(); 662 } 663 664 bool UserManagerBase::CanUserBeRemoved(const User* user) const { 665 // Only regular and supervised users are allowed to be manually removed. 666 if (!user || (user->GetType() != USER_TYPE_REGULAR && 667 user->GetType() != USER_TYPE_SUPERVISED)) { 668 return false; 669 } 670 671 // Sanity check: we must not remove single user unless it's an enterprise 672 // device. This check may seem redundant at a first sight because 673 // this single user must be an owner and we perform special check later 674 // in order not to remove an owner. However due to non-instant nature of 675 // ownership assignment this later check may sometimes fail. 676 // See http://crosbug.com/12723 677 if (users_.size() < 2 && !IsEnterpriseManaged()) 678 return false; 679 680 // Sanity check: do not allow any of the the logged in users to be removed. 681 for (UserList::const_iterator it = logged_in_users_.begin(); 682 it != logged_in_users_.end(); 683 ++it) { 684 if ((*it)->email() == user->email()) 685 return false; 686 } 687 688 return true; 689 } 690 691 bool UserManagerBase::GetEphemeralUsersEnabled() const { 692 return ephemeral_users_enabled_; 693 } 694 695 void UserManagerBase::SetEphemeralUsersEnabled(bool enabled) { 696 ephemeral_users_enabled_ = enabled; 697 } 698 699 void UserManagerBase::SetIsCurrentUserNew(bool is_new) { 700 is_current_user_new_ = is_new; 701 } 702 703 void UserManagerBase::SetOwnerEmail(std::string owner_user_id) { 704 owner_email_ = owner_user_id; 705 } 706 707 const std::string& UserManagerBase::GetPendingUserSwitchID() const { 708 return pending_user_switch_; 709 } 710 711 void UserManagerBase::SetPendingUserSwitchID(std::string user_id) { 712 pending_user_switch_ = user_id; 713 } 714 715 void UserManagerBase::EnsureUsersLoaded() { 716 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 717 if (!GetLocalState()) 718 return; 719 720 if (user_loading_stage_ != STAGE_NOT_LOADED) 721 return; 722 user_loading_stage_ = STAGE_LOADING; 723 724 PerformPreUserListLoadingActions(); 725 726 PrefService* local_state = GetLocalState(); 727 const base::ListValue* prefs_regular_users = 728 local_state->GetList(kRegularUsers); 729 730 const base::DictionaryValue* prefs_display_names = 731 local_state->GetDictionary(kUserDisplayName); 732 const base::DictionaryValue* prefs_given_names = 733 local_state->GetDictionary(kUserGivenName); 734 const base::DictionaryValue* prefs_display_emails = 735 local_state->GetDictionary(kUserDisplayEmail); 736 737 // Load public sessions first. 738 std::set<std::string> public_sessions_set; 739 LoadPublicAccounts(&public_sessions_set); 740 741 // Load regular users and supervised users. 742 std::vector<std::string> regular_users; 743 std::set<std::string> regular_users_set; 744 ParseUserList(*prefs_regular_users, 745 public_sessions_set, 746 ®ular_users, 747 ®ular_users_set); 748 for (std::vector<std::string>::const_iterator it = regular_users.begin(); 749 it != regular_users.end(); 750 ++it) { 751 User* user = NULL; 752 const std::string domain = gaia::ExtractDomainName(*it); 753 if (domain == chromeos::login::kSupervisedUserDomain) 754 user = User::CreateSupervisedUser(*it); 755 else 756 user = User::CreateRegularUser(*it); 757 user->set_oauth_token_status(LoadUserOAuthStatus(*it)); 758 user->set_force_online_signin(LoadForceOnlineSignin(*it)); 759 users_.push_back(user); 760 761 base::string16 display_name; 762 if (prefs_display_names->GetStringWithoutPathExpansion(*it, 763 &display_name)) { 764 user->set_display_name(display_name); 765 } 766 767 base::string16 given_name; 768 if (prefs_given_names->GetStringWithoutPathExpansion(*it, &given_name)) { 769 user->set_given_name(given_name); 770 } 771 772 std::string display_email; 773 if (prefs_display_emails->GetStringWithoutPathExpansion(*it, 774 &display_email)) { 775 user->set_display_email(display_email); 776 } 777 } 778 779 user_loading_stage_ = STAGE_LOADED; 780 781 PerformPostUserListLoadingActions(); 782 } 783 784 UserList& UserManagerBase::GetUsersAndModify() { 785 EnsureUsersLoaded(); 786 return users_; 787 } 788 789 const User* UserManagerBase::FindUserInList(const std::string& user_id) const { 790 const UserList& users = GetUsers(); 791 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { 792 if ((*it)->email() == user_id) 793 return *it; 794 } 795 return NULL; 796 } 797 798 const bool UserManagerBase::UserExistsInList(const std::string& user_id) const { 799 const base::ListValue* user_list = GetLocalState()->GetList(kRegularUsers); 800 for (size_t i = 0; i < user_list->GetSize(); ++i) { 801 std::string email; 802 if (user_list->GetString(i, &email) && (user_id == email)) 803 return true; 804 } 805 return false; 806 } 807 808 User* UserManagerBase::FindUserInListAndModify(const std::string& user_id) { 809 UserList& users = GetUsersAndModify(); 810 for (UserList::iterator it = users.begin(); it != users.end(); ++it) { 811 if ((*it)->email() == user_id) 812 return *it; 813 } 814 return NULL; 815 } 816 817 void UserManagerBase::GuestUserLoggedIn() { 818 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 819 active_user_ = User::CreateGuestUser(); 820 } 821 822 void UserManagerBase::AddUserRecord(User* user) { 823 // Add the user to the front of the user list. 824 ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers); 825 prefs_users_update->Insert(0, new base::StringValue(user->email())); 826 users_.insert(users_.begin(), user); 827 } 828 829 void UserManagerBase::RegularUserLoggedIn(const std::string& user_id) { 830 // Remove the user from the user list. 831 active_user_ = RemoveRegularOrSupervisedUserFromList(user_id); 832 833 // If the user was not found on the user list, create a new user. 834 SetIsCurrentUserNew(!active_user_); 835 if (IsCurrentUserNew()) { 836 active_user_ = User::CreateRegularUser(user_id); 837 active_user_->set_oauth_token_status(LoadUserOAuthStatus(user_id)); 838 SaveUserDisplayName(active_user_->email(), 839 base::UTF8ToUTF16(active_user_->GetAccountName(true))); 840 } 841 842 AddUserRecord(active_user_); 843 844 // Make sure that new data is persisted to Local State. 845 GetLocalState()->CommitPendingWrite(); 846 } 847 848 void UserManagerBase::RegularUserLoggedInAsEphemeral( 849 const std::string& user_id) { 850 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 851 SetIsCurrentUserNew(true); 852 is_current_user_ephemeral_regular_user_ = true; 853 active_user_ = User::CreateRegularUser(user_id); 854 } 855 856 void UserManagerBase::NotifyOnLogin() { 857 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 858 859 NotifyActiveUserHashChanged(active_user_->username_hash()); 860 NotifyActiveUserChanged(active_user_); 861 UpdateLoginState(); 862 } 863 864 User::OAuthTokenStatus UserManagerBase::LoadUserOAuthStatus( 865 const std::string& user_id) const { 866 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 867 868 const base::DictionaryValue* prefs_oauth_status = 869 GetLocalState()->GetDictionary(kUserOAuthTokenStatus); 870 int oauth_token_status = User::OAUTH_TOKEN_STATUS_UNKNOWN; 871 if (prefs_oauth_status && 872 prefs_oauth_status->GetIntegerWithoutPathExpansion(user_id, 873 &oauth_token_status)) { 874 User::OAuthTokenStatus status = 875 static_cast<User::OAuthTokenStatus>(oauth_token_status); 876 HandleUserOAuthTokenStatusChange(user_id, status); 877 878 return status; 879 } 880 return User::OAUTH_TOKEN_STATUS_UNKNOWN; 881 } 882 883 bool UserManagerBase::LoadForceOnlineSignin(const std::string& user_id) const { 884 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 885 886 const base::DictionaryValue* prefs_force_online = 887 GetLocalState()->GetDictionary(kUserForceOnlineSignin); 888 bool force_online_signin = false; 889 if (prefs_force_online) { 890 prefs_force_online->GetBooleanWithoutPathExpansion(user_id, 891 &force_online_signin); 892 } 893 return force_online_signin; 894 } 895 896 void UserManagerBase::RemoveNonCryptohomeData(const std::string& user_id) { 897 PrefService* prefs = GetLocalState(); 898 DictionaryPrefUpdate prefs_display_name_update(prefs, kUserDisplayName); 899 prefs_display_name_update->RemoveWithoutPathExpansion(user_id, NULL); 900 901 DictionaryPrefUpdate prefs_given_name_update(prefs, kUserGivenName); 902 prefs_given_name_update->RemoveWithoutPathExpansion(user_id, NULL); 903 904 DictionaryPrefUpdate prefs_display_email_update(prefs, kUserDisplayEmail); 905 prefs_display_email_update->RemoveWithoutPathExpansion(user_id, NULL); 906 907 DictionaryPrefUpdate prefs_oauth_update(prefs, kUserOAuthTokenStatus); 908 prefs_oauth_update->RemoveWithoutPathExpansion(user_id, NULL); 909 910 DictionaryPrefUpdate prefs_force_online_update(prefs, kUserForceOnlineSignin); 911 prefs_force_online_update->RemoveWithoutPathExpansion(user_id, NULL); 912 913 std::string last_active_user = GetLocalState()->GetString(kLastActiveUser); 914 if (user_id == last_active_user) 915 GetLocalState()->SetString(kLastActiveUser, std::string()); 916 } 917 918 User* UserManagerBase::RemoveRegularOrSupervisedUserFromList( 919 const std::string& user_id) { 920 ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers); 921 prefs_users_update->Clear(); 922 User* user = NULL; 923 for (UserList::iterator it = users_.begin(); it != users_.end();) { 924 const std::string user_email = (*it)->email(); 925 if (user_email == user_id) { 926 user = *it; 927 it = users_.erase(it); 928 } else { 929 if ((*it)->GetType() == USER_TYPE_REGULAR || 930 (*it)->GetType() == USER_TYPE_SUPERVISED) { 931 prefs_users_update->Append(new base::StringValue(user_email)); 932 } 933 ++it; 934 } 935 } 936 return user; 937 } 938 939 void UserManagerBase::NotifyActiveUserChanged(const User* active_user) { 940 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 941 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver, 942 session_state_observer_list_, 943 ActiveUserChanged(active_user)); 944 } 945 946 void UserManagerBase::NotifyUserAddedToSession(const User* added_user, 947 bool user_switch_pending) { 948 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 949 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver, 950 session_state_observer_list_, 951 UserAddedToSession(added_user)); 952 } 953 954 void UserManagerBase::NotifyActiveUserHashChanged(const std::string& hash) { 955 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 956 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver, 957 session_state_observer_list_, 958 ActiveUserHashChanged(hash)); 959 } 960 961 void UserManagerBase::UpdateLoginState() { 962 if (!chromeos::LoginState::IsInitialized()) 963 return; // LoginState may not be intialized in tests. 964 965 chromeos::LoginState::LoggedInState logged_in_state; 966 logged_in_state = active_user_ ? chromeos::LoginState::LOGGED_IN_ACTIVE 967 : chromeos::LoginState::LOGGED_IN_NONE; 968 969 chromeos::LoginState::LoggedInUserType login_user_type; 970 if (logged_in_state == chromeos::LoginState::LOGGED_IN_NONE) 971 login_user_type = chromeos::LoginState::LOGGED_IN_USER_NONE; 972 else if (is_current_user_owner_) 973 login_user_type = chromeos::LoginState::LOGGED_IN_USER_OWNER; 974 else if (active_user_->GetType() == USER_TYPE_GUEST) 975 login_user_type = chromeos::LoginState::LOGGED_IN_USER_GUEST; 976 else if (active_user_->GetType() == USER_TYPE_RETAIL_MODE) 977 login_user_type = chromeos::LoginState::LOGGED_IN_USER_RETAIL_MODE; 978 else if (active_user_->GetType() == USER_TYPE_PUBLIC_ACCOUNT) 979 login_user_type = chromeos::LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT; 980 else if (active_user_->GetType() == USER_TYPE_SUPERVISED) 981 login_user_type = chromeos::LoginState::LOGGED_IN_USER_SUPERVISED; 982 else if (active_user_->GetType() == USER_TYPE_KIOSK_APP) 983 login_user_type = chromeos::LoginState::LOGGED_IN_USER_KIOSK_APP; 984 else 985 login_user_type = chromeos::LoginState::LOGGED_IN_USER_REGULAR; 986 987 if (primary_user_) { 988 chromeos::LoginState::Get()->SetLoggedInStateAndPrimaryUser( 989 logged_in_state, login_user_type, primary_user_->username_hash()); 990 } else { 991 chromeos::LoginState::Get()->SetLoggedInState(logged_in_state, 992 login_user_type); 993 } 994 } 995 996 void UserManagerBase::SetLRUUser(User* user) { 997 GetLocalState()->SetString(kLastActiveUser, user->email()); 998 GetLocalState()->CommitPendingWrite(); 999 1000 UserList::iterator it = 1001 std::find(lru_logged_in_users_.begin(), lru_logged_in_users_.end(), user); 1002 if (it != lru_logged_in_users_.end()) 1003 lru_logged_in_users_.erase(it); 1004 lru_logged_in_users_.insert(lru_logged_in_users_.begin(), user); 1005 } 1006 1007 void UserManagerBase::SendRegularUserLoginMetrics(const std::string& user_id) { 1008 // If this isn't the first time Chrome was run after the system booted, 1009 // assume that Chrome was restarted because a previous session ended. 1010 if (!CommandLine::ForCurrentProcess()->HasSwitch( 1011 chromeos::switches::kFirstExecAfterBoot)) { 1012 const std::string last_email = 1013 GetLocalState()->GetString(kLastLoggedInRegularUser); 1014 const base::TimeDelta time_to_login = 1015 base::TimeTicks::Now() - manager_creation_time_; 1016 if (!last_email.empty() && user_id != last_email && 1017 time_to_login.InSeconds() <= kLogoutToLoginDelayMaxSec) { 1018 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay", 1019 time_to_login.InSeconds(), 1020 0, 1021 kLogoutToLoginDelayMaxSec, 1022 50); 1023 } 1024 } 1025 } 1026 1027 void UserManagerBase::UpdateUserAccountLocale(const std::string& user_id, 1028 const std::string& locale) { 1029 scoped_ptr<std::string> resolved_locale(new std::string()); 1030 if (!locale.empty() && locale != GetApplicationLocale()) { 1031 // base::Pased will NULL out |resolved_locale|, so cache the underlying ptr. 1032 std::string* raw_resolved_locale = resolved_locale.get(); 1033 blocking_task_runner_->PostTaskAndReply( 1034 FROM_HERE, 1035 base::Bind(ResolveLocale, 1036 locale, 1037 base::Unretained(raw_resolved_locale)), 1038 base::Bind(&UserManagerBase::DoUpdateAccountLocale, 1039 weak_factory_.GetWeakPtr(), 1040 user_id, 1041 base::Passed(&resolved_locale))); 1042 } else { 1043 resolved_locale.reset(new std::string(locale)); 1044 DoUpdateAccountLocale(user_id, resolved_locale.Pass()); 1045 } 1046 } 1047 1048 void UserManagerBase::DoUpdateAccountLocale( 1049 const std::string& user_id, 1050 scoped_ptr<std::string> resolved_locale) { 1051 User* user = FindUserAndModify(user_id); 1052 if (user && resolved_locale) 1053 user->SetAccountLocale(*resolved_locale); 1054 } 1055 1056 void UserManagerBase::DeleteUser(User* user) { 1057 const bool is_active_user = (user == active_user_); 1058 delete user; 1059 if (is_active_user) 1060 active_user_ = NULL; 1061 } 1062 1063 } // namespace user_manager 1064