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/chrome_user_manager_impl.h"
6
7 #include <cstddef>
8 #include <set>
9
10 #include "ash/multi_profile_uma.h"
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/command_line.h"
14 #include "base/compiler_specific.h"
15 #include "base/format_macros.h"
16 #include "base/logging.h"
17 #include "base/metrics/histogram.h"
18 #include "base/prefs/pref_registry_simple.h"
19 #include "base/prefs/pref_service.h"
20 #include "base/prefs/scoped_user_pref_update.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/thread_task_runner_handle.h"
25 #include "base/values.h"
26 #include "chrome/browser/browser_process.h"
27 #include "chrome/browser/chrome_notification_types.h"
28 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
29 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
30 #include "chrome/browser/chromeos/login/signin/auth_sync_observer.h"
31 #include "chrome/browser/chromeos/login/signin/auth_sync_observer_factory.h"
32 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
33 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
34 #include "chrome/browser/chromeos/login/users/supervised_user_manager_impl.h"
35 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
36 #include "chrome/browser/chromeos/policy/device_local_account.h"
37 #include "chrome/browser/chromeos/profiles/multiprofiles_session_aborted_dialog.h"
38 #include "chrome/browser/chromeos/profiles/profile_helper.h"
39 #include "chrome/browser/chromeos/session_length_limiter.h"
40 #include "chrome/browser/profiles/profile.h"
41 #include "chrome/browser/signin/easy_unlock_service.h"
42 #include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
43 #include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
44 #include "chrome/common/chrome_constants.h"
45 #include "chrome/common/chrome_switches.h"
46 #include "chrome/common/crash_keys.h"
47 #include "chrome/common/pref_names.h"
48 #include "chrome/grit/theme_resources.h"
49 #include "chromeos/chromeos_switches.h"
50 #include "chromeos/login/user_names.h"
51 #include "chromeos/settings/cros_settings_names.h"
52 #include "components/session_manager/core/session_manager.h"
53 #include "components/user_manager/remove_user_delegate.h"
54 #include "components/user_manager/user_image/user_image.h"
55 #include "components/user_manager/user_type.h"
56 #include "content/public/browser/browser_thread.h"
57 #include "content/public/browser/notification_service.h"
58 #include "policy/policy_constants.h"
59 #include "ui/base/resource/resource_bundle.h"
60 #include "ui/wm/core/wm_core_switches.h"
61
62 using content::BrowserThread;
63
64 namespace chromeos {
65 namespace {
66
67 // A vector pref of the the regular users known on this device, arranged in LRU
68 // order.
69 const char kRegularUsers[] = "LoggedInUsers";
70
71 // A vector pref of the public accounts defined on this device.
72 const char kPublicAccounts[] = "PublicAccounts";
73
74 // A string pref that gets set when a public account is removed but a user is
75 // currently logged into that account, requiring the account's data to be
76 // removed after logout.
77 const char kPublicAccountPendingDataRemoval[] =
78 "PublicAccountPendingDataRemoval";
79
80 } // namespace
81
82 // static
RegisterPrefs(PrefRegistrySimple * registry)83 void ChromeUserManagerImpl::RegisterPrefs(PrefRegistrySimple* registry) {
84 ChromeUserManager::RegisterPrefs(registry);
85
86 registry->RegisterListPref(kPublicAccounts);
87 registry->RegisterStringPref(kPublicAccountPendingDataRemoval, std::string());
88 SupervisedUserManager::RegisterPrefs(registry);
89 SessionLengthLimiter::RegisterPrefs(registry);
90 }
91
92 // static
CreateChromeUserManager()93 scoped_ptr<ChromeUserManager> ChromeUserManagerImpl::CreateChromeUserManager() {
94 return scoped_ptr<ChromeUserManager>(new ChromeUserManagerImpl());
95 }
96
ChromeUserManagerImpl()97 ChromeUserManagerImpl::ChromeUserManagerImpl()
98 : ChromeUserManager(base::ThreadTaskRunnerHandle::Get(),
99 BrowserThread::GetBlockingPool()),
100 cros_settings_(CrosSettings::Get()),
101 device_local_account_policy_service_(NULL),
102 supervised_user_manager_(new SupervisedUserManagerImpl(this)),
103 weak_factory_(this) {
104 UpdateNumberOfUsers();
105
106 // UserManager instance should be used only on UI thread.
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
108 registrar_.Add(this,
109 chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED,
110 content::NotificationService::AllSources());
111 registrar_.Add(this,
112 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
113 content::NotificationService::AllSources());
114 registrar_.Add(this,
115 chrome::NOTIFICATION_PROFILE_CREATED,
116 content::NotificationService::AllSources());
117
118 // Since we're in ctor postpone any actions till this is fully created.
119 if (base::MessageLoop::current()) {
120 base::MessageLoop::current()->PostTask(
121 FROM_HERE,
122 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies,
123 weak_factory_.GetWeakPtr()));
124 }
125
126 local_accounts_subscription_ = cros_settings_->AddSettingsObserver(
127 kAccountsPrefDeviceLocalAccounts,
128 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies,
129 weak_factory_.GetWeakPtr()));
130 multi_profile_user_controller_.reset(
131 new MultiProfileUserController(this, GetLocalState()));
132
133 policy::BrowserPolicyConnectorChromeOS* connector =
134 g_browser_process->platform_part()->browser_policy_connector_chromeos();
135 avatar_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
136 cros_settings_,
137 connector->GetDeviceLocalAccountPolicyService(),
138 policy::key::kUserAvatarImage,
139 this));
140 avatar_policy_observer_->Init();
141
142 wallpaper_policy_observer_.reset(new policy::CloudExternalDataPolicyObserver(
143 cros_settings_,
144 connector->GetDeviceLocalAccountPolicyService(),
145 policy::key::kWallpaperImage,
146 this));
147 wallpaper_policy_observer_->Init();
148 }
149
~ChromeUserManagerImpl()150 ChromeUserManagerImpl::~ChromeUserManagerImpl() {
151 }
152
Shutdown()153 void ChromeUserManagerImpl::Shutdown() {
154 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
155 ChromeUserManager::Shutdown();
156
157 local_accounts_subscription_.reset();
158
159 // Stop the session length limiter.
160 session_length_limiter_.reset();
161
162 if (device_local_account_policy_service_)
163 device_local_account_policy_service_->RemoveObserver(this);
164
165 for (UserImageManagerMap::iterator it = user_image_managers_.begin(),
166 ie = user_image_managers_.end();
167 it != ie;
168 ++it) {
169 it->second->Shutdown();
170 }
171 multi_profile_user_controller_.reset();
172 avatar_policy_observer_.reset();
173 wallpaper_policy_observer_.reset();
174 registrar_.RemoveAll();
175 }
176
177 MultiProfileUserController*
GetMultiProfileUserController()178 ChromeUserManagerImpl::GetMultiProfileUserController() {
179 return multi_profile_user_controller_.get();
180 }
181
GetUserImageManager(const std::string & user_id)182 UserImageManager* ChromeUserManagerImpl::GetUserImageManager(
183 const std::string& user_id) {
184 UserImageManagerMap::iterator ui = user_image_managers_.find(user_id);
185 if (ui != user_image_managers_.end())
186 return ui->second.get();
187 linked_ptr<UserImageManagerImpl> mgr(new UserImageManagerImpl(user_id, this));
188 user_image_managers_[user_id] = mgr;
189 return mgr.get();
190 }
191
GetSupervisedUserManager()192 SupervisedUserManager* ChromeUserManagerImpl::GetSupervisedUserManager() {
193 return supervised_user_manager_.get();
194 }
195
GetUsersAdmittedForMultiProfile() const196 user_manager::UserList ChromeUserManagerImpl::GetUsersAdmittedForMultiProfile()
197 const {
198 // Supervised users are not allowed to use multi-profiles.
199 if (GetLoggedInUsers().size() == 1 &&
200 GetPrimaryUser()->GetType() != user_manager::USER_TYPE_REGULAR) {
201 return user_manager::UserList();
202 }
203
204 user_manager::UserList result;
205 const user_manager::UserList& users = GetUsers();
206 for (user_manager::UserList::const_iterator it = users.begin();
207 it != users.end();
208 ++it) {
209 if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR &&
210 !(*it)->is_logged_in()) {
211 MultiProfileUserController::UserAllowedInSessionReason check;
212 multi_profile_user_controller_->IsUserAllowedInSession((*it)->email(),
213 &check);
214 if (check ==
215 MultiProfileUserController::NOT_ALLOWED_PRIMARY_USER_POLICY_FORBIDS) {
216 return user_manager::UserList();
217 }
218
219 // Users with a policy that prevents them being added to a session will be
220 // shown in login UI but will be grayed out.
221 // Same applies to owner account (see http://crbug.com/385034).
222 result.push_back(*it);
223 }
224 }
225
226 return result;
227 }
228
GetUnlockUsers() const229 user_manager::UserList ChromeUserManagerImpl::GetUnlockUsers() const {
230 const user_manager::UserList& logged_in_users = GetLoggedInUsers();
231 if (logged_in_users.empty())
232 return user_manager::UserList();
233
234 user_manager::UserList unlock_users;
235 Profile* profile =
236 ProfileHelper::Get()->GetProfileByUserUnsafe(GetPrimaryUser());
237 std::string primary_behavior =
238 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
239
240 // Specific case: only one logged in user or
241 // primary user has primary-only multi-profile policy.
242 if (logged_in_users.size() == 1 ||
243 primary_behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
244 if (GetPrimaryUser()->can_lock())
245 unlock_users.push_back(primary_user_);
246 } else {
247 // Fill list of potential unlock users based on multi-profile policy state.
248 for (user_manager::UserList::const_iterator it = logged_in_users.begin();
249 it != logged_in_users.end();
250 ++it) {
251 user_manager::User* user = (*it);
252 Profile* profile = ProfileHelper::Get()->GetProfileByUserUnsafe(user);
253 const std::string behavior =
254 profile->GetPrefs()->GetString(prefs::kMultiProfileUserBehavior);
255 if (behavior == MultiProfileUserController::kBehaviorUnrestricted &&
256 user->can_lock()) {
257 unlock_users.push_back(user);
258 } else if (behavior == MultiProfileUserController::kBehaviorPrimaryOnly) {
259 NOTREACHED()
260 << "Spotted primary-only multi-profile policy for non-primary user";
261 }
262 }
263 }
264
265 return unlock_users;
266 }
267
SessionStarted()268 void ChromeUserManagerImpl::SessionStarted() {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
270 ChromeUserManager::SessionStarted();
271
272 content::NotificationService::current()->Notify(
273 chrome::NOTIFICATION_SESSION_STARTED,
274 content::Source<UserManager>(this),
275 content::Details<const user_manager::User>(GetActiveUser()));
276 }
277
RemoveUserInternal(const std::string & user_email,user_manager::RemoveUserDelegate * delegate)278 void ChromeUserManagerImpl::RemoveUserInternal(
279 const std::string& user_email,
280 user_manager::RemoveUserDelegate* delegate) {
281 CrosSettings* cros_settings = CrosSettings::Get();
282
283 const base::Closure& callback =
284 base::Bind(&ChromeUserManagerImpl::RemoveUserInternal,
285 weak_factory_.GetWeakPtr(),
286 user_email,
287 delegate);
288
289 // Ensure the value of owner email has been fetched.
290 if (CrosSettingsProvider::TRUSTED !=
291 cros_settings->PrepareTrustedValues(callback)) {
292 // Value of owner email is not fetched yet. RemoveUserInternal will be
293 // called again after fetch completion.
294 return;
295 }
296 std::string owner;
297 cros_settings->GetString(kDeviceOwner, &owner);
298 if (user_email == owner) {
299 // Owner is not allowed to be removed from the device.
300 return;
301 }
302 RemoveNonOwnerUserInternal(user_email, delegate);
303 }
304
SaveUserOAuthStatus(const std::string & user_id,user_manager::User::OAuthTokenStatus oauth_token_status)305 void ChromeUserManagerImpl::SaveUserOAuthStatus(
306 const std::string& user_id,
307 user_manager::User::OAuthTokenStatus oauth_token_status) {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
309 ChromeUserManager::SaveUserOAuthStatus(user_id, oauth_token_status);
310
311 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(oauth_token_status);
312 }
313
SaveUserDisplayName(const std::string & user_id,const base::string16 & display_name)314 void ChromeUserManagerImpl::SaveUserDisplayName(
315 const std::string& user_id,
316 const base::string16& display_name) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
318 ChromeUserManager::SaveUserDisplayName(user_id, display_name);
319
320 // Do not update local state if data stored or cached outside the user's
321 // cryptohome is to be treated as ephemeral.
322 if (!IsUserNonCryptohomeDataEphemeral(user_id))
323 supervised_user_manager_->UpdateManagerName(user_id, display_name);
324 }
325
StopPolicyObserverForTesting()326 void ChromeUserManagerImpl::StopPolicyObserverForTesting() {
327 avatar_policy_observer_.reset();
328 wallpaper_policy_observer_.reset();
329 }
330
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)331 void ChromeUserManagerImpl::Observe(
332 int type,
333 const content::NotificationSource& source,
334 const content::NotificationDetails& details) {
335 switch (type) {
336 case chrome::NOTIFICATION_OWNERSHIP_STATUS_CHANGED:
337 if (!device_local_account_policy_service_) {
338 policy::BrowserPolicyConnectorChromeOS* connector =
339 g_browser_process->platform_part()
340 ->browser_policy_connector_chromeos();
341 device_local_account_policy_service_ =
342 connector->GetDeviceLocalAccountPolicyService();
343 if (device_local_account_policy_service_)
344 device_local_account_policy_service_->AddObserver(this);
345 }
346 RetrieveTrustedDevicePolicies();
347 UpdateOwnership();
348 break;
349 case chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED: {
350 Profile* profile = content::Details<Profile>(details).ptr();
351 if (IsUserLoggedIn() && !IsLoggedInAsGuest() && !IsLoggedInAsKioskApp()) {
352 if (IsLoggedInAsSupervisedUser())
353 SupervisedUserPasswordServiceFactory::GetForProfile(profile);
354 if (IsLoggedInAsRegularUser())
355 ManagerPasswordServiceFactory::GetForProfile(profile);
356
357 if (!profile->IsOffTheRecord()) {
358 AuthSyncObserver* sync_observer =
359 AuthSyncObserverFactory::GetInstance()->GetForProfile(profile);
360 sync_observer->StartObserving();
361 multi_profile_user_controller_->StartObserving(profile);
362 }
363 }
364 break;
365 }
366 case chrome::NOTIFICATION_PROFILE_CREATED: {
367 Profile* profile = content::Source<Profile>(source).ptr();
368 user_manager::User* user =
369 ProfileHelper::Get()->GetUserByProfile(profile);
370 if (user != NULL)
371 user->set_profile_is_created();
372
373 // If there is pending user switch, do it now.
374 if (!GetPendingUserSwitchID().empty()) {
375 // Call SwitchActiveUser async because otherwise it may cause
376 // ProfileManager::GetProfile before the profile gets registered
377 // in ProfileManager. It happens in case of sync profile load when
378 // NOTIFICATION_PROFILE_CREATED is called synchronously.
379 base::MessageLoop::current()->PostTask(
380 FROM_HERE,
381 base::Bind(&ChromeUserManagerImpl::SwitchActiveUser,
382 weak_factory_.GetWeakPtr(),
383 GetPendingUserSwitchID()));
384 SetPendingUserSwitchID(std::string());
385 }
386 break;
387 }
388 default:
389 NOTREACHED();
390 }
391 }
392
OnExternalDataSet(const std::string & policy,const std::string & user_id)393 void ChromeUserManagerImpl::OnExternalDataSet(const std::string& policy,
394 const std::string& user_id) {
395 if (policy == policy::key::kUserAvatarImage)
396 GetUserImageManager(user_id)->OnExternalDataSet(policy);
397 else if (policy == policy::key::kWallpaperImage)
398 WallpaperManager::Get()->OnPolicySet(policy, user_id);
399 else
400 NOTREACHED();
401 }
402
OnExternalDataCleared(const std::string & policy,const std::string & user_id)403 void ChromeUserManagerImpl::OnExternalDataCleared(const std::string& policy,
404 const std::string& user_id) {
405 if (policy == policy::key::kUserAvatarImage)
406 GetUserImageManager(user_id)->OnExternalDataCleared(policy);
407 else if (policy == policy::key::kWallpaperImage)
408 WallpaperManager::Get()->OnPolicyCleared(policy, user_id);
409 else
410 NOTREACHED();
411 }
412
OnExternalDataFetched(const std::string & policy,const std::string & user_id,scoped_ptr<std::string> data)413 void ChromeUserManagerImpl::OnExternalDataFetched(
414 const std::string& policy,
415 const std::string& user_id,
416 scoped_ptr<std::string> data) {
417 if (policy == policy::key::kUserAvatarImage)
418 GetUserImageManager(user_id)->OnExternalDataFetched(policy, data.Pass());
419 else if (policy == policy::key::kWallpaperImage)
420 WallpaperManager::Get()->OnPolicyFetched(policy, user_id, data.Pass());
421 else
422 NOTREACHED();
423 }
424
OnPolicyUpdated(const std::string & user_id)425 void ChromeUserManagerImpl::OnPolicyUpdated(const std::string& user_id) {
426 const user_manager::User* user = FindUser(user_id);
427 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
428 return;
429 UpdatePublicAccountDisplayName(user_id);
430 }
431
OnDeviceLocalAccountsChanged()432 void ChromeUserManagerImpl::OnDeviceLocalAccountsChanged() {
433 // No action needed here, changes to the list of device-local accounts get
434 // handled via the kAccountsPrefDeviceLocalAccounts device setting observer.
435 }
436
CanCurrentUserLock() const437 bool ChromeUserManagerImpl::CanCurrentUserLock() const {
438 return ChromeUserManager::CanCurrentUserLock() &&
439 GetCurrentUserFlow()->CanLockScreen();
440 }
441
IsUserNonCryptohomeDataEphemeral(const std::string & user_id) const442 bool ChromeUserManagerImpl::IsUserNonCryptohomeDataEphemeral(
443 const std::string& user_id) const {
444 // Data belonging to the obsolete public accounts whose data has not been
445 // removed yet is not ephemeral.
446 bool is_obsolete_public_account = IsPublicAccountMarkedForRemoval(user_id);
447
448 return !is_obsolete_public_account &&
449 ChromeUserManager::IsUserNonCryptohomeDataEphemeral(user_id);
450 }
451
AreEphemeralUsersEnabled() const452 bool ChromeUserManagerImpl::AreEphemeralUsersEnabled() const {
453 policy::BrowserPolicyConnectorChromeOS* connector =
454 g_browser_process->platform_part()->browser_policy_connector_chromeos();
455 return GetEphemeralUsersEnabled() &&
456 (connector->IsEnterpriseManaged() || !GetOwnerEmail().empty());
457 }
458
GetApplicationLocale() const459 const std::string& ChromeUserManagerImpl::GetApplicationLocale() const {
460 return g_browser_process->GetApplicationLocale();
461 }
462
GetLocalState() const463 PrefService* ChromeUserManagerImpl::GetLocalState() const {
464 return g_browser_process ? g_browser_process->local_state() : NULL;
465 }
466
HandleUserOAuthTokenStatusChange(const std::string & user_id,user_manager::User::OAuthTokenStatus status) const467 void ChromeUserManagerImpl::HandleUserOAuthTokenStatusChange(
468 const std::string& user_id,
469 user_manager::User::OAuthTokenStatus status) const {
470 GetUserFlow(user_id)->HandleOAuthTokenStatusChange(status);
471 }
472
IsEnterpriseManaged() const473 bool ChromeUserManagerImpl::IsEnterpriseManaged() const {
474 policy::BrowserPolicyConnectorChromeOS* connector =
475 g_browser_process->platform_part()->browser_policy_connector_chromeos();
476 return connector->IsEnterpriseManaged();
477 }
478
LoadPublicAccounts(std::set<std::string> * public_sessions_set)479 void ChromeUserManagerImpl::LoadPublicAccounts(
480 std::set<std::string>* public_sessions_set) {
481 const base::ListValue* prefs_public_sessions =
482 GetLocalState()->GetList(kPublicAccounts);
483 std::vector<std::string> public_sessions;
484 ParseUserList(*prefs_public_sessions,
485 std::set<std::string>(),
486 &public_sessions,
487 public_sessions_set);
488 for (std::vector<std::string>::const_iterator it = public_sessions.begin();
489 it != public_sessions.end();
490 ++it) {
491 users_.push_back(user_manager::User::CreatePublicAccountUser(*it));
492 UpdatePublicAccountDisplayName(*it);
493 }
494 }
495
PerformPreUserListLoadingActions()496 void ChromeUserManagerImpl::PerformPreUserListLoadingActions() {
497 // Clean up user list first. All code down the path should be synchronous,
498 // so that local state after transaction rollback is in consistent state.
499 // This process also should not trigger EnsureUsersLoaded again.
500 if (supervised_user_manager_->HasFailedUserCreationTransaction())
501 supervised_user_manager_->RollbackUserCreationTransaction();
502 }
503
PerformPostUserListLoadingActions()504 void ChromeUserManagerImpl::PerformPostUserListLoadingActions() {
505 for (user_manager::UserList::iterator ui = users_.begin(), ue = users_.end();
506 ui != ue;
507 ++ui) {
508 GetUserImageManager((*ui)->email())->LoadUserImage();
509 }
510 }
511
PerformPostUserLoggedInActions(bool browser_restart)512 void ChromeUserManagerImpl::PerformPostUserLoggedInActions(
513 bool browser_restart) {
514 // Initialize the session length limiter and start it only if
515 // session limit is defined by the policy.
516 session_length_limiter_.reset(
517 new SessionLengthLimiter(NULL, browser_restart));
518 }
519
IsDemoApp(const std::string & user_id) const520 bool ChromeUserManagerImpl::IsDemoApp(const std::string& user_id) const {
521 return DemoAppLauncher::IsDemoAppSession(user_id);
522 }
523
IsKioskApp(const std::string & user_id) const524 bool ChromeUserManagerImpl::IsKioskApp(const std::string& user_id) const {
525 policy::DeviceLocalAccount::Type device_local_account_type;
526 return policy::IsDeviceLocalAccountUser(user_id,
527 &device_local_account_type) &&
528 device_local_account_type ==
529 policy::DeviceLocalAccount::TYPE_KIOSK_APP;
530 }
531
IsPublicAccountMarkedForRemoval(const std::string & user_id) const532 bool ChromeUserManagerImpl::IsPublicAccountMarkedForRemoval(
533 const std::string& user_id) const {
534 return user_id ==
535 GetLocalState()->GetString(kPublicAccountPendingDataRemoval);
536 }
537
RetrieveTrustedDevicePolicies()538 void ChromeUserManagerImpl::RetrieveTrustedDevicePolicies() {
539 // Local state may not be initialized in unit_tests.
540 if (!GetLocalState())
541 return;
542
543 SetEphemeralUsersEnabled(false);
544 SetOwnerEmail(std::string());
545
546 // Schedule a callback if device policy has not yet been verified.
547 if (CrosSettingsProvider::TRUSTED !=
548 cros_settings_->PrepareTrustedValues(
549 base::Bind(&ChromeUserManagerImpl::RetrieveTrustedDevicePolicies,
550 weak_factory_.GetWeakPtr()))) {
551 return;
552 }
553
554 bool ephemeral_users_enabled = false;
555 cros_settings_->GetBoolean(kAccountsPrefEphemeralUsersEnabled,
556 &ephemeral_users_enabled);
557 SetEphemeralUsersEnabled(ephemeral_users_enabled);
558
559 std::string owner_email;
560 cros_settings_->GetString(kDeviceOwner, &owner_email);
561 SetOwnerEmail(owner_email);
562
563 EnsureUsersLoaded();
564
565 bool changed = UpdateAndCleanUpPublicAccounts(
566 policy::GetDeviceLocalAccounts(cros_settings_));
567
568 // If ephemeral users are enabled and we are on the login screen, take this
569 // opportunity to clean up by removing all regular users except the owner.
570 if (GetEphemeralUsersEnabled() && !IsUserLoggedIn()) {
571 ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
572 prefs_users_update->Clear();
573 for (user_manager::UserList::iterator it = users_.begin();
574 it != users_.end();) {
575 const std::string user_email = (*it)->email();
576 if ((*it)->GetType() == user_manager::USER_TYPE_REGULAR &&
577 user_email != GetOwnerEmail()) {
578 RemoveNonCryptohomeData(user_email);
579 DeleteUser(*it);
580 it = users_.erase(it);
581 changed = true;
582 } else {
583 if ((*it)->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
584 prefs_users_update->Append(new base::StringValue(user_email));
585 ++it;
586 }
587 }
588 }
589
590 if (changed)
591 NotifyUserListChanged();
592 }
593
GuestUserLoggedIn()594 void ChromeUserManagerImpl::GuestUserLoggedIn() {
595 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
596 ChromeUserManager::GuestUserLoggedIn();
597
598 // TODO(nkostylev): Add support for passing guest session cryptohome
599 // mount point. Legacy (--login-profile) value will be used for now.
600 // http://crosbug.com/230859
601 active_user_->SetStubImage(
602 user_manager::UserImage(
603 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
604 IDR_PROFILE_PICTURE_LOADING)),
605 user_manager::User::USER_IMAGE_INVALID,
606 false);
607
608 // Initializes wallpaper after active_user_ is set.
609 WallpaperManager::Get()->SetUserWallpaperNow(chromeos::login::kGuestUserName);
610 }
611
RegularUserLoggedIn(const std::string & user_id)612 void ChromeUserManagerImpl::RegularUserLoggedIn(const std::string& user_id) {
613 ChromeUserManager::RegularUserLoggedIn(user_id);
614
615 if (IsCurrentUserNew())
616 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
617
618 GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
619
620 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
621
622 // Make sure that new data is persisted to Local State.
623 GetLocalState()->CommitPendingWrite();
624 }
625
RegularUserLoggedInAsEphemeral(const std::string & user_id)626 void ChromeUserManagerImpl::RegularUserLoggedInAsEphemeral(
627 const std::string& user_id) {
628 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
629 ChromeUserManager::RegularUserLoggedInAsEphemeral(user_id);
630
631 GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), false);
632 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
633 }
634
SupervisedUserLoggedIn(const std::string & user_id)635 void ChromeUserManagerImpl::SupervisedUserLoggedIn(const std::string& user_id) {
636 // TODO(nkostylev): Refactor, share code with RegularUserLoggedIn().
637
638 // Remove the user from the user list.
639 active_user_ = RemoveRegularOrSupervisedUserFromList(user_id);
640
641 // If the user was not found on the user list, create a new user.
642 if (!GetActiveUser()) {
643 SetIsCurrentUserNew(true);
644 active_user_ = user_manager::User::CreateSupervisedUser(user_id);
645 // Leaving OAuth token status at the default state = unknown.
646 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
647 } else {
648 if (supervised_user_manager_->CheckForFirstRun(user_id)) {
649 SetIsCurrentUserNew(true);
650 WallpaperManager::Get()->SetUserWallpaperNow(user_id);
651 } else {
652 SetIsCurrentUserNew(false);
653 }
654 }
655
656 // Add the user to the front of the user list.
657 ListPrefUpdate prefs_users_update(GetLocalState(), kRegularUsers);
658 prefs_users_update->Insert(0, new base::StringValue(user_id));
659 users_.insert(users_.begin(), active_user_);
660
661 // Now that user is in the list, save display name.
662 if (IsCurrentUserNew()) {
663 SaveUserDisplayName(GetActiveUser()->email(),
664 GetActiveUser()->GetDisplayName());
665 }
666
667 GetUserImageManager(user_id)->UserLoggedIn(IsCurrentUserNew(), true);
668 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
669
670 // Make sure that new data is persisted to Local State.
671 GetLocalState()->CommitPendingWrite();
672 }
673
PublicAccountUserLoggedIn(user_manager::User * user)674 void ChromeUserManagerImpl::PublicAccountUserLoggedIn(
675 user_manager::User* user) {
676 SetIsCurrentUserNew(true);
677 active_user_ = user;
678
679 // The UserImageManager chooses a random avatar picture when a user logs in
680 // for the first time. Tell the UserImageManager that this user is not new to
681 // prevent the avatar from getting changed.
682 GetUserImageManager(user->email())->UserLoggedIn(false, true);
683 WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
684 }
685
KioskAppLoggedIn(const std::string & app_id)686 void ChromeUserManagerImpl::KioskAppLoggedIn(const std::string& app_id) {
687 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
688 policy::DeviceLocalAccount::Type device_local_account_type;
689 DCHECK(policy::IsDeviceLocalAccountUser(app_id, &device_local_account_type));
690 DCHECK_EQ(policy::DeviceLocalAccount::TYPE_KIOSK_APP,
691 device_local_account_type);
692
693 active_user_ = user_manager::User::CreateKioskAppUser(app_id);
694 active_user_->SetStubImage(
695 user_manager::UserImage(
696 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
697 IDR_PROFILE_PICTURE_LOADING)),
698 user_manager::User::USER_IMAGE_INVALID,
699 false);
700
701 WallpaperManager::Get()->SetUserWallpaperNow(app_id);
702
703 // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
704 // the kiosk_app_id in these objects, removing the need to re-parse the
705 // device-local account list here to extract the kiosk_app_id.
706 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
707 policy::GetDeviceLocalAccounts(cros_settings_);
708 const policy::DeviceLocalAccount* account = NULL;
709 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
710 device_local_accounts.begin();
711 it != device_local_accounts.end();
712 ++it) {
713 if (it->user_id == app_id) {
714 account = &*it;
715 break;
716 }
717 }
718 std::string kiosk_app_id;
719 if (account) {
720 kiosk_app_id = account->kiosk_app_id;
721 } else {
722 LOG(ERROR) << "Logged into nonexistent kiosk-app account: " << app_id;
723 NOTREACHED();
724 }
725
726 CommandLine* command_line = CommandLine::ForCurrentProcess();
727 command_line->AppendSwitch(::switches::kForceAppMode);
728 command_line->AppendSwitchASCII(::switches::kAppId, kiosk_app_id);
729
730 // Disable window animation since kiosk app runs in a single full screen
731 // window and window animation causes start-up janks.
732 command_line->AppendSwitch(wm::switches::kWindowAnimationsDisabled);
733 }
734
DemoAccountLoggedIn()735 void ChromeUserManagerImpl::DemoAccountLoggedIn() {
736 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
737 active_user_ =
738 user_manager::User::CreateKioskAppUser(DemoAppLauncher::kDemoUserName);
739 active_user_->SetStubImage(
740 user_manager::UserImage(
741 *ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
742 IDR_PROFILE_PICTURE_LOADING)),
743 user_manager::User::USER_IMAGE_INVALID,
744 false);
745 WallpaperManager::Get()->SetUserWallpaperNow(DemoAppLauncher::kDemoUserName);
746
747 CommandLine* command_line = CommandLine::ForCurrentProcess();
748 command_line->AppendSwitch(::switches::kForceAppMode);
749 command_line->AppendSwitchASCII(::switches::kAppId,
750 DemoAppLauncher::kDemoAppId);
751
752 // Disable window animation since the demo app runs in a single full screen
753 // window and window animation causes start-up janks.
754 CommandLine::ForCurrentProcess()->AppendSwitch(
755 wm::switches::kWindowAnimationsDisabled);
756 }
757
RetailModeUserLoggedIn()758 void ChromeUserManagerImpl::RetailModeUserLoggedIn() {
759 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
760 SetIsCurrentUserNew(true);
761 active_user_ = user_manager::User::CreateRetailModeUser();
762 GetUserImageManager(chromeos::login::kRetailModeUserName)
763 ->UserLoggedIn(IsCurrentUserNew(), true);
764 WallpaperManager::Get()->SetUserWallpaperNow(
765 chromeos::login::kRetailModeUserName);
766 }
767
NotifyOnLogin()768 void ChromeUserManagerImpl::NotifyOnLogin() {
769 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
770
771 UserSessionManager::OverrideHomedir();
772 UpdateNumberOfUsers();
773
774 ChromeUserManager::NotifyOnLogin();
775
776 // TODO(nkostylev): Deprecate this notification in favor of
777 // ActiveUserChanged() observer call.
778 content::NotificationService::current()->Notify(
779 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
780 content::Source<UserManager>(this),
781 content::Details<const user_manager::User>(GetActiveUser()));
782
783 UserSessionManager::GetInstance()->PerformPostUserLoggedInActions();
784 }
785
UpdateOwnership()786 void ChromeUserManagerImpl::UpdateOwnership() {
787 bool is_owner = DeviceSettingsService::Get()->HasPrivateOwnerKey();
788 VLOG(1) << "Current user " << (is_owner ? "is owner" : "is not owner");
789
790 SetCurrentUserIsOwner(is_owner);
791 }
792
RemoveNonCryptohomeData(const std::string & user_id)793 void ChromeUserManagerImpl::RemoveNonCryptohomeData(
794 const std::string& user_id) {
795 ChromeUserManager::RemoveNonCryptohomeData(user_id);
796
797 WallpaperManager::Get()->RemoveUserWallpaperInfo(user_id);
798 GetUserImageManager(user_id)->DeleteUserImage();
799
800 supervised_user_manager_->RemoveNonCryptohomeData(user_id);
801
802 multi_profile_user_controller_->RemoveCachedValues(user_id);
803
804 EasyUnlockService::ResetLocalStateForUser(user_id);
805 }
806
807 void
CleanUpPublicAccountNonCryptohomeDataPendingRemoval()808 ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeDataPendingRemoval() {
809 PrefService* local_state = GetLocalState();
810 const std::string public_account_pending_data_removal =
811 local_state->GetString(kPublicAccountPendingDataRemoval);
812 if (public_account_pending_data_removal.empty() ||
813 (IsUserLoggedIn() &&
814 public_account_pending_data_removal == GetActiveUser()->email())) {
815 return;
816 }
817
818 RemoveNonCryptohomeData(public_account_pending_data_removal);
819 local_state->ClearPref(kPublicAccountPendingDataRemoval);
820 }
821
CleanUpPublicAccountNonCryptohomeData(const std::vector<std::string> & old_public_accounts)822 void ChromeUserManagerImpl::CleanUpPublicAccountNonCryptohomeData(
823 const std::vector<std::string>& old_public_accounts) {
824 std::set<std::string> users;
825 for (user_manager::UserList::const_iterator it = users_.begin();
826 it != users_.end();
827 ++it)
828 users.insert((*it)->email());
829
830 // If the user is logged into a public account that has been removed from the
831 // user list, mark the account's data as pending removal after logout.
832 if (IsLoggedInAsPublicAccount()) {
833 const std::string active_user_id = GetActiveUser()->email();
834 if (users.find(active_user_id) == users.end()) {
835 GetLocalState()->SetString(kPublicAccountPendingDataRemoval,
836 active_user_id);
837 users.insert(active_user_id);
838 }
839 }
840
841 // Remove the data belonging to any other public accounts that are no longer
842 // found on the user list.
843 for (std::vector<std::string>::const_iterator it =
844 old_public_accounts.begin();
845 it != old_public_accounts.end();
846 ++it) {
847 if (users.find(*it) == users.end())
848 RemoveNonCryptohomeData(*it);
849 }
850 }
851
UpdateAndCleanUpPublicAccounts(const std::vector<policy::DeviceLocalAccount> & device_local_accounts)852 bool ChromeUserManagerImpl::UpdateAndCleanUpPublicAccounts(
853 const std::vector<policy::DeviceLocalAccount>& device_local_accounts) {
854 // Try to remove any public account data marked as pending removal.
855 CleanUpPublicAccountNonCryptohomeDataPendingRemoval();
856
857 // Get the current list of public accounts.
858 std::vector<std::string> old_public_accounts;
859 for (user_manager::UserList::const_iterator it = users_.begin();
860 it != users_.end();
861 ++it) {
862 if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT)
863 old_public_accounts.push_back((*it)->email());
864 }
865
866 // Get the new list of public accounts from policy.
867 std::vector<std::string> new_public_accounts;
868 for (std::vector<policy::DeviceLocalAccount>::const_iterator it =
869 device_local_accounts.begin();
870 it != device_local_accounts.end();
871 ++it) {
872 // TODO(mnissler, nkostylev, bartfab): Process Kiosk Apps within the
873 // standard login framework: http://crbug.com/234694
874 if (it->type == policy::DeviceLocalAccount::TYPE_PUBLIC_SESSION)
875 new_public_accounts.push_back(it->user_id);
876 }
877
878 // If the list of public accounts has not changed, return.
879 if (new_public_accounts.size() == old_public_accounts.size()) {
880 bool changed = false;
881 for (size_t i = 0; i < new_public_accounts.size(); ++i) {
882 if (new_public_accounts[i] != old_public_accounts[i]) {
883 changed = true;
884 break;
885 }
886 }
887 if (!changed)
888 return false;
889 }
890
891 // Persist the new list of public accounts in a pref.
892 ListPrefUpdate prefs_public_accounts_update(GetLocalState(), kPublicAccounts);
893 prefs_public_accounts_update->Clear();
894 for (std::vector<std::string>::const_iterator it =
895 new_public_accounts.begin();
896 it != new_public_accounts.end();
897 ++it) {
898 prefs_public_accounts_update->AppendString(*it);
899 }
900
901 // Remove the old public accounts from the user list.
902 for (user_manager::UserList::iterator it = users_.begin();
903 it != users_.end();) {
904 if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
905 if (*it != GetLoggedInUser())
906 DeleteUser(*it);
907 it = users_.erase(it);
908 } else {
909 ++it;
910 }
911 }
912
913 // Add the new public accounts to the front of the user list.
914 for (std::vector<std::string>::const_reverse_iterator it =
915 new_public_accounts.rbegin();
916 it != new_public_accounts.rend();
917 ++it) {
918 if (IsLoggedInAsPublicAccount() && *it == GetActiveUser()->email())
919 users_.insert(users_.begin(), GetLoggedInUser());
920 else
921 users_.insert(users_.begin(),
922 user_manager::User::CreatePublicAccountUser(*it));
923 UpdatePublicAccountDisplayName(*it);
924 }
925
926 for (user_manager::UserList::iterator
927 ui = users_.begin(),
928 ue = users_.begin() + new_public_accounts.size();
929 ui != ue;
930 ++ui) {
931 GetUserImageManager((*ui)->email())->LoadUserImage();
932 }
933
934 // Remove data belonging to public accounts that are no longer found on the
935 // user list.
936 CleanUpPublicAccountNonCryptohomeData(old_public_accounts);
937
938 return true;
939 }
940
UpdatePublicAccountDisplayName(const std::string & user_id)941 void ChromeUserManagerImpl::UpdatePublicAccountDisplayName(
942 const std::string& user_id) {
943 std::string display_name;
944
945 if (device_local_account_policy_service_) {
946 policy::DeviceLocalAccountPolicyBroker* broker =
947 device_local_account_policy_service_->GetBrokerForUser(user_id);
948 if (broker)
949 display_name = broker->GetDisplayName();
950 }
951
952 // Set or clear the display name.
953 SaveUserDisplayName(user_id, base::UTF8ToUTF16(display_name));
954 }
955
GetCurrentUserFlow() const956 UserFlow* ChromeUserManagerImpl::GetCurrentUserFlow() const {
957 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
958 if (!IsUserLoggedIn())
959 return GetDefaultUserFlow();
960 return GetUserFlow(GetLoggedInUser()->email());
961 }
962
GetUserFlow(const std::string & user_id) const963 UserFlow* ChromeUserManagerImpl::GetUserFlow(const std::string& user_id) const {
964 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
965 FlowMap::const_iterator it = specific_flows_.find(user_id);
966 if (it != specific_flows_.end())
967 return it->second;
968 return GetDefaultUserFlow();
969 }
970
SetUserFlow(const std::string & user_id,UserFlow * flow)971 void ChromeUserManagerImpl::SetUserFlow(const std::string& user_id,
972 UserFlow* flow) {
973 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
974 ResetUserFlow(user_id);
975 specific_flows_[user_id] = flow;
976 }
977
ResetUserFlow(const std::string & user_id)978 void ChromeUserManagerImpl::ResetUserFlow(const std::string& user_id) {
979 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
980 FlowMap::iterator it = specific_flows_.find(user_id);
981 if (it != specific_flows_.end()) {
982 delete it->second;
983 specific_flows_.erase(it);
984 }
985 }
986
AreSupervisedUsersAllowed() const987 bool ChromeUserManagerImpl::AreSupervisedUsersAllowed() const {
988 bool supervised_users_allowed = false;
989 cros_settings_->GetBoolean(kAccountsPrefSupervisedUsersEnabled,
990 &supervised_users_allowed);
991 return supervised_users_allowed;
992 }
993
GetDefaultUserFlow() const994 UserFlow* ChromeUserManagerImpl::GetDefaultUserFlow() const {
995 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
996 if (!default_flow_.get())
997 default_flow_.reset(new DefaultUserFlow());
998 return default_flow_.get();
999 }
1000
NotifyUserListChanged()1001 void ChromeUserManagerImpl::NotifyUserListChanged() {
1002 content::NotificationService::current()->Notify(
1003 chrome::NOTIFICATION_USER_LIST_CHANGED,
1004 content::Source<UserManager>(this),
1005 content::NotificationService::NoDetails());
1006 }
1007
NotifyUserAddedToSession(const user_manager::User * added_user,bool user_switch_pending)1008 void ChromeUserManagerImpl::NotifyUserAddedToSession(
1009 const user_manager::User* added_user,
1010 bool user_switch_pending) {
1011 // Special case for user session restoration after browser crash.
1012 // We don't switch to each user session that has been restored as once all
1013 // session will be restored we'll switch to the session that has been used
1014 // before the crash.
1015 if (user_switch_pending &&
1016 !UserSessionManager::GetInstance()->UserSessionsRestoreInProgress()) {
1017 SetPendingUserSwitchID(added_user->email());
1018 }
1019
1020 UpdateNumberOfUsers();
1021 ChromeUserManager::NotifyUserAddedToSession(added_user, user_switch_pending);
1022 }
1023
OnUserNotAllowed(const std::string & user_email)1024 void ChromeUserManagerImpl::OnUserNotAllowed(const std::string& user_email) {
1025 LOG(ERROR) << "Shutdown session because a user is not allowed to be in the "
1026 "current session";
1027 chromeos::ShowMultiprofilesSessionAbortedDialog(user_email);
1028 }
1029
UpdateNumberOfUsers()1030 void ChromeUserManagerImpl::UpdateNumberOfUsers() {
1031 size_t users = GetLoggedInUsers().size();
1032 if (users) {
1033 // Write the user number as UMA stat when a multi user session is possible.
1034 if ((users + GetUsersAdmittedForMultiProfile().size()) > 1)
1035 ash::MultiProfileUMA::RecordUserCount(users);
1036 }
1037
1038 base::debug::SetCrashKeyValue(
1039 crash_keys::kNumberOfUsers,
1040 base::StringPrintf("%" PRIuS, GetLoggedInUsers().size()));
1041 }
1042
1043 } // namespace chromeos
1044