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.
5 #include "components/user_manager/user_manager_base.h"
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"
37 namespace user_manager
{
40 // A vector pref of the the regular users known on this device, arranged in LRU
42 const char kRegularUsers
[] = "LoggedInUsers";
44 // A dictionary that maps user IDs to the displayed name.
45 const char kUserDisplayName
[] = "UserDisplayName";
47 // A dictionary that maps user IDs to the user's given name.
48 const char kUserGivenName
[] = "UserGivenName";
50 // A dictionary that maps user IDs to the displayed (non-canonical) emails.
51 const char kUserDisplayEmail
[] = "UserDisplayEmail";
53 // A dictionary that maps user IDs to OAuth token presence flag.
54 const char kUserOAuthTokenStatus
[] = "OAuthTokenStatus";
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";
60 // A dictionary that maps user ID to the user type.
61 const char kUserType
[] = "UserType";
63 // A string pref containing the ID of the last user who logged in if it was
64 // a user with gaia account (regular) or an empty string if it was another type
65 // of user (guest, kiosk, public account, etc.).
66 const char kLastLoggedInGaiaUser
[] = "LastLoggedInRegularUser";
68 // A string pref containing the ID of the last active user.
69 // In case of browser crash, this pref will be used to set active user after
71 const char kLastActiveUser
[] = "LastActiveUser";
73 // A vector pref of preferences of known users. All new preferences should be
74 // placed in this list.
75 const char kKnownUsers
[] = "KnownUsers";
77 // Known user preferences keys (stored in Local State).
79 // Key of canonical e-mail value.
80 const char kCanonicalEmail
[] = "email";
82 // Key of obfuscated GAIA id value.
83 const char kGAIAIdKey
[] = "gaia_id";
85 // Upper bound for a histogram metric reporting the amount of time between
86 // one regular user logging out and a different regular user logging in.
87 const int kLogoutToLoginDelayMaxSec
= 1800;
89 // Callback that is called after user removal is complete.
90 void OnRemoveUserComplete(const std::string
& user_email
,
92 cryptohome::MountError return_code
) {
93 // Log the error, but there's not much we can do.
95 LOG(ERROR
) << "Removal of cryptohome for " << user_email
96 << " failed, return code: " << return_code
;
100 // Runs on SequencedWorkerPool thread. Passes resolved locale to UI thread.
101 void ResolveLocale(const std::string
& raw_locale
,
102 std::string
* resolved_locale
) {
103 ignore_result(l10n_util::CheckAndResolveLocale(raw_locale
, resolved_locale
));
106 // Checks if values in |dict| correspond with |user_id| identity.
107 bool UserMatches(const UserID
& user_id
, const base::DictionaryValue
& dict
) {
110 bool has_email
= dict
.GetString(kCanonicalEmail
, &value
);
111 if (has_email
&& user_id
== value
)
114 // TODO(antrim): update code once user id is really a struct.
115 bool has_gaia_id
= dict
.GetString(kGAIAIdKey
, &value
);
116 if (has_gaia_id
&& user_id
== value
)
122 // Fills relevant |dict| values based on |user_id|.
123 void UpdateIdentity(const UserID
& user_id
, base::DictionaryValue
& dict
) {
124 dict
.SetString(kCanonicalEmail
, user_id
);
130 void UserManagerBase::RegisterPrefs(PrefRegistrySimple
* registry
) {
131 registry
->RegisterListPref(kRegularUsers
);
132 registry
->RegisterListPref(kKnownUsers
);
133 registry
->RegisterStringPref(kLastLoggedInGaiaUser
, std::string());
134 registry
->RegisterDictionaryPref(kUserDisplayName
);
135 registry
->RegisterDictionaryPref(kUserGivenName
);
136 registry
->RegisterDictionaryPref(kUserDisplayEmail
);
137 registry
->RegisterDictionaryPref(kUserOAuthTokenStatus
);
138 registry
->RegisterDictionaryPref(kUserForceOnlineSignin
);
139 registry
->RegisterDictionaryPref(kUserType
);
140 registry
->RegisterStringPref(kLastActiveUser
, std::string());
143 UserManagerBase::UserManagerBase(
144 scoped_refptr
<base::TaskRunner
> task_runner
,
145 scoped_refptr
<base::TaskRunner
> blocking_task_runner
)
146 : active_user_(NULL
),
148 user_loading_stage_(STAGE_NOT_LOADED
),
149 session_started_(false),
150 is_current_user_owner_(false),
151 is_current_user_new_(false),
152 is_current_user_ephemeral_regular_user_(false),
153 ephemeral_users_enabled_(false),
154 manager_creation_time_(base::TimeTicks::Now()),
155 last_session_active_user_initialized_(false),
156 task_runner_(task_runner
),
157 blocking_task_runner_(blocking_task_runner
),
158 weak_factory_(this) {
162 UserManagerBase::~UserManagerBase() {
163 // Can't use STLDeleteElements because of the private destructor of User.
164 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end();
165 it
= users_
.erase(it
)) {
168 // These are pointers to the same User instances that were in users_ list.
169 logged_in_users_
.clear();
170 lru_logged_in_users_
.clear();
172 DeleteUser(active_user_
);
175 void UserManagerBase::Shutdown() {
176 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
179 const UserList
& UserManagerBase::GetUsers() const {
180 const_cast<UserManagerBase
*>(this)->EnsureUsersLoaded();
184 const UserList
& UserManagerBase::GetLoggedInUsers() const {
185 return logged_in_users_
;
188 const UserList
& UserManagerBase::GetLRULoggedInUsers() const {
189 return lru_logged_in_users_
;
192 const std::string
& UserManagerBase::GetOwnerEmail() const {
196 void UserManagerBase::UserLoggedIn(const std::string
& user_id
,
197 const std::string
& username_hash
,
198 bool browser_restart
) {
199 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
201 if (!last_session_active_user_initialized_
) {
202 last_session_active_user_
= GetLocalState()->GetString(kLastActiveUser
);
203 last_session_active_user_initialized_
= true;
206 User
* user
= FindUserInListAndModify(user_id
);
207 if (active_user_
&& user
) {
208 user
->set_is_logged_in(true);
209 user
->set_username_hash(username_hash
);
210 logged_in_users_
.push_back(user
);
211 lru_logged_in_users_
.push_back(user
);
213 // Reset the new user flag if the user already exists.
214 SetIsCurrentUserNew(false);
215 NotifyUserAddedToSession(user
, true /* user switch pending */);
220 if (user_id
== chromeos::login::kGuestUserName
) {
222 } else if (IsKioskApp(user_id
)) {
223 KioskAppLoggedIn(user_id
);
224 } else if (IsDemoApp(user_id
)) {
225 DemoAccountLoggedIn();
229 if (user
&& user
->GetType() == USER_TYPE_PUBLIC_ACCOUNT
) {
230 PublicAccountUserLoggedIn(user
);
231 } else if ((user
&& user
->GetType() == USER_TYPE_SUPERVISED
) ||
233 gaia::ExtractDomainName(user_id
) ==
234 chromeos::login::kSupervisedUserDomain
)) {
235 SupervisedUserLoggedIn(user_id
);
236 } else if (browser_restart
&& IsPublicAccountMarkedForRemoval(user_id
)) {
237 PublicAccountUserLoggedIn(User::CreatePublicAccountUser(user_id
));
238 } else if (user_id
!= GetOwnerEmail() && !user
&&
239 (AreEphemeralUsersEnabled() || browser_restart
)) {
240 RegularUserLoggedInAsEphemeral(user_id
);
242 RegularUserLoggedIn(user_id
);
246 DCHECK(active_user_
);
247 active_user_
->set_is_logged_in(true);
248 active_user_
->set_is_active(true);
249 active_user_
->set_username_hash(username_hash
);
251 // Place user who just signed in to the top of the logged in users.
252 logged_in_users_
.insert(logged_in_users_
.begin(), active_user_
);
253 SetLRUUser(active_user_
);
255 if (!primary_user_
) {
256 primary_user_
= active_user_
;
257 if (primary_user_
->HasGaiaAccount())
258 SendGaiaUserLoginMetrics(user_id
);
261 UMA_HISTOGRAM_ENUMERATION(
262 "UserManager.LoginUserType", active_user_
->GetType(), NUM_USER_TYPES
);
264 GetLocalState()->SetString(
265 kLastLoggedInGaiaUser
, active_user_
->HasGaiaAccount() ? user_id
: "");
268 PerformPostUserLoggedInActions(browser_restart
);
271 void UserManagerBase::SwitchActiveUser(const std::string
& user_id
) {
272 User
* user
= FindUserAndModify(user_id
);
274 NOTREACHED() << "Switching to a non-existing user";
277 if (user
== active_user_
) {
278 NOTREACHED() << "Switching to a user who is already active";
281 if (!user
->is_logged_in()) {
282 NOTREACHED() << "Switching to a user that is not logged in";
285 if (!user
->HasGaiaAccount()) {
287 "Switching to a user without gaia account (non-regular one)";
290 if (user
->username_hash().empty()) {
291 NOTREACHED() << "Switching to a user that doesn't have username_hash set";
295 DCHECK(active_user_
);
296 active_user_
->set_is_active(false);
297 user
->set_is_active(true);
300 // Move the user to the front.
301 SetLRUUser(active_user_
);
303 NotifyActiveUserHashChanged(active_user_
->username_hash());
304 NotifyActiveUserChanged(active_user_
);
307 void UserManagerBase::SwitchToLastActiveUser() {
308 if (last_session_active_user_
.empty())
311 if (GetActiveUser()->email() != last_session_active_user_
)
312 SwitchActiveUser(last_session_active_user_
);
314 // Make sure that this function gets run only once.
315 last_session_active_user_
.clear();
318 void UserManagerBase::SessionStarted() {
319 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
320 session_started_
= true;
323 session_manager::SessionManager::Get()->SetSessionState(
324 session_manager::SESSION_STATE_ACTIVE
);
326 if (IsCurrentUserNew()) {
327 // Make sure that the new user's data is persisted to Local State.
328 GetLocalState()->CommitPendingWrite();
332 void UserManagerBase::RemoveUser(const std::string
& user_id
,
333 RemoveUserDelegate
* delegate
) {
334 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
336 if (!CanUserBeRemoved(FindUser(user_id
)))
339 RemoveUserInternal(user_id
, delegate
);
342 void UserManagerBase::RemoveUserInternal(const std::string
& user_email
,
343 RemoveUserDelegate
* delegate
) {
344 RemoveNonOwnerUserInternal(user_email
, delegate
);
347 void UserManagerBase::RemoveNonOwnerUserInternal(const std::string
& user_email
,
348 RemoveUserDelegate
* delegate
) {
350 delegate
->OnBeforeUserRemoved(user_email
);
351 RemoveUserFromList(user_email
);
352 cryptohome::AsyncMethodCaller::GetInstance()->AsyncRemove(
353 user_email
, base::Bind(&OnRemoveUserComplete
, user_email
));
356 delegate
->OnUserRemoved(user_email
);
359 void UserManagerBase::RemoveUserFromList(const std::string
& user_id
) {
360 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
361 RemoveNonCryptohomeData(user_id
);
362 if (user_loading_stage_
== STAGE_LOADED
) {
363 DeleteUser(RemoveRegularOrSupervisedUserFromList(user_id
));
364 } else if (user_loading_stage_
== STAGE_LOADING
) {
365 DCHECK(gaia::ExtractDomainName(user_id
) ==
366 chromeos::login::kSupervisedUserDomain
||
367 HasPendingBootstrap(user_id
));
368 // Special case, removing partially-constructed supervised user or
369 // boostrapping user during user list loading.
370 ListPrefUpdate
users_update(GetLocalState(), kRegularUsers
);
371 users_update
->Remove(base::StringValue(user_id
), NULL
);
373 NOTREACHED() << "Users are not loaded yet.";
377 // Make sure that new data is persisted to Local State.
378 GetLocalState()->CommitPendingWrite();
381 bool UserManagerBase::IsKnownUser(const std::string
& user_id
) const {
382 return FindUser(user_id
) != NULL
;
385 const User
* UserManagerBase::FindUser(const std::string
& user_id
) const {
386 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
387 if (active_user_
&& active_user_
->email() == user_id
)
389 return FindUserInList(user_id
);
392 User
* UserManagerBase::FindUserAndModify(const std::string
& user_id
) {
393 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
394 if (active_user_
&& active_user_
->email() == user_id
)
396 return FindUserInListAndModify(user_id
);
399 const User
* UserManagerBase::GetLoggedInUser() const {
400 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
404 User
* UserManagerBase::GetLoggedInUser() {
405 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
409 const User
* UserManagerBase::GetActiveUser() const {
410 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
414 User
* UserManagerBase::GetActiveUser() {
415 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
419 const User
* UserManagerBase::GetPrimaryUser() const {
420 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
421 return primary_user_
;
424 void UserManagerBase::SaveUserOAuthStatus(
425 const std::string
& user_id
,
426 User::OAuthTokenStatus oauth_token_status
) {
427 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
429 DVLOG(1) << "Saving user OAuth token status in Local State";
430 User
* user
= FindUserAndModify(user_id
);
432 user
->set_oauth_token_status(oauth_token_status
);
434 // Do not update local state if data stored or cached outside the user's
435 // cryptohome is to be treated as ephemeral.
436 if (IsUserNonCryptohomeDataEphemeral(user_id
))
439 DictionaryPrefUpdate
oauth_status_update(GetLocalState(),
440 kUserOAuthTokenStatus
);
441 oauth_status_update
->SetWithoutPathExpansion(
443 new base::FundamentalValue(static_cast<int>(oauth_token_status
)));
446 void UserManagerBase::SaveForceOnlineSignin(const std::string
& user_id
,
447 bool force_online_signin
) {
448 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
450 // Do not update local state if data stored or cached outside the user's
451 // cryptohome is to be treated as ephemeral.
452 if (IsUserNonCryptohomeDataEphemeral(user_id
))
455 DictionaryPrefUpdate
force_online_update(GetLocalState(),
456 kUserForceOnlineSignin
);
457 force_online_update
->SetBooleanWithoutPathExpansion(user_id
,
458 force_online_signin
);
461 void UserManagerBase::SaveUserDisplayName(const std::string
& user_id
,
462 const base::string16
& display_name
) {
463 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
465 if (User
* user
= FindUserAndModify(user_id
)) {
466 user
->set_display_name(display_name
);
468 // Do not update local state if data stored or cached outside the user's
469 // cryptohome is to be treated as ephemeral.
470 if (!IsUserNonCryptohomeDataEphemeral(user_id
)) {
471 DictionaryPrefUpdate
display_name_update(GetLocalState(),
473 display_name_update
->SetWithoutPathExpansion(
474 user_id
, new base::StringValue(display_name
));
479 base::string16
UserManagerBase::GetUserDisplayName(
480 const std::string
& user_id
) const {
481 const User
* user
= FindUser(user_id
);
482 return user
? user
->display_name() : base::string16();
485 void UserManagerBase::SaveUserDisplayEmail(const std::string
& user_id
,
486 const std::string
& display_email
) {
487 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
489 User
* user
= FindUserAndModify(user_id
);
491 LOG(ERROR
) << "User not found: " << user_id
;
492 return; // Ignore if there is no such user.
495 user
->set_display_email(display_email
);
497 // Do not update local state if data stored or cached outside the user's
498 // cryptohome is to be treated as ephemeral.
499 if (IsUserNonCryptohomeDataEphemeral(user_id
))
502 DictionaryPrefUpdate
display_email_update(GetLocalState(), kUserDisplayEmail
);
503 display_email_update
->SetWithoutPathExpansion(
504 user_id
, new base::StringValue(display_email
));
507 std::string
UserManagerBase::GetUserDisplayEmail(
508 const std::string
& user_id
) const {
509 const User
* user
= FindUser(user_id
);
510 return user
? user
->display_email() : user_id
;
513 void UserManagerBase::SaveUserType(const std::string
& user_id
,
514 const UserType
& user_type
) {
515 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
517 User
* user
= FindUserAndModify(user_id
);
519 LOG(ERROR
) << "User not found: " << user_id
;
520 return; // Ignore if there is no such user.
523 // Do not update local state if data stored or cached outside the user's
524 // cryptohome is to be treated as ephemeral.
525 if (IsUserNonCryptohomeDataEphemeral(user_id
))
528 DictionaryPrefUpdate
user_type_update(GetLocalState(), kUserType
);
529 user_type_update
->SetWithoutPathExpansion(
530 user_id
, new base::FundamentalValue(static_cast<int>(user_type
)));
531 GetLocalState()->CommitPendingWrite();
534 void UserManagerBase::UpdateUserAccountData(
535 const std::string
& user_id
,
536 const UserAccountData
& account_data
) {
537 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
539 SaveUserDisplayName(user_id
, account_data
.display_name());
541 if (User
* user
= FindUserAndModify(user_id
)) {
542 base::string16 given_name
= account_data
.given_name();
543 user
->set_given_name(given_name
);
544 if (!IsUserNonCryptohomeDataEphemeral(user_id
)) {
545 DictionaryPrefUpdate
given_name_update(GetLocalState(), kUserGivenName
);
546 given_name_update
->SetWithoutPathExpansion(
547 user_id
, new base::StringValue(given_name
));
551 UpdateUserAccountLocale(user_id
, account_data
.locale());
555 void UserManagerBase::ParseUserList(const base::ListValue
& users_list
,
556 const std::set
<std::string
>& existing_users
,
557 std::vector
<std::string
>* users_vector
,
558 std::set
<std::string
>* users_set
) {
559 users_vector
->clear();
561 for (size_t i
= 0; i
< users_list
.GetSize(); ++i
) {
563 if (!users_list
.GetString(i
, &email
) || email
.empty()) {
564 LOG(ERROR
) << "Corrupt entry in user list at index " << i
<< ".";
567 if (existing_users
.find(email
) != existing_users
.end() ||
568 !users_set
->insert(email
).second
) {
569 LOG(ERROR
) << "Duplicate user: " << email
;
572 users_vector
->push_back(email
);
576 bool UserManagerBase::IsCurrentUserOwner() const {
577 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
578 base::AutoLock
lk(is_current_user_owner_lock_
);
579 return is_current_user_owner_
;
582 void UserManagerBase::SetCurrentUserIsOwner(bool is_current_user_owner
) {
583 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
585 base::AutoLock
lk(is_current_user_owner_lock_
);
586 is_current_user_owner_
= is_current_user_owner
;
591 bool UserManagerBase::IsCurrentUserNew() const {
592 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
593 return is_current_user_new_
;
596 bool UserManagerBase::IsCurrentUserNonCryptohomeDataEphemeral() const {
597 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
598 return IsUserLoggedIn() &&
599 IsUserNonCryptohomeDataEphemeral(GetLoggedInUser()->email());
602 bool UserManagerBase::CanCurrentUserLock() const {
603 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
604 return IsUserLoggedIn() && active_user_
->can_lock();
607 bool UserManagerBase::IsUserLoggedIn() const {
608 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
612 bool UserManagerBase::IsLoggedInAsUserWithGaiaAccount() const {
613 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
614 return IsUserLoggedIn() && active_user_
->HasGaiaAccount();
617 bool UserManagerBase::IsLoggedInAsChildUser() const {
618 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
619 return IsUserLoggedIn() && active_user_
->GetType() == USER_TYPE_CHILD
;
622 bool UserManagerBase::IsLoggedInAsPublicAccount() const {
623 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
624 return IsUserLoggedIn() &&
625 active_user_
->GetType() == USER_TYPE_PUBLIC_ACCOUNT
;
628 bool UserManagerBase::IsLoggedInAsGuest() const {
629 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
630 return IsUserLoggedIn() && active_user_
->GetType() == USER_TYPE_GUEST
;
633 bool UserManagerBase::IsLoggedInAsSupervisedUser() const {
634 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
635 return IsUserLoggedIn() && active_user_
->GetType() == USER_TYPE_SUPERVISED
;
638 bool UserManagerBase::IsLoggedInAsKioskApp() const {
639 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
640 return IsUserLoggedIn() && active_user_
->GetType() == USER_TYPE_KIOSK_APP
;
643 bool UserManagerBase::IsLoggedInAsStub() const {
644 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
645 return IsUserLoggedIn() &&
646 active_user_
->email() == chromeos::login::kStubUser
;
649 bool UserManagerBase::IsSessionStarted() const {
650 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
651 return session_started_
;
654 bool UserManagerBase::IsUserNonCryptohomeDataEphemeral(
655 const std::string
& user_id
) const {
656 // Data belonging to the guest and stub users is always ephemeral.
657 if (user_id
== chromeos::login::kGuestUserName
||
658 user_id
== chromeos::login::kStubUser
) {
662 // Data belonging to the owner, anyone found on the user list and obsolete
663 // public accounts whose data has not been removed yet is not ephemeral.
664 if (user_id
== GetOwnerEmail() || UserExistsInList(user_id
) ||
665 IsPublicAccountMarkedForRemoval(user_id
)) {
669 // Data belonging to the currently logged-in user is ephemeral when:
670 // a) The user logged into a regular gaia account while the ephemeral users
671 // policy was enabled.
673 // b) The user logged into any other account type.
674 if (IsUserLoggedIn() && (user_id
== GetLoggedInUser()->email()) &&
675 (is_current_user_ephemeral_regular_user_
||
676 !IsLoggedInAsUserWithGaiaAccount())) {
680 // Data belonging to any other user is ephemeral when:
681 // a) Going through the regular login flow and the ephemeral users policy is
684 // b) The browser is restarting after a crash.
685 return AreEphemeralUsersEnabled() ||
686 session_manager::SessionManager::HasBrowserRestarted();
689 void UserManagerBase::AddObserver(UserManager::Observer
* obs
) {
690 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
691 observer_list_
.AddObserver(obs
);
694 void UserManagerBase::RemoveObserver(UserManager::Observer
* obs
) {
695 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
696 observer_list_
.RemoveObserver(obs
);
699 void UserManagerBase::AddSessionStateObserver(
700 UserManager::UserSessionStateObserver
* obs
) {
701 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
702 session_state_observer_list_
.AddObserver(obs
);
705 void UserManagerBase::RemoveSessionStateObserver(
706 UserManager::UserSessionStateObserver
* obs
) {
707 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
708 session_state_observer_list_
.RemoveObserver(obs
);
711 void UserManagerBase::NotifyLocalStateChanged() {
712 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
714 UserManager::Observer
, observer_list_
, LocalStateChanged(this));
717 bool UserManagerBase::CanUserBeRemoved(const User
* user
) const {
718 // Only regular and supervised users are allowed to be manually removed.
719 if (!user
|| !(user
->HasGaiaAccount() || user
->IsSupervised()))
722 // Sanity check: we must not remove single user unless it's an enterprise
723 // device. This check may seem redundant at a first sight because
724 // this single user must be an owner and we perform special check later
725 // in order not to remove an owner. However due to non-instant nature of
726 // ownership assignment this later check may sometimes fail.
727 // See http://crosbug.com/12723
728 if (users_
.size() < 2 && !IsEnterpriseManaged())
731 // Sanity check: do not allow any of the the logged in users to be removed.
732 for (UserList::const_iterator it
= logged_in_users_
.begin();
733 it
!= logged_in_users_
.end();
735 if ((*it
)->email() == user
->email())
742 bool UserManagerBase::GetEphemeralUsersEnabled() const {
743 return ephemeral_users_enabled_
;
746 void UserManagerBase::SetEphemeralUsersEnabled(bool enabled
) {
747 ephemeral_users_enabled_
= enabled
;
750 void UserManagerBase::SetIsCurrentUserNew(bool is_new
) {
751 is_current_user_new_
= is_new
;
754 bool UserManagerBase::HasPendingBootstrap(const std::string
& user_id
) const {
758 void UserManagerBase::SetOwnerEmail(std::string owner_user_id
) {
759 owner_email_
= owner_user_id
;
762 const std::string
& UserManagerBase::GetPendingUserSwitchID() const {
763 return pending_user_switch_
;
766 void UserManagerBase::SetPendingUserSwitchID(std::string user_id
) {
767 pending_user_switch_
= user_id
;
770 void UserManagerBase::EnsureUsersLoaded() {
771 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
772 if (!GetLocalState())
775 if (user_loading_stage_
!= STAGE_NOT_LOADED
)
777 user_loading_stage_
= STAGE_LOADING
;
779 PerformPreUserListLoadingActions();
781 PrefService
* local_state
= GetLocalState();
782 const base::ListValue
* prefs_regular_users
=
783 local_state
->GetList(kRegularUsers
);
785 const base::DictionaryValue
* prefs_display_names
=
786 local_state
->GetDictionary(kUserDisplayName
);
787 const base::DictionaryValue
* prefs_given_names
=
788 local_state
->GetDictionary(kUserGivenName
);
789 const base::DictionaryValue
* prefs_display_emails
=
790 local_state
->GetDictionary(kUserDisplayEmail
);
791 const base::DictionaryValue
* prefs_user_types
=
792 local_state
->GetDictionary(kUserType
);
794 // Load public sessions first.
795 std::set
<std::string
> public_sessions_set
;
796 LoadPublicAccounts(&public_sessions_set
);
798 // Load regular users and supervised users.
799 std::vector
<std::string
> regular_users
;
800 std::set
<std::string
> regular_users_set
;
801 ParseUserList(*prefs_regular_users
,
805 for (std::vector
<std::string
>::const_iterator it
= regular_users
.begin();
806 it
!= regular_users
.end();
809 const std::string domain
= gaia::ExtractDomainName(*it
);
810 if (domain
== chromeos::login::kSupervisedUserDomain
) {
811 user
= User::CreateSupervisedUser(*it
);
813 user
= User::CreateRegularUser(*it
);
815 if (prefs_user_types
->GetIntegerWithoutPathExpansion(*it
, &user_type
) &&
816 user_type
== USER_TYPE_CHILD
) {
817 ChangeUserChildStatus(user
, true /* is child */);
820 user
->set_oauth_token_status(LoadUserOAuthStatus(*it
));
821 user
->set_force_online_signin(LoadForceOnlineSignin(*it
));
822 users_
.push_back(user
);
824 base::string16 display_name
;
825 if (prefs_display_names
->GetStringWithoutPathExpansion(*it
,
827 user
->set_display_name(display_name
);
830 base::string16 given_name
;
831 if (prefs_given_names
->GetStringWithoutPathExpansion(*it
, &given_name
)) {
832 user
->set_given_name(given_name
);
835 std::string display_email
;
836 if (prefs_display_emails
->GetStringWithoutPathExpansion(*it
,
838 user
->set_display_email(display_email
);
842 user_loading_stage_
= STAGE_LOADED
;
844 PerformPostUserListLoadingActions();
847 UserList
& UserManagerBase::GetUsersAndModify() {
852 const User
* UserManagerBase::FindUserInList(const std::string
& user_id
) const {
853 const UserList
& users
= GetUsers();
854 for (UserList::const_iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
855 if ((*it
)->email() == user_id
)
861 bool UserManagerBase::UserExistsInList(const std::string
& user_id
) const {
862 const base::ListValue
* user_list
= GetLocalState()->GetList(kRegularUsers
);
863 for (size_t i
= 0; i
< user_list
->GetSize(); ++i
) {
865 if (user_list
->GetString(i
, &email
) && (user_id
== email
))
871 User
* UserManagerBase::FindUserInListAndModify(const std::string
& user_id
) {
872 UserList
& users
= GetUsersAndModify();
873 for (UserList::iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
874 if ((*it
)->email() == user_id
)
880 void UserManagerBase::GuestUserLoggedIn() {
881 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
882 active_user_
= User::CreateGuestUser();
885 void UserManagerBase::AddUserRecord(User
* user
) {
886 // Add the user to the front of the user list.
887 ListPrefUpdate
prefs_users_update(GetLocalState(), kRegularUsers
);
888 prefs_users_update
->Insert(0, new base::StringValue(user
->email()));
889 users_
.insert(users_
.begin(), user
);
892 void UserManagerBase::RegularUserLoggedIn(const std::string
& user_id
) {
893 // Remove the user from the user list.
894 active_user_
= RemoveRegularOrSupervisedUserFromList(user_id
);
896 // If the user was not found on the user list, create a new user.
897 SetIsCurrentUserNew(!active_user_
);
898 if (IsCurrentUserNew()) {
899 active_user_
= User::CreateRegularUser(user_id
);
900 active_user_
->set_oauth_token_status(LoadUserOAuthStatus(user_id
));
901 SaveUserDisplayName(active_user_
->email(),
902 base::UTF8ToUTF16(active_user_
->GetAccountName(true)));
905 AddUserRecord(active_user_
);
907 // Make sure that new data is persisted to Local State.
908 GetLocalState()->CommitPendingWrite();
911 void UserManagerBase::RegularUserLoggedInAsEphemeral(
912 const std::string
& user_id
) {
913 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
914 SetIsCurrentUserNew(true);
915 is_current_user_ephemeral_regular_user_
= true;
916 active_user_
= User::CreateRegularUser(user_id
);
919 void UserManagerBase::NotifyOnLogin() {
920 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
922 NotifyActiveUserHashChanged(active_user_
->username_hash());
923 NotifyActiveUserChanged(active_user_
);
927 User::OAuthTokenStatus
UserManagerBase::LoadUserOAuthStatus(
928 const std::string
& user_id
) const {
929 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
931 const base::DictionaryValue
* prefs_oauth_status
=
932 GetLocalState()->GetDictionary(kUserOAuthTokenStatus
);
933 int oauth_token_status
= User::OAUTH_TOKEN_STATUS_UNKNOWN
;
934 if (prefs_oauth_status
&&
935 prefs_oauth_status
->GetIntegerWithoutPathExpansion(user_id
,
936 &oauth_token_status
)) {
937 User::OAuthTokenStatus status
=
938 static_cast<User::OAuthTokenStatus
>(oauth_token_status
);
939 HandleUserOAuthTokenStatusChange(user_id
, status
);
943 return User::OAUTH_TOKEN_STATUS_UNKNOWN
;
946 bool UserManagerBase::LoadForceOnlineSignin(const std::string
& user_id
) const {
947 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
949 const base::DictionaryValue
* prefs_force_online
=
950 GetLocalState()->GetDictionary(kUserForceOnlineSignin
);
951 bool force_online_signin
= false;
952 if (prefs_force_online
) {
953 prefs_force_online
->GetBooleanWithoutPathExpansion(user_id
,
954 &force_online_signin
);
956 return force_online_signin
;
959 void UserManagerBase::RemoveNonCryptohomeData(const std::string
& user_id
) {
960 PrefService
* prefs
= GetLocalState();
961 DictionaryPrefUpdate
prefs_display_name_update(prefs
, kUserDisplayName
);
962 prefs_display_name_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
964 DictionaryPrefUpdate
prefs_given_name_update(prefs
, kUserGivenName
);
965 prefs_given_name_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
967 DictionaryPrefUpdate
prefs_display_email_update(prefs
, kUserDisplayEmail
);
968 prefs_display_email_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
970 DictionaryPrefUpdate
prefs_oauth_update(prefs
, kUserOAuthTokenStatus
);
971 prefs_oauth_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
973 DictionaryPrefUpdate
prefs_force_online_update(prefs
, kUserForceOnlineSignin
);
974 prefs_force_online_update
->RemoveWithoutPathExpansion(user_id
, NULL
);
976 RemoveKnownUserPrefs(user_id
);
978 std::string last_active_user
= GetLocalState()->GetString(kLastActiveUser
);
979 if (user_id
== last_active_user
)
980 GetLocalState()->SetString(kLastActiveUser
, std::string());
983 bool UserManagerBase::FindKnownUserPrefs(
984 const UserID
& user_id
,
985 const base::DictionaryValue
** out_value
) {
986 PrefService
* local_state
= GetLocalState();
987 const base::ListValue
* known_users
= local_state
->GetList(kKnownUsers
);
988 for (size_t i
= 0; i
< known_users
->GetSize(); ++i
) {
989 const base::DictionaryValue
* element
= nullptr;
990 if (known_users
->GetDictionary(i
, &element
)) {
991 if (UserMatches(user_id
, *element
)) {
992 known_users
->GetDictionary(i
, out_value
);
1000 void UserManagerBase::UpdateKnownUserPrefs(const UserID
& user_id
,
1001 const base::DictionaryValue
& values
,
1003 ListPrefUpdate
update(GetLocalState(), kKnownUsers
);
1004 for (size_t i
= 0; i
< update
->GetSize(); ++i
) {
1005 base::DictionaryValue
* element
= nullptr;
1006 if (update
->GetDictionary(i
, &element
)) {
1007 if (UserMatches(user_id
, *element
)) {
1010 element
->MergeDictionary(&values
);
1011 UpdateIdentity(user_id
, *element
);
1016 scoped_ptr
<base::DictionaryValue
> new_value(new base::DictionaryValue());
1017 new_value
->MergeDictionary(&values
);
1018 UpdateIdentity(user_id
, *new_value
);
1019 update
->Append(new_value
.release());
1022 bool UserManagerBase::GetKnownUserStringPref(const UserID
& user_id
,
1023 const std::string
& path
,
1024 std::string
* out_value
) {
1025 const base::DictionaryValue
* user_pref_dict
= nullptr;
1026 if (!FindKnownUserPrefs(user_id
, &user_pref_dict
))
1029 return user_pref_dict
->GetString(path
, out_value
);
1032 void UserManagerBase::SetKnownUserStringPref(const UserID
& user_id
,
1033 const std::string
& path
,
1034 const std::string
& in_value
) {
1035 ListPrefUpdate
update(GetLocalState(), kKnownUsers
);
1036 base::DictionaryValue dict
;
1037 dict
.SetString(path
, in_value
);
1038 UpdateKnownUserPrefs(user_id
, dict
, false);
1041 void UserManagerBase::UpdateGaiaID(const UserID
& user_id
,
1042 const std::string
& gaia_id
) {
1043 SetKnownUserStringPref(user_id
, kGAIAIdKey
, gaia_id
);
1046 bool UserManagerBase::FindGaiaID(const UserID
& user_id
,
1047 std::string
* out_value
) {
1048 return GetKnownUserStringPref(user_id
, kGAIAIdKey
, out_value
);
1051 User
* UserManagerBase::RemoveRegularOrSupervisedUserFromList(
1052 const std::string
& user_id
) {
1053 ListPrefUpdate
prefs_users_update(GetLocalState(), kRegularUsers
);
1054 prefs_users_update
->Clear();
1056 for (UserList::iterator it
= users_
.begin(); it
!= users_
.end();) {
1057 const std::string user_email
= (*it
)->email();
1058 if (user_email
== user_id
) {
1060 it
= users_
.erase(it
);
1062 if ((*it
)->HasGaiaAccount() || (*it
)->IsSupervised())
1063 prefs_users_update
->Append(new base::StringValue(user_email
));
1070 void UserManagerBase::RemoveKnownUserPrefs(const UserID
& user_id
) {
1071 ListPrefUpdate
update(GetLocalState(), kKnownUsers
);
1072 for (size_t i
= 0; i
< update
->GetSize(); ++i
) {
1073 base::DictionaryValue
* element
= nullptr;
1074 if (update
->GetDictionary(i
, &element
)) {
1075 if (UserMatches(user_id
, *element
)) {
1076 update
->Remove(i
, nullptr);
1083 void UserManagerBase::NotifyActiveUserChanged(const User
* active_user
) {
1084 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
1085 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1086 session_state_observer_list_
,
1087 ActiveUserChanged(active_user
));
1090 void UserManagerBase::NotifyUserAddedToSession(const User
* added_user
,
1091 bool user_switch_pending
) {
1092 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
1093 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1094 session_state_observer_list_
,
1095 UserAddedToSession(added_user
));
1098 void UserManagerBase::NotifyActiveUserHashChanged(const std::string
& hash
) {
1099 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
1100 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1101 session_state_observer_list_
,
1102 ActiveUserHashChanged(hash
));
1105 void UserManagerBase::ChangeUserChildStatus(User
* user
, bool is_child
) {
1106 DCHECK(task_runner_
->RunsTasksOnCurrentThread());
1107 if (user
->IsSupervised() == is_child
)
1109 user
->SetIsChild(is_child
);
1110 SaveUserType(user
->email(), is_child
? user_manager::USER_TYPE_CHILD
1111 : user_manager::USER_TYPE_REGULAR
);
1112 FOR_EACH_OBSERVER(UserManager::UserSessionStateObserver
,
1113 session_state_observer_list_
,
1114 UserChangedChildStatus(user
));
1117 void UserManagerBase::UpdateLoginState() {
1118 if (!chromeos::LoginState::IsInitialized())
1119 return; // LoginState may not be initialized in tests.
1121 chromeos::LoginState::LoggedInState logged_in_state
;
1122 logged_in_state
= active_user_
? chromeos::LoginState::LOGGED_IN_ACTIVE
1123 : chromeos::LoginState::LOGGED_IN_NONE
;
1125 chromeos::LoginState::LoggedInUserType login_user_type
;
1126 if (logged_in_state
== chromeos::LoginState::LOGGED_IN_NONE
)
1127 login_user_type
= chromeos::LoginState::LOGGED_IN_USER_NONE
;
1128 else if (is_current_user_owner_
)
1129 login_user_type
= chromeos::LoginState::LOGGED_IN_USER_OWNER
;
1130 else if (active_user_
->GetType() == USER_TYPE_GUEST
)
1131 login_user_type
= chromeos::LoginState::LOGGED_IN_USER_GUEST
;
1132 else if (active_user_
->GetType() == USER_TYPE_PUBLIC_ACCOUNT
)
1133 login_user_type
= chromeos::LoginState::LOGGED_IN_USER_PUBLIC_ACCOUNT
;
1134 else if (active_user_
->GetType() == USER_TYPE_SUPERVISED
)
1135 login_user_type
= chromeos::LoginState::LOGGED_IN_USER_SUPERVISED
;
1136 else if (active_user_
->GetType() == USER_TYPE_KIOSK_APP
)
1137 login_user_type
= chromeos::LoginState::LOGGED_IN_USER_KIOSK_APP
;
1139 login_user_type
= chromeos::LoginState::LOGGED_IN_USER_REGULAR
;
1141 if (primary_user_
) {
1142 chromeos::LoginState::Get()->SetLoggedInStateAndPrimaryUser(
1143 logged_in_state
, login_user_type
, primary_user_
->username_hash());
1145 chromeos::LoginState::Get()->SetLoggedInState(logged_in_state
,
1150 void UserManagerBase::SetLRUUser(User
* user
) {
1151 GetLocalState()->SetString(kLastActiveUser
, user
->email());
1152 GetLocalState()->CommitPendingWrite();
1154 UserList::iterator it
=
1155 std::find(lru_logged_in_users_
.begin(), lru_logged_in_users_
.end(), user
);
1156 if (it
!= lru_logged_in_users_
.end())
1157 lru_logged_in_users_
.erase(it
);
1158 lru_logged_in_users_
.insert(lru_logged_in_users_
.begin(), user
);
1161 void UserManagerBase::SendGaiaUserLoginMetrics(const std::string
& user_id
) {
1162 // If this isn't the first time Chrome was run after the system booted,
1163 // assume that Chrome was restarted because a previous session ended.
1164 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
1165 chromeos::switches::kFirstExecAfterBoot
)) {
1166 const std::string last_email
=
1167 GetLocalState()->GetString(kLastLoggedInGaiaUser
);
1168 const base::TimeDelta time_to_login
=
1169 base::TimeTicks::Now() - manager_creation_time_
;
1170 if (!last_email
.empty() && user_id
!= last_email
&&
1171 time_to_login
.InSeconds() <= kLogoutToLoginDelayMaxSec
) {
1172 UMA_HISTOGRAM_CUSTOM_COUNTS("UserManager.LogoutToLoginDelay",
1173 time_to_login
.InSeconds(),
1175 kLogoutToLoginDelayMaxSec
,
1181 void UserManagerBase::UpdateUserAccountLocale(const std::string
& user_id
,
1182 const std::string
& locale
) {
1183 scoped_ptr
<std::string
> resolved_locale(new std::string());
1184 if (!locale
.empty() && locale
!= GetApplicationLocale()) {
1185 // base::Pased will NULL out |resolved_locale|, so cache the underlying ptr.
1186 std::string
* raw_resolved_locale
= resolved_locale
.get();
1187 blocking_task_runner_
->PostTaskAndReply(
1189 base::Bind(ResolveLocale
,
1191 base::Unretained(raw_resolved_locale
)),
1192 base::Bind(&UserManagerBase::DoUpdateAccountLocale
,
1193 weak_factory_
.GetWeakPtr(),
1195 base::Passed(&resolved_locale
)));
1197 resolved_locale
.reset(new std::string(locale
));
1198 DoUpdateAccountLocale(user_id
, resolved_locale
.Pass());
1202 void UserManagerBase::DoUpdateAccountLocale(
1203 const std::string
& user_id
,
1204 scoped_ptr
<std::string
> resolved_locale
) {
1205 User
* user
= FindUserAndModify(user_id
);
1206 if (user
&& resolved_locale
)
1207 user
->SetAccountLocale(*resolved_locale
);
1210 void UserManagerBase::DeleteUser(User
* user
) {
1211 const bool is_active_user
= (user
== active_user_
);
1214 active_user_
= NULL
;
1217 } // namespace user_manager