Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / existing_user_controller.cc
blobe79392aed4b556b4ead32e80008b60d5f87d2f47
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/login/existing_user_controller.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/bind_helpers.h"
11 #include "base/callback.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/histogram.h"
17 #include "base/prefs/pref_service.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/values.h"
21 #include "base/version.h"
22 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/browser_process_platform_part.h"
24 #include "chrome/browser/chrome_notification_types.h"
25 #include "chrome/browser/chromeos/boot_times_recorder.h"
26 #include "chrome/browser/chromeos/customization/customization_document.h"
27 #include "chrome/browser/chromeos/login/auth/chrome_login_performer.h"
28 #include "chrome/browser/chromeos/login/easy_unlock/bootstrap_user_context_initializer.h"
29 #include "chrome/browser/chromeos/login/easy_unlock/bootstrap_user_flow.h"
30 #include "chrome/browser/chromeos/login/helper.h"
31 #include "chrome/browser/chromeos/login/reauth_stats.h"
32 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
33 #include "chrome/browser/chromeos/login/signin/oauth2_token_initializer.h"
34 #include "chrome/browser/chromeos/login/signin_specifics.h"
35 #include "chrome/browser/chromeos/login/startup_utils.h"
36 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
37 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
38 #include "chrome/browser/chromeos/login/user_flow.h"
39 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
40 #include "chrome/browser/chromeos/login/wizard_controller.h"
41 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
42 #include "chrome/browser/chromeos/policy/device_local_account.h"
43 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
44 #include "chrome/browser/chromeos/profiles/profile_helper.h"
45 #include "chrome/browser/chromeos/settings/cros_settings.h"
46 #include "chrome/browser/chromeos/system/device_disabling_manager.h"
47 #include "chrome/browser/signin/easy_unlock_service.h"
48 #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h"
49 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
50 #include "chrome/common/chrome_switches.h"
51 #include "chrome/common/chrome_version_info.h"
52 #include "chrome/common/url_constants.h"
53 #include "chrome/grit/generated_resources.h"
54 #include "chromeos/chromeos_switches.h"
55 #include "chromeos/dbus/dbus_thread_manager.h"
56 #include "chromeos/dbus/power_manager_client.h"
57 #include "chromeos/dbus/session_manager_client.h"
58 #include "chromeos/login/user_names.h"
59 #include "chromeos/settings/cros_settings_names.h"
60 #include "components/google/core/browser/google_util.h"
61 #include "components/policy/core/common/cloud/cloud_policy_core.h"
62 #include "components/policy/core/common/cloud/cloud_policy_store.h"
63 #include "components/policy/core/common/policy_map.h"
64 #include "components/policy/core/common/policy_service.h"
65 #include "components/policy/core/common/policy_types.h"
66 #include "components/signin/core/browser/signin_client.h"
67 #include "components/user_manager/user_manager.h"
68 #include "components/user_manager/user_type.h"
69 #include "content/public/browser/browser_thread.h"
70 #include "content/public/browser/notification_service.h"
71 #include "content/public/browser/notification_types.h"
72 #include "content/public/browser/user_metrics.h"
73 #include "google_apis/gaia/gaia_auth_util.h"
74 #include "google_apis/gaia/google_service_auth_error.h"
75 #include "net/http/http_auth_cache.h"
76 #include "net/http/http_network_session.h"
77 #include "net/http/http_transaction_factory.h"
78 #include "net/url_request/url_request_context.h"
79 #include "net/url_request/url_request_context_getter.h"
80 #include "policy/policy_constants.h"
81 #include "ui/accessibility/ax_enums.h"
82 #include "ui/base/l10n/l10n_util.h"
83 #include "ui/views/widget/widget.h"
85 namespace chromeos {
87 namespace {
89 // URL for account creation.
90 const char kCreateAccountURL[] =
91 "https://accounts.google.com/NewAccount?service=mail";
93 // Delay for transferring the auth cache to the system profile.
94 const long int kAuthCacheTransferDelayMs = 2000;
96 // Delay for restarting the ui if safe-mode login has failed.
97 const long int kSafeModeRestartUiDelayMs = 30000;
99 // Makes a call to the policy subsystem to reload the policy when we detect
100 // authentication change.
101 void RefreshPoliciesOnUIThread() {
102 if (g_browser_process->policy_service())
103 g_browser_process->policy_service()->RefreshPolicies(base::Closure());
106 // Copies any authentication details that were entered in the login profile in
107 // the mail profile to make sure all subsystems of Chrome can access the network
108 // with the provided authentication which are possibly for a proxy server.
109 void TransferContextAuthenticationsOnIOThread(
110 net::URLRequestContextGetter* default_profile_context_getter,
111 net::URLRequestContextGetter* browser_process_context_getter) {
112 net::HttpAuthCache* new_cache =
113 browser_process_context_getter->GetURLRequestContext()->
114 http_transaction_factory()->GetSession()->http_auth_cache();
115 net::HttpAuthCache* old_cache =
116 default_profile_context_getter->GetURLRequestContext()->
117 http_transaction_factory()->GetSession()->http_auth_cache();
118 new_cache->UpdateAllFrom(*old_cache);
119 VLOG(1) << "Main request context populated with authentication data.";
120 // Last but not least tell the policy subsystem to refresh now as it might
121 // have been stuck until now too.
122 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
123 base::Bind(&RefreshPoliciesOnUIThread));
126 // Record UMA for password login of regular user when Easy sign-in is enabled.
127 void RecordPasswordLoginEvent(const UserContext& user_context) {
128 EasyUnlockService* easy_unlock_service =
129 EasyUnlockService::Get(ProfileHelper::GetSigninProfile());
130 if (user_context.GetUserType() == user_manager::USER_TYPE_REGULAR &&
131 user_context.GetAuthFlow() == UserContext::AUTH_FLOW_OFFLINE &&
132 easy_unlock_service) {
133 easy_unlock_service->RecordPasswordLoginEvent(user_context.GetUserID());
137 bool CanShowDebuggingFeatures() {
138 // We need to be on the login screen and in dev mode to show this menu item.
139 return base::CommandLine::ForCurrentProcess()->HasSwitch(
140 chromeos::switches::kSystemDevMode) &&
141 base::CommandLine::ForCurrentProcess()->HasSwitch(
142 chromeos::switches::kLoginManager) &&
143 !user_manager::UserManager::Get()->IsSessionStarted();
146 } // namespace
148 // static
149 ExistingUserController* ExistingUserController::current_controller_ = NULL;
151 ////////////////////////////////////////////////////////////////////////////////
152 // ExistingUserController, public:
154 ExistingUserController::ExistingUserController(LoginDisplayHost* host)
155 : auth_status_consumer_(NULL),
156 host_(host),
157 login_display_(host_->CreateLoginDisplay(this)),
158 num_login_attempts_(0),
159 cros_settings_(CrosSettings::Get()),
160 offline_failed_(false),
161 is_login_in_progress_(false),
162 password_changed_(false),
163 auth_mode_(LoginPerformer::AUTH_MODE_EXTENSION),
164 signin_screen_ready_(false),
165 network_state_helper_(new login::NetworkStateHelper),
166 weak_factory_(this) {
167 DCHECK(current_controller_ == NULL);
168 current_controller_ = this;
170 registrar_.Add(this,
171 chrome::NOTIFICATION_USER_LIST_CHANGED,
172 content::NotificationService::AllSources());
173 registrar_.Add(this,
174 chrome::NOTIFICATION_AUTH_SUPPLIED,
175 content::NotificationService::AllSources());
176 registrar_.Add(this,
177 chrome::NOTIFICATION_SESSION_STARTED,
178 content::NotificationService::AllSources());
179 show_user_names_subscription_ = cros_settings_->AddSettingsObserver(
180 kAccountsPrefShowUserNamesOnSignIn,
181 base::Bind(&ExistingUserController::DeviceSettingsChanged,
182 base::Unretained(this)));
183 allow_new_user_subscription_ = cros_settings_->AddSettingsObserver(
184 kAccountsPrefAllowNewUser,
185 base::Bind(&ExistingUserController::DeviceSettingsChanged,
186 base::Unretained(this)));
187 allow_guest_subscription_ = cros_settings_->AddSettingsObserver(
188 kAccountsPrefAllowGuest,
189 base::Bind(&ExistingUserController::DeviceSettingsChanged,
190 base::Unretained(this)));
191 allow_supervised_user_subscription_ = cros_settings_->AddSettingsObserver(
192 kAccountsPrefSupervisedUsersEnabled,
193 base::Bind(&ExistingUserController::DeviceSettingsChanged,
194 base::Unretained(this)));
195 users_subscription_ = cros_settings_->AddSettingsObserver(
196 kAccountsPrefUsers,
197 base::Bind(&ExistingUserController::DeviceSettingsChanged,
198 base::Unretained(this)));
199 local_account_auto_login_id_subscription_ =
200 cros_settings_->AddSettingsObserver(
201 kAccountsPrefDeviceLocalAccountAutoLoginId,
202 base::Bind(&ExistingUserController::ConfigurePublicSessionAutoLogin,
203 base::Unretained(this)));
204 local_account_auto_login_delay_subscription_ =
205 cros_settings_->AddSettingsObserver(
206 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
207 base::Bind(&ExistingUserController::ConfigurePublicSessionAutoLogin,
208 base::Unretained(this)));
211 void ExistingUserController::Init(const user_manager::UserList& users) {
212 time_init_ = base::Time::Now();
213 UpdateLoginDisplay(users);
214 ConfigurePublicSessionAutoLogin();
217 void ExistingUserController::UpdateLoginDisplay(
218 const user_manager::UserList& users) {
219 bool show_users_on_signin;
220 user_manager::UserList filtered_users;
222 cros_settings_->GetBoolean(kAccountsPrefShowUserNamesOnSignIn,
223 &show_users_on_signin);
224 for (user_manager::UserList::const_iterator it = users.begin();
225 it != users.end();
226 ++it) {
227 // TODO(xiyuan): Clean user profile whose email is not in whitelist.
228 bool meets_supervised_requirements =
229 (*it)->GetType() != user_manager::USER_TYPE_SUPERVISED ||
230 user_manager::UserManager::Get()->AreSupervisedUsersAllowed();
231 bool meets_whitelist_requirements =
232 CrosSettings::IsWhitelisted((*it)->email(), NULL) ||
233 !(*it)->HasGaiaAccount();
235 // Public session accounts are always shown on login screen.
236 bool meets_show_users_requirements =
237 show_users_on_signin ||
238 (*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT;
239 if (meets_supervised_requirements &&
240 meets_whitelist_requirements &&
241 meets_show_users_requirements) {
242 filtered_users.push_back(*it);
246 // If no user pods are visible, fallback to single new user pod which will
247 // have guest session link.
248 bool show_guest;
249 cros_settings_->GetBoolean(kAccountsPrefAllowGuest, &show_guest);
250 show_users_on_signin |= !filtered_users.empty();
251 show_guest &= !filtered_users.empty();
252 bool show_new_user = true;
253 login_display_->set_parent_window(GetNativeWindow());
254 login_display_->Init(
255 filtered_users, show_guest, show_users_on_signin, show_new_user);
256 host_->OnPreferencesChanged();
259 ////////////////////////////////////////////////////////////////////////////////
260 // ExistingUserController, content::NotificationObserver implementation:
263 void ExistingUserController::Observe(
264 int type,
265 const content::NotificationSource& source,
266 const content::NotificationDetails& details) {
267 if (type == chrome::NOTIFICATION_SESSION_STARTED) {
268 // Stop listening to any notification once session has started.
269 // Sign in screen objects are marked for deletion with DeleteSoon so
270 // make sure no object would be used after session has started.
271 // http://crbug.com/125276
272 registrar_.RemoveAll();
273 return;
275 if (type == chrome::NOTIFICATION_USER_LIST_CHANGED) {
276 DeviceSettingsChanged();
277 return;
279 if (type == chrome::NOTIFICATION_AUTH_SUPPLIED) {
280 // Possibly the user has authenticated against a proxy server and we might
281 // need the credentials for enrollment and other system requests from the
282 // main |g_browser_process| request context (see bug
283 // http://crosbug.com/24861). So we transfer any credentials to the global
284 // request context here.
285 // The issue we have here is that the NOTIFICATION_AUTH_SUPPLIED is sent
286 // just after the UI is closed but before the new credentials were stored
287 // in the profile. Therefore we have to give it some time to make sure it
288 // has been updated before we copy it.
289 VLOG(1) << "Authentication was entered manually, possibly for proxyauth.";
290 scoped_refptr<net::URLRequestContextGetter> browser_process_context_getter =
291 g_browser_process->system_request_context();
292 Profile* signin_profile = ProfileHelper::GetSigninProfile();
293 scoped_refptr<net::URLRequestContextGetter> signin_profile_context_getter =
294 signin_profile->GetRequestContext();
295 DCHECK(browser_process_context_getter.get());
296 DCHECK(signin_profile_context_getter.get());
297 content::BrowserThread::PostDelayedTask(
298 content::BrowserThread::IO, FROM_HERE,
299 base::Bind(&TransferContextAuthenticationsOnIOThread,
300 signin_profile_context_getter,
301 browser_process_context_getter),
302 base::TimeDelta::FromMilliseconds(kAuthCacheTransferDelayMs));
306 ////////////////////////////////////////////////////////////////////////////////
307 // ExistingUserController, private:
309 ExistingUserController::~ExistingUserController() {
310 UserSessionManager::GetInstance()->DelegateDeleted(this);
312 if (current_controller_ == this) {
313 current_controller_ = NULL;
314 } else {
315 NOTREACHED() << "More than one controller are alive.";
317 DCHECK(login_display_.get());
320 ////////////////////////////////////////////////////////////////////////////////
321 // ExistingUserController, LoginDisplay::Delegate implementation:
324 void ExistingUserController::CancelPasswordChangedFlow() {
325 login_performer_.reset(NULL);
326 PerformLoginFinishedActions(true /* start public session timer */);
329 void ExistingUserController::CreateAccount() {
330 content::RecordAction(base::UserMetricsAction("Login.CreateAccount"));
331 guest_mode_url_ = google_util::AppendGoogleLocaleParam(
332 GURL(kCreateAccountURL), g_browser_process->GetApplicationLocale());
333 Login(UserContext(user_manager::USER_TYPE_GUEST, std::string()),
334 SigninSpecifics());
337 void ExistingUserController::CompleteLogin(const UserContext& user_context) {
338 login_display_->set_signin_completed(true);
339 if (!host_) {
340 // Complete login event was generated already from UI. Ignore notification.
341 return;
344 ContinueLoginIfDeviceNotDisabled(base::Bind(
345 &ExistingUserController::DoCompleteLogin,
346 weak_factory_.GetWeakPtr(),
347 user_context));
350 base::string16 ExistingUserController::GetConnectedNetworkName() {
351 return network_state_helper_->GetCurrentNetworkName();
354 bool ExistingUserController::IsSigninInProgress() const {
355 return is_login_in_progress_;
358 void ExistingUserController::Login(const UserContext& user_context,
359 const SigninSpecifics& specifics) {
360 ContinueLoginIfDeviceNotDisabled(base::Bind(
361 &ExistingUserController::DoLogin,
362 weak_factory_.GetWeakPtr(),
363 user_context,
364 specifics));
367 void ExistingUserController::PerformLogin(
368 const UserContext& user_context,
369 LoginPerformer::AuthorizationMode auth_mode) {
370 // TODO(antrim): remove this output once crash reason is found.
371 LOG(ERROR) << "Setting flow from PerformLogin";
372 ChromeUserManager::Get()
373 ->GetUserFlow(user_context.GetUserID())
374 ->SetHost(host_);
376 BootTimesRecorder::Get()->RecordLoginAttempted();
378 // Use the same LoginPerformer for subsequent login as it has state
379 // such as Authenticator instance.
380 if (!login_performer_.get() || num_login_attempts_ <= 1) {
381 // Only one instance of LoginPerformer should exist at a time.
382 login_performer_.reset(NULL);
383 login_performer_.reset(new ChromeLoginPerformer(this));
386 if (gaia::ExtractDomainName(user_context.GetUserID()) ==
387 chromeos::login::kSupervisedUserDomain) {
388 login_performer_->LoginAsSupervisedUser(user_context);
389 } else {
390 login_performer_->PerformLogin(user_context, auth_mode);
391 RecordPasswordLoginEvent(user_context);
393 SendAccessibilityAlert(
394 l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNING_IN));
397 void ExistingUserController::MigrateUserData(const std::string& old_password) {
398 // LoginPerformer instance has state of the user so it should exist.
399 if (login_performer_.get())
400 login_performer_->RecoverEncryptedData(old_password);
404 void ExistingUserController::OnSigninScreenReady() {
405 signin_screen_ready_ = true;
406 StartPublicSessionAutoLoginTimer();
409 void ExistingUserController::OnStartEnterpriseEnrollment() {
410 if (KioskAppManager::Get()->IsConsumerKioskDeviceWithAutoLaunch()) {
411 LOG(WARNING) << "Enterprise enrollment is not available after kiosk auto "
412 "launch is set.";
413 return;
416 DeviceSettingsService::Get()->GetOwnershipStatusAsync(
417 base::Bind(&ExistingUserController::OnEnrollmentOwnershipCheckCompleted,
418 weak_factory_.GetWeakPtr()));
421 void ExistingUserController::OnStartEnableDebuggingScreen() {
422 if (CanShowDebuggingFeatures())
423 ShowEnableDebuggingScreen();
426 void ExistingUserController::OnStartKioskEnableScreen() {
427 KioskAppManager::Get()->GetConsumerKioskAutoLaunchStatus(
428 base::Bind(
429 &ExistingUserController::OnConsumerKioskAutoLaunchCheckCompleted,
430 weak_factory_.GetWeakPtr()));
433 void ExistingUserController::OnStartKioskAutolaunchScreen() {
434 ShowKioskAutolaunchScreen();
437 void ExistingUserController::ResyncUserData() {
438 // LoginPerformer instance has state of the user so it should exist.
439 if (login_performer_.get())
440 login_performer_->ResyncEncryptedData();
443 void ExistingUserController::SetDisplayEmail(const std::string& email) {
444 display_email_ = email;
447 void ExistingUserController::ShowWrongHWIDScreen() {
448 host_->StartWizard(WizardController::kWrongHWIDScreenName);
451 void ExistingUserController::Signout() {
452 NOTREACHED();
455 bool ExistingUserController::IsUserWhitelisted(const std::string& user_id) {
456 bool wildcard_match = false;
457 if (login_performer_.get())
458 return login_performer_->IsUserWhitelisted(user_id, &wildcard_match);
460 return chromeos::CrosSettings::IsWhitelisted(user_id, &wildcard_match);
463 void ExistingUserController::OnConsumerKioskAutoLaunchCheckCompleted(
464 KioskAppManager::ConsumerKioskAutoLaunchStatus status) {
465 if (status == KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE)
466 ShowKioskEnableScreen();
469 void ExistingUserController::OnEnrollmentOwnershipCheckCompleted(
470 DeviceSettingsService::OwnershipStatus status) {
471 if (status == DeviceSettingsService::OWNERSHIP_NONE) {
472 ShowEnrollmentScreen();
473 } else if (status == DeviceSettingsService::OWNERSHIP_TAKEN) {
474 // On a device that is already owned we might want to allow users to
475 // re-enroll if the policy information is invalid.
476 CrosSettingsProvider::TrustedStatus trusted_status =
477 CrosSettings::Get()->PrepareTrustedValues(
478 base::Bind(
479 &ExistingUserController::OnEnrollmentOwnershipCheckCompleted,
480 weak_factory_.GetWeakPtr(), status));
481 if (trusted_status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
482 ShowEnrollmentScreen();
484 } else {
485 // OwnershipService::GetStatusAsync is supposed to return either
486 // OWNERSHIP_NONE or OWNERSHIP_TAKEN.
487 NOTREACHED();
491 void ExistingUserController::ShowEnrollmentScreen() {
492 host_->StartWizard(WizardController::kEnrollmentScreenName);
495 void ExistingUserController::ShowResetScreen() {
496 host_->StartWizard(WizardController::kResetScreenName);
499 void ExistingUserController::ShowEnableDebuggingScreen() {
500 host_->StartWizard(WizardController::kEnableDebuggingScreenName);
503 void ExistingUserController::ShowKioskEnableScreen() {
504 host_->StartWizard(WizardController::kKioskEnableScreenName);
507 void ExistingUserController::ShowKioskAutolaunchScreen() {
508 host_->StartWizard(WizardController::kKioskAutolaunchScreenName);
511 void ExistingUserController::ShowTPMError() {
512 login_display_->SetUIEnabled(false);
513 login_display_->ShowErrorScreen(LoginDisplay::TPM_ERROR);
516 ////////////////////////////////////////////////////////////////////////////////
517 // ExistingUserController, LoginPerformer::Delegate implementation:
520 void ExistingUserController::OnAuthFailure(const AuthFailure& failure) {
521 offline_failed_ = true;
522 guest_mode_url_ = GURL::EmptyGURL();
523 std::string error = failure.GetErrorString();
525 PerformLoginFinishedActions(false /* don't start public session timer */);
527 if (ChromeUserManager::Get()
528 ->GetUserFlow(last_login_attempt_username_)
529 ->HandleLoginFailure(failure)) {
530 return;
533 if (failure.reason() == AuthFailure::OWNER_REQUIRED) {
534 ShowError(IDS_LOGIN_ERROR_OWNER_REQUIRED, error);
535 content::BrowserThread::PostDelayedTask(
536 content::BrowserThread::UI, FROM_HERE,
537 base::Bind(&SessionManagerClient::StopSession,
538 base::Unretained(DBusThreadManager::Get()->
539 GetSessionManagerClient())),
540 base::TimeDelta::FromMilliseconds(kSafeModeRestartUiDelayMs));
541 } else if (failure.reason() == AuthFailure::TPM_ERROR) {
542 ShowTPMError();
543 } else if (!online_succeeded_for_.empty()) {
544 ShowGaiaPasswordChanged(online_succeeded_for_);
545 } else if (last_login_attempt_username_ == chromeos::login::kGuestUserName) {
546 // Show no errors, just re-enable input.
547 login_display_->ClearAndEnablePassword();
548 StartPublicSessionAutoLoginTimer();
549 } else {
550 // Check networking after trying to login in case user is
551 // cached locally or the local admin account.
552 bool is_known_user = user_manager::UserManager::Get()->IsKnownUser(
553 last_login_attempt_username_);
554 if (!network_state_helper_->IsConnected()) {
555 if (is_known_user)
556 ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
557 else
558 ShowError(IDS_LOGIN_ERROR_OFFLINE_FAILED_NETWORK_NOT_CONNECTED, error);
559 } else {
560 // TODO(nkostylev): Cleanup rest of ClientLogin related code.
561 if (failure.reason() == AuthFailure::NETWORK_AUTH_FAILED &&
562 failure.error().state() ==
563 GoogleServiceAuthError::HOSTED_NOT_ALLOWED) {
564 ShowError(IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED, error);
565 } else {
566 if (!is_known_user)
567 ShowError(IDS_LOGIN_ERROR_AUTHENTICATING_NEW, error);
568 else
569 ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
572 login_display_->ClearAndEnablePassword();
573 StartPublicSessionAutoLoginTimer();
576 // Reset user flow to default, so that special flow will not affect next
577 // attempt.
578 ChromeUserManager::Get()->ResetUserFlow(last_login_attempt_username_);
580 if (auth_status_consumer_)
581 auth_status_consumer_->OnAuthFailure(failure);
583 // Clear the recorded displayed email so it won't affect any future attempts.
584 display_email_.clear();
586 // TODO(ginkage): Fix this case once crbug.com/469990 is ready.
588 if (failure.reason() == AuthFailure::COULD_NOT_MOUNT_CRYPTOHOME) {
589 RecordReauthReason(last_login_attempt_username_,
590 ReauthReason::MISSING_CRYPTOHOME);
595 void ExistingUserController::OnAuthSuccess(const UserContext& user_context) {
596 is_login_in_progress_ = false;
597 offline_failed_ = false;
598 login_display_->set_signin_completed(true);
600 // Login performer will be gone so cache this value to use
601 // once profile is loaded.
602 password_changed_ = login_performer_->password_changed();
603 auth_mode_ = login_performer_->auth_mode();
605 ChromeUserManager::Get()
606 ->GetUserFlow(user_context.GetUserID())
607 ->HandleLoginSuccess(user_context);
609 StopPublicSessionAutoLoginTimer();
611 // Truth table of |has_auth_cookies|:
612 // Regular SAML
613 // /ServiceLogin T T
614 // /ChromeOsEmbeddedSetup F T
615 // Bootstrap experiment F N/A
616 const bool has_auth_cookies =
617 login_performer_->auth_mode() == LoginPerformer::AUTH_MODE_EXTENSION &&
618 (user_context.GetAccessToken().empty() ||
619 user_context.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITH_SAML) &&
620 user_context.GetAuthFlow() != UserContext::AUTH_FLOW_EASY_BOOTSTRAP;
622 // LoginPerformer instance will delete itself in case of successful auth.
623 login_performer_->set_delegate(NULL);
624 ignore_result(login_performer_.release());
626 UserSessionManager::StartSessionType start_session_type =
627 UserAddingScreen::Get()->IsRunning()
628 ? UserSessionManager::SECONDARY_USER_SESSION
629 : UserSessionManager::PRIMARY_USER_SESSION;
630 UserSessionManager::GetInstance()->StartSession(
631 user_context, start_session_type, has_auth_cookies,
632 false, // Start session for user.
633 this);
635 // Update user's displayed email.
636 if (!display_email_.empty()) {
637 user_manager::UserManager::Get()->SaveUserDisplayEmail(
638 user_context.GetUserID(), display_email_);
639 display_email_.clear();
643 void ExistingUserController::OnProfilePrepared(Profile* profile,
644 bool browser_launched) {
645 // Reenable clicking on other windows and status area.
646 login_display_->SetUIEnabled(true);
648 if (browser_launched)
649 host_ = NULL;
651 // Inform |auth_status_consumer_| about successful login.
652 // TODO(nkostylev): Pass UserContext back crbug.com/424550
653 if (auth_status_consumer_) {
654 auth_status_consumer_->
655 OnAuthSuccess(UserContext(last_login_attempt_username_));
659 void ExistingUserController::OnOffTheRecordAuthSuccess() {
660 is_login_in_progress_ = false;
661 offline_failed_ = false;
663 // Mark the device as registered., i.e. the second part of OOBE as completed.
664 if (!StartupUtils::IsDeviceRegistered())
665 StartupUtils::MarkDeviceRegistered(base::Closure());
667 UserSessionManager::GetInstance()->CompleteGuestSessionLogin(guest_mode_url_);
669 if (auth_status_consumer_)
670 auth_status_consumer_->OnOffTheRecordAuthSuccess();
673 void ExistingUserController::OnPasswordChangeDetected() {
674 is_login_in_progress_ = false;
675 offline_failed_ = false;
677 // Must not proceed without signature verification.
678 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
679 base::Bind(&ExistingUserController::OnPasswordChangeDetected,
680 weak_factory_.GetWeakPtr()))) {
681 // Value of owner email is still not verified.
682 // Another attempt will be invoked after verification completion.
683 return;
686 if (ChromeUserManager::Get()
687 ->GetUserFlow(last_login_attempt_username_)
688 ->HandlePasswordChangeDetected()) {
689 return;
692 // True if user has already made an attempt to enter old password and failed.
693 bool show_invalid_old_password_error =
694 login_performer_->password_changed_callback_count() > 1;
696 // Note: We allow owner using "full sync" mode which will recreate
697 // cryptohome and deal with owner private key being lost. This also allows
698 // us to recover from a lost owner password/homedir.
699 // TODO(gspencer): We shouldn't have to erase stateful data when
700 // doing this. See http://crosbug.com/9115 http://crosbug.com/7792
701 login_display_->ShowPasswordChangedDialog(show_invalid_old_password_error,
702 display_email_);
704 if (auth_status_consumer_)
705 auth_status_consumer_->OnPasswordChangeDetected();
707 display_email_.clear();
710 void ExistingUserController::WhiteListCheckFailed(const std::string& email) {
711 PerformLoginFinishedActions(true /* start public session timer */);
712 offline_failed_ = false;
714 if (StartupUtils::IsWebviewSigninEnabled()) {
715 login_display_->ShowWhitelistCheckFailedError();
716 } else {
717 if (g_browser_process->platform_part()
718 ->browser_policy_connector_chromeos()
719 ->IsEnterpriseManaged()) {
720 ShowError(IDS_ENTERPRISE_LOGIN_ERROR_WHITELIST, email);
721 } else {
722 ShowError(IDS_LOGIN_ERROR_WHITELIST, email);
724 login_display_->ShowSigninUI(email);
727 if (auth_status_consumer_) {
728 auth_status_consumer_->OnAuthFailure(
729 AuthFailure(AuthFailure::WHITELIST_CHECK_FAILED));
732 display_email_.clear();
735 void ExistingUserController::PolicyLoadFailed() {
736 ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, "");
738 PerformLoginFinishedActions(false /* don't start public session timer */);
739 offline_failed_ = false;
740 display_email_.clear();
743 void ExistingUserController::OnOnlineChecked(const std::string& username,
744 bool success) {
745 if (success && last_login_attempt_username_ == username) {
746 online_succeeded_for_ = username;
747 // Wait for login attempt to end, if it hasn't yet.
748 if (offline_failed_ && !is_login_in_progress_)
749 ShowGaiaPasswordChanged(username);
753 ////////////////////////////////////////////////////////////////////////////////
754 // ExistingUserController, private:
756 void ExistingUserController::DeviceSettingsChanged() {
757 // If login was already completed, we should avoid any signin screen
758 // transitions, see http://crbug.com/461604 for example.
759 if (host_ != NULL && !login_display_->is_signin_completed()) {
760 // Signed settings or user list changed. Notify views and update them.
761 UpdateLoginDisplay(user_manager::UserManager::Get()->GetUsers());
762 ConfigurePublicSessionAutoLogin();
766 LoginPerformer::AuthorizationMode ExistingUserController::auth_mode() const {
767 if (login_performer_)
768 return login_performer_->auth_mode();
770 return auth_mode_;
773 bool ExistingUserController::password_changed() const {
774 if (login_performer_)
775 return login_performer_->password_changed();
777 return password_changed_;
780 void ExistingUserController::LoginAsGuest() {
781 PerformPreLoginActions(UserContext(user_manager::USER_TYPE_GUEST,
782 chromeos::login::kGuestUserName));
784 bool allow_guest;
785 cros_settings_->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
786 if (!allow_guest) {
787 // Disallowed. The UI should normally not show the guest pod but if for some
788 // reason this has been made available to the user here is the time to tell
789 // this nicely.
790 if (g_browser_process->platform_part()
791 ->browser_policy_connector_chromeos()
792 ->IsEnterpriseManaged()) {
793 login_display_->ShowError(IDS_ENTERPRISE_LOGIN_ERROR_WHITELIST, 1,
794 HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
795 } else {
796 login_display_->ShowError(IDS_LOGIN_ERROR_WHITELIST, 1,
797 HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
799 PerformLoginFinishedActions(true /* start public session timer */);
800 display_email_.clear();
801 return;
804 // Only one instance of LoginPerformer should exist at a time.
805 login_performer_.reset(NULL);
806 login_performer_.reset(new ChromeLoginPerformer(this));
807 login_performer_->LoginOffTheRecord();
808 SendAccessibilityAlert(
809 l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_OFFRECORD));
812 void ExistingUserController::LoginAsPublicSession(
813 const UserContext& user_context) {
814 PerformPreLoginActions(user_context);
816 // If there is no public account with the given user ID, logging in is not
817 // possible.
818 const user_manager::User* user =
819 user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
820 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
821 PerformLoginFinishedActions(true /* start public session timer */);
822 return;
825 UserContext new_user_context = user_context;
826 std::string locale = user_context.GetPublicSessionLocale();
827 if (locale.empty()) {
828 // When performing auto-login, no locale is chosen by the user. Check
829 // whether a list of recommended locales was set by policy. If so, use its
830 // first entry. Otherwise, |locale| will remain blank, indicating that the
831 // public session should use the current UI locale.
832 const policy::PolicyMap::Entry* entry = g_browser_process->platform_part()->
833 browser_policy_connector_chromeos()->
834 GetDeviceLocalAccountPolicyService()->
835 GetBrokerForUser(user_context.GetUserID())->core()->store()->
836 policy_map().Get(policy::key::kSessionLocales);
837 base::ListValue const* list = NULL;
838 if (entry &&
839 entry->level == policy::POLICY_LEVEL_RECOMMENDED &&
840 entry->value &&
841 entry->value->GetAsList(&list)) {
842 if (list->GetString(0, &locale))
843 new_user_context.SetPublicSessionLocale(locale);
847 if (!locale.empty() &&
848 new_user_context.GetPublicSessionInputMethod().empty()) {
849 // When |locale| is set, a suitable keyboard layout should be chosen. In
850 // most cases, this will already be the case because the UI shows a list of
851 // keyboard layouts suitable for the |locale| and ensures that one of them
852 // us selected. However, it is still possible that |locale| is set but no
853 // keyboard layout was chosen:
854 // * The list of keyboard layouts is updated asynchronously. If the user
855 // enters the public session before the list of keyboard layouts for the
856 // |locale| has been retrieved, the UI will indicate that no keyboard
857 // layout was chosen.
858 // * During auto-login, the |locale| is set in this method and a suitable
859 // keyboard layout must be chosen next.
861 // The list of suitable keyboard layouts is constructed asynchronously. Once
862 // it has been retrieved, |SetPublicSessionKeyboardLayoutAndLogin| will
863 // select the first layout from the list and continue login.
864 GetKeyboardLayoutsForLocale(
865 base::Bind(
866 &ExistingUserController::SetPublicSessionKeyboardLayoutAndLogin,
867 weak_factory_.GetWeakPtr(),
868 new_user_context),
869 locale);
870 return;
873 // The user chose a locale and a suitable keyboard layout or left both unset.
874 // Login can continue immediately.
875 LoginAsPublicSessionInternal(new_user_context);
878 void ExistingUserController::LoginAsKioskApp(const std::string& app_id,
879 bool diagnostic_mode) {
880 const bool auto_start = false;
881 host_->StartAppLaunch(app_id, diagnostic_mode, auto_start);
884 void ExistingUserController::ConfigurePublicSessionAutoLogin() {
885 std::string auto_login_account_id;
886 cros_settings_->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
887 &auto_login_account_id);
888 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
889 policy::GetDeviceLocalAccounts(cros_settings_);
891 public_session_auto_login_username_.clear();
892 for (std::vector<policy::DeviceLocalAccount>::const_iterator
893 it = device_local_accounts.begin();
894 it != device_local_accounts.end(); ++it) {
895 if (it->account_id == auto_login_account_id) {
896 public_session_auto_login_username_ = it->user_id;
897 break;
901 const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
902 public_session_auto_login_username_);
903 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
904 public_session_auto_login_username_.clear();
906 if (!cros_settings_->GetInteger(
907 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
908 &public_session_auto_login_delay_)) {
909 public_session_auto_login_delay_ = 0;
912 if (!public_session_auto_login_username_.empty())
913 StartPublicSessionAutoLoginTimer();
914 else
915 StopPublicSessionAutoLoginTimer();
918 void ExistingUserController::ResetPublicSessionAutoLoginTimer() {
919 // Only restart the auto-login timer if it's already running.
920 if (auto_login_timer_ && auto_login_timer_->IsRunning()) {
921 StopPublicSessionAutoLoginTimer();
922 StartPublicSessionAutoLoginTimer();
926 void ExistingUserController::OnPublicSessionAutoLoginTimerFire() {
927 CHECK(signin_screen_ready_ && !public_session_auto_login_username_.empty());
928 Login(UserContext(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
929 public_session_auto_login_username_),
930 SigninSpecifics());
933 void ExistingUserController::StopPublicSessionAutoLoginTimer() {
934 if (auto_login_timer_)
935 auto_login_timer_->Stop();
938 void ExistingUserController::StartPublicSessionAutoLoginTimer() {
939 if (!signin_screen_ready_ ||
940 is_login_in_progress_ ||
941 public_session_auto_login_username_.empty()) {
942 return;
945 // Start the auto-login timer.
946 if (!auto_login_timer_)
947 auto_login_timer_.reset(new base::OneShotTimer<ExistingUserController>);
949 auto_login_timer_->Start(
950 FROM_HERE,
951 base::TimeDelta::FromMilliseconds(
952 public_session_auto_login_delay_),
953 base::Bind(
954 &ExistingUserController::OnPublicSessionAutoLoginTimerFire,
955 weak_factory_.GetWeakPtr()));
958 gfx::NativeWindow ExistingUserController::GetNativeWindow() const {
959 return host_->GetNativeWindow();
962 void ExistingUserController::ShowError(int error_id,
963 const std::string& details) {
964 VLOG(1) << details;
965 HelpAppLauncher::HelpTopic help_topic_id;
966 if (login_performer_) {
967 switch (login_performer_->error().state()) {
968 case GoogleServiceAuthError::ACCOUNT_DISABLED:
969 help_topic_id = HelpAppLauncher::HELP_ACCOUNT_DISABLED;
970 break;
971 case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
972 help_topic_id = HelpAppLauncher::HELP_HOSTED_ACCOUNT;
973 break;
974 default:
975 help_topic_id = HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT;
976 break;
978 } else {
979 // login_performer_ will be null if an error occurred during OAuth2 token
980 // fetch. In this case, show a generic error.
981 help_topic_id = HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT;
984 if (error_id == IDS_LOGIN_ERROR_AUTHENTICATING) {
985 if (num_login_attempts_ > 1) {
986 const user_manager::User* user =
987 user_manager::UserManager::Get()->FindUser(
988 last_login_attempt_username_);
989 if (user && (user->GetType() == user_manager::USER_TYPE_SUPERVISED))
990 error_id = IDS_LOGIN_ERROR_AUTHENTICATING_2ND_TIME_SUPERVISED;
994 login_display_->ShowError(error_id, num_login_attempts_, help_topic_id);
997 void ExistingUserController::ShowGaiaPasswordChanged(
998 const std::string& username) {
999 // Invalidate OAuth token, since it can't be correct after password is
1000 // changed.
1001 user_manager::UserManager::Get()->SaveUserOAuthStatus(
1002 username, user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
1003 RecordReauthReason(username, ReauthReason::OTHER);
1005 login_display_->SetUIEnabled(true);
1006 login_display_->ShowGaiaPasswordChanged(username);
1009 void ExistingUserController::SendAccessibilityAlert(
1010 const std::string& alert_text) {
1011 AutomationManagerAura::GetInstance()->HandleAlert(
1012 ProfileHelper::GetSigninProfile(), alert_text);
1015 void ExistingUserController::SetPublicSessionKeyboardLayoutAndLogin(
1016 const UserContext& user_context,
1017 scoped_ptr<base::ListValue> keyboard_layouts) {
1018 UserContext new_user_context = user_context;
1019 std::string keyboard_layout;
1020 for (size_t i = 0; i < keyboard_layouts->GetSize(); ++i) {
1021 base::DictionaryValue* entry = NULL;
1022 keyboard_layouts->GetDictionary(i, &entry);
1023 bool selected = false;
1024 entry->GetBoolean("selected", &selected);
1025 if (selected) {
1026 entry->GetString("value", &keyboard_layout);
1027 break;
1030 DCHECK(!keyboard_layout.empty());
1031 new_user_context.SetPublicSessionInputMethod(keyboard_layout);
1033 LoginAsPublicSessionInternal(new_user_context);
1036 void ExistingUserController::LoginAsPublicSessionInternal(
1037 const UserContext& user_context) {
1038 // Only one instance of LoginPerformer should exist at a time.
1039 login_performer_.reset(NULL);
1040 login_performer_.reset(new ChromeLoginPerformer(this));
1041 login_performer_->LoginAsPublicSession(user_context);
1042 SendAccessibilityAlert(
1043 l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_PUBLIC_ACCOUNT));
1046 void ExistingUserController::PerformPreLoginActions(
1047 const UserContext& user_context) {
1048 // Disable clicking on other windows and status tray.
1049 login_display_->SetUIEnabled(false);
1051 if (last_login_attempt_username_ != user_context.GetUserID()) {
1052 last_login_attempt_username_ = user_context.GetUserID();
1053 num_login_attempts_ = 0;
1055 // Also reset state variables, which are used to determine password change.
1056 offline_failed_ = false;
1057 online_succeeded_for_.clear();
1060 // Guard in cases when we're called twice but login process is still active.
1061 // This might happen when login process is paused till signed settings status
1062 // is verified which results in Login* method called again as a callback.
1063 if (!is_login_in_progress_)
1064 num_login_attempts_++;
1066 is_login_in_progress_ = true;
1068 // Stop the auto-login timer when attempting login.
1069 StopPublicSessionAutoLoginTimer();
1072 void ExistingUserController::PerformLoginFinishedActions(
1073 bool start_public_session_timer) {
1074 is_login_in_progress_ = false;
1076 // Reenable clicking on other windows and status area.
1077 login_display_->SetUIEnabled(true);
1079 if (start_public_session_timer)
1080 StartPublicSessionAutoLoginTimer();
1083 void ExistingUserController::ContinueLoginIfDeviceNotDisabled(
1084 const base::Closure& continuation) {
1085 // Disable clicking on other windows and status tray.
1086 login_display_->SetUIEnabled(false);
1088 // Stop the auto-login timer.
1089 StopPublicSessionAutoLoginTimer();
1091 // Wait for the |cros_settings_| to become either trusted or permanently
1092 // untrusted.
1093 const CrosSettingsProvider::TrustedStatus status =
1094 cros_settings_->PrepareTrustedValues(base::Bind(
1095 &ExistingUserController::ContinueLoginIfDeviceNotDisabled,
1096 weak_factory_.GetWeakPtr(),
1097 continuation));
1098 if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED)
1099 return;
1101 if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
1102 // If the |cros_settings_| are permanently untrusted, show an error message
1103 // and refuse to log in.
1104 login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST,
1106 HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
1108 // Re-enable clicking on other windows and the status area. Do not start the
1109 // auto-login timer though. Without trusted |cros_settings_|, no auto-login
1110 // can succeed.
1111 login_display_->SetUIEnabled(true);
1112 return;
1115 bool device_disabled = false;
1116 cros_settings_->GetBoolean(kDeviceDisabled, &device_disabled);
1117 if (device_disabled && system::DeviceDisablingManager::
1118 HonorDeviceDisablingDuringNormalOperation()) {
1119 // If the device is disabled, bail out. A device disabled screen will be
1120 // shown by the DeviceDisablingManager.
1122 // Re-enable clicking on other windows and the status area. Do not start the
1123 // auto-login timer though. On a disabled device, no auto-login can succeed.
1124 login_display_->SetUIEnabled(true);
1125 return;
1128 continuation.Run();
1131 void ExistingUserController::DoCompleteLogin(
1132 const UserContext& user_context_wo_device_id) {
1133 UserContext user_context = user_context_wo_device_id;
1134 std::string device_id =
1135 user_manager::UserManager::Get()->GetKnownUserDeviceId(
1136 user_context.GetUserID());
1137 if (device_id.empty()) {
1138 bool is_ephemeral =
1139 ChromeUserManager::Get()->AreEphemeralUsersEnabled() &&
1140 user_context.GetUserID() != ChromeUserManager::Get()->GetOwnerEmail();
1141 device_id = SigninClient::GenerateSigninScopedDeviceID(is_ephemeral);
1143 user_context.SetDeviceId(device_id);
1145 const std::string& gaps_cookie = user_context.GetGAPSCookie();
1146 if (!gaps_cookie.empty()) {
1147 user_manager::UserManager::Get()->SetKnownUserGAPSCookie(
1148 user_context.GetUserID(), gaps_cookie);
1151 PerformPreLoginActions(user_context);
1153 if (!time_init_.is_null()) {
1154 base::TimeDelta delta = base::Time::Now() - time_init_;
1155 UMA_HISTOGRAM_MEDIUM_TIMES("Login.PromptToCompleteLoginTime", delta);
1156 time_init_ = base::Time(); // Reset to null.
1159 host_->OnCompleteLogin();
1161 if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_EASY_BOOTSTRAP) {
1162 bootstrap_user_context_initializer_.reset(
1163 new BootstrapUserContextInitializer());
1164 bootstrap_user_context_initializer_->Start(
1165 user_context.GetAuthCode(),
1166 base::Bind(&ExistingUserController::OnBootstrapUserContextInitialized,
1167 weak_factory_.GetWeakPtr()));
1168 return;
1171 // Fetch OAuth2 tokens if we have an auth code and are not using SAML.
1172 // SAML uses cookies to get tokens.
1173 if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML &&
1174 !user_context.GetAuthCode().empty()) {
1175 oauth2_token_initializer_.reset(new OAuth2TokenInitializer);
1176 oauth2_token_initializer_->Start(
1177 user_context, base::Bind(&ExistingUserController::OnOAuth2TokensFetched,
1178 weak_factory_.GetWeakPtr()));
1179 return;
1182 PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
1185 void ExistingUserController::DoLogin(const UserContext& user_context,
1186 const SigninSpecifics& specifics) {
1187 if (is_login_in_progress_) {
1188 // If there is another login in progress, bail out. Do not re-enable
1189 // clicking on other windows and the status area. Do not start the
1190 // auto-login timer.
1191 return;
1194 if (user_context.GetUserType() != user_manager::USER_TYPE_REGULAR &&
1195 user_manager::UserManager::Get()->IsUserLoggedIn()) {
1196 // Multi-login is only allowed for regular users. If we are attempting to
1197 // do multi-login as another type of user somehow, bail out. Do not
1198 // re-enable clicking on other windows and the status area. Do not start the
1199 // auto-login timer.
1200 return;
1203 if (user_context.GetUserType() == user_manager::USER_TYPE_GUEST) {
1204 if (!specifics.guest_mode_url.empty()) {
1205 guest_mode_url_ = GURL(specifics.guest_mode_url);
1206 if (specifics.guest_mode_url_append_locale)
1207 guest_mode_url_ = google_util::AppendGoogleLocaleParam(
1208 guest_mode_url_, g_browser_process->GetApplicationLocale());
1210 LoginAsGuest();
1211 return;
1214 if (user_context.GetUserType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
1215 LoginAsPublicSession(user_context);
1216 return;
1219 if (user_context.GetUserType() == user_manager::USER_TYPE_KIOSK_APP) {
1220 LoginAsKioskApp(user_context.GetUserID(), specifics.kiosk_diagnostic_mode);
1221 return;
1224 // Regular user or supervised user login.
1226 if (!user_context.HasCredentials()) {
1227 // If credentials are missing, refuse to log in.
1229 // Reenable clicking on other windows and status area.
1230 login_display_->SetUIEnabled(true);
1231 // Restart the auto-login timer.
1232 StartPublicSessionAutoLoginTimer();
1235 PerformPreLoginActions(user_context);
1236 PerformLogin(user_context, LoginPerformer::AUTH_MODE_INTERNAL);
1239 void ExistingUserController::OnBootstrapUserContextInitialized(
1240 bool success,
1241 const UserContext& user_context) {
1242 if (!success) {
1243 LOG(ERROR) << "Easy bootstrap failed.";
1244 OnAuthFailure(AuthFailure(AuthFailure::NETWORK_AUTH_FAILED));
1245 return;
1248 // Setting a customized login user flow to perform additional initializations
1249 // for bootstrap after the user session is started.
1250 ChromeUserManager::Get()->SetUserFlow(
1251 user_context.GetUserID(),
1252 new BootstrapUserFlow(
1253 user_context,
1254 bootstrap_user_context_initializer_->random_key_used()));
1256 PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
1259 void ExistingUserController::OnOAuth2TokensFetched(
1260 bool success,
1261 const UserContext& user_context) {
1262 if (!success) {
1263 LOG(ERROR) << "OAuth2 token fetch failed.";
1264 OnAuthFailure(AuthFailure(AuthFailure::FAILED_TO_INITIALIZE_TOKEN));
1265 return;
1267 UserSessionManager::GetInstance()->OnOAuth2TokensFetched(user_context);
1268 PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
1271 } // namespace chromeos