• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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