Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: chrome/browser/chromeos/login/users/user_manager_base.cc

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

Powered by Google App Engine
This is Rietveld 408576698