Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / chromeos / login / existing_user_controller.cc
blob3db402453b65fc41976ea47b01a6a95310cb34ac
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/session/user_session_manager.h"
32 #include "chrome/browser/chromeos/login/signin/oauth2_token_initializer.h"
33 #include "chrome/browser/chromeos/login/signin_specifics.h"
34 #include "chrome/browser/chromeos/login/startup_utils.h"
35 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
36 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
37 #include "chrome/browser/chromeos/login/user_flow.h"
38 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
39 #include "chrome/browser/chromeos/login/wizard_controller.h"
40 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
41 #include "chrome/browser/chromeos/policy/device_local_account.h"
42 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
43 #include "chrome/browser/chromeos/profiles/profile_helper.h"
44 #include "chrome/browser/chromeos/settings/cros_settings.h"
45 #include "chrome/browser/chromeos/system/device_disabling_manager.h"
46 #include "chrome/browser/signin/easy_unlock_service.h"
47 #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h"
48 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
49 #include "chrome/common/chrome_switches.h"
50 #include "chrome/common/url_constants.h"
51 #include "chrome/grit/generated_resources.h"
52 #include "chromeos/chromeos_switches.h"
53 #include "chromeos/dbus/dbus_thread_manager.h"
54 #include "chromeos/dbus/power_manager_client.h"
55 #include "chromeos/dbus/session_manager_client.h"
56 #include "chromeos/login/user_names.h"
57 #include "chromeos/settings/cros_settings_names.h"
58 #include "components/google/core/browser/google_util.h"
59 #include "components/policy/core/common/cloud/cloud_policy_core.h"
60 #include "components/policy/core/common/cloud/cloud_policy_store.h"
61 #include "components/policy/core/common/policy_map.h"
62 #include "components/policy/core/common/policy_service.h"
63 #include "components/policy/core/common/policy_types.h"
64 #include "components/signin/core/browser/signin_client.h"
65 #include "components/user_manager/user_manager.h"
66 #include "components/user_manager/user_type.h"
67 #include "content/public/browser/browser_thread.h"
68 #include "content/public/browser/notification_service.h"
69 #include "content/public/browser/notification_types.h"
70 #include "content/public/browser/user_metrics.h"
71 #include "google_apis/gaia/gaia_auth_util.h"
72 #include "google_apis/gaia/google_service_auth_error.h"
73 #include "net/http/http_auth_cache.h"
74 #include "net/http/http_network_session.h"
75 #include "net/http/http_transaction_factory.h"
76 #include "net/url_request/url_request_context.h"
77 #include "net/url_request/url_request_context_getter.h"
78 #include "policy/policy_constants.h"
79 #include "ui/accessibility/ax_enums.h"
80 #include "ui/base/l10n/l10n_util.h"
81 #include "ui/views/widget/widget.h"
83 namespace chromeos {
85 namespace {
87 // URL for account creation.
88 const char kCreateAccountURL[] =
89 "https://accounts.google.com/NewAccount?service=mail";
91 // Delay for transferring the auth cache to the system profile.
92 const long int kAuthCacheTransferDelayMs = 2000;
94 // Delay for restarting the ui if safe-mode login has failed.
95 const long int kSafeModeRestartUiDelayMs = 30000;
97 // Makes a call to the policy subsystem to reload the policy when we detect
98 // authentication change.
99 void RefreshPoliciesOnUIThread() {
100 if (g_browser_process->policy_service())
101 g_browser_process->policy_service()->RefreshPolicies(base::Closure());
104 // Copies any authentication details that were entered in the login profile in
105 // the mail profile to make sure all subsystems of Chrome can access the network
106 // with the provided authentication which are possibly for a proxy server.
107 void TransferContextAuthenticationsOnIOThread(
108 net::URLRequestContextGetter* default_profile_context_getter,
109 net::URLRequestContextGetter* browser_process_context_getter) {
110 net::HttpAuthCache* new_cache =
111 browser_process_context_getter->GetURLRequestContext()->
112 http_transaction_factory()->GetSession()->http_auth_cache();
113 net::HttpAuthCache* old_cache =
114 default_profile_context_getter->GetURLRequestContext()->
115 http_transaction_factory()->GetSession()->http_auth_cache();
116 new_cache->UpdateAllFrom(*old_cache);
117 VLOG(1) << "Main request context populated with authentication data.";
118 // Last but not least tell the policy subsystem to refresh now as it might
119 // have been stuck until now too.
120 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
121 base::Bind(&RefreshPoliciesOnUIThread));
124 // Record UMA for password login of regular user when Easy sign-in is enabled.
125 void RecordPasswordLoginEvent(const UserContext& user_context) {
126 EasyUnlockService* easy_unlock_service =
127 EasyUnlockService::Get(ProfileHelper::GetSigninProfile());
128 if (user_context.GetUserType() == user_manager::USER_TYPE_REGULAR &&
129 user_context.GetAuthFlow() == UserContext::AUTH_FLOW_OFFLINE &&
130 easy_unlock_service) {
131 easy_unlock_service->RecordPasswordLoginEvent(user_context.GetUserID());
135 bool CanShowDebuggingFeatures() {
136 // We need to be on the login screen and in dev mode to show this menu item.
137 return base::CommandLine::ForCurrentProcess()->HasSwitch(
138 chromeos::switches::kSystemDevMode) &&
139 base::CommandLine::ForCurrentProcess()->HasSwitch(
140 chromeos::switches::kLoginManager) &&
141 !user_manager::UserManager::Get()->IsSessionStarted();
144 } // namespace
146 // static
147 ExistingUserController* ExistingUserController::current_controller_ = NULL;
149 ////////////////////////////////////////////////////////////////////////////////
150 // ExistingUserController, public:
152 ExistingUserController::ExistingUserController(LoginDisplayHost* host)
153 : auth_status_consumer_(NULL),
154 host_(host),
155 login_display_(host_->CreateLoginDisplay(this)),
156 num_login_attempts_(0),
157 cros_settings_(CrosSettings::Get()),
158 is_login_in_progress_(false),
159 password_changed_(false),
160 auth_mode_(LoginPerformer::AUTH_MODE_EXTENSION),
161 signin_screen_ready_(false),
162 network_state_helper_(new login::NetworkStateHelper),
163 weak_factory_(this) {
164 DCHECK(current_controller_ == NULL);
165 current_controller_ = this;
167 registrar_.Add(this,
168 chrome::NOTIFICATION_USER_LIST_CHANGED,
169 content::NotificationService::AllSources());
170 registrar_.Add(this,
171 chrome::NOTIFICATION_AUTH_SUPPLIED,
172 content::NotificationService::AllSources());
173 registrar_.Add(this,
174 chrome::NOTIFICATION_SESSION_STARTED,
175 content::NotificationService::AllSources());
176 show_user_names_subscription_ = cros_settings_->AddSettingsObserver(
177 kAccountsPrefShowUserNamesOnSignIn,
178 base::Bind(&ExistingUserController::DeviceSettingsChanged,
179 base::Unretained(this)));
180 allow_new_user_subscription_ = cros_settings_->AddSettingsObserver(
181 kAccountsPrefAllowNewUser,
182 base::Bind(&ExistingUserController::DeviceSettingsChanged,
183 base::Unretained(this)));
184 allow_guest_subscription_ = cros_settings_->AddSettingsObserver(
185 kAccountsPrefAllowGuest,
186 base::Bind(&ExistingUserController::DeviceSettingsChanged,
187 base::Unretained(this)));
188 allow_supervised_user_subscription_ = cros_settings_->AddSettingsObserver(
189 kAccountsPrefSupervisedUsersEnabled,
190 base::Bind(&ExistingUserController::DeviceSettingsChanged,
191 base::Unretained(this)));
192 users_subscription_ = cros_settings_->AddSettingsObserver(
193 kAccountsPrefUsers,
194 base::Bind(&ExistingUserController::DeviceSettingsChanged,
195 base::Unretained(this)));
196 local_account_auto_login_id_subscription_ =
197 cros_settings_->AddSettingsObserver(
198 kAccountsPrefDeviceLocalAccountAutoLoginId,
199 base::Bind(&ExistingUserController::ConfigurePublicSessionAutoLogin,
200 base::Unretained(this)));
201 local_account_auto_login_delay_subscription_ =
202 cros_settings_->AddSettingsObserver(
203 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
204 base::Bind(&ExistingUserController::ConfigurePublicSessionAutoLogin,
205 base::Unretained(this)));
208 void ExistingUserController::Init(const user_manager::UserList& users) {
209 time_init_ = base::Time::Now();
210 UpdateLoginDisplay(users);
211 ConfigurePublicSessionAutoLogin();
214 void ExistingUserController::UpdateLoginDisplay(
215 const user_manager::UserList& users) {
216 bool show_users_on_signin;
217 user_manager::UserList filtered_users;
219 cros_settings_->GetBoolean(kAccountsPrefShowUserNamesOnSignIn,
220 &show_users_on_signin);
221 for (user_manager::UserList::const_iterator it = users.begin();
222 it != users.end();
223 ++it) {
224 // TODO(xiyuan): Clean user profile whose email is not in whitelist.
225 bool meets_supervised_requirements =
226 (*it)->GetType() != user_manager::USER_TYPE_SUPERVISED ||
227 user_manager::UserManager::Get()->AreSupervisedUsersAllowed();
228 bool meets_whitelist_requirements =
229 CrosSettings::IsWhitelisted((*it)->email(), NULL) ||
230 !(*it)->HasGaiaAccount();
232 // Public session accounts are always shown on login screen.
233 bool meets_show_users_requirements =
234 show_users_on_signin ||
235 (*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT;
236 if (meets_supervised_requirements &&
237 meets_whitelist_requirements &&
238 meets_show_users_requirements) {
239 filtered_users.push_back(*it);
243 // If no user pods are visible, fallback to single new user pod which will
244 // have guest session link.
245 bool show_guest;
246 cros_settings_->GetBoolean(kAccountsPrefAllowGuest, &show_guest);
247 show_users_on_signin |= !filtered_users.empty();
248 show_guest &= !filtered_users.empty();
249 bool show_new_user = true;
250 login_display_->set_parent_window(GetNativeWindow());
251 login_display_->Init(
252 filtered_users, show_guest, show_users_on_signin, show_new_user);
253 host_->OnPreferencesChanged();
256 ////////////////////////////////////////////////////////////////////////////////
257 // ExistingUserController, content::NotificationObserver implementation:
260 void ExistingUserController::Observe(
261 int type,
262 const content::NotificationSource& source,
263 const content::NotificationDetails& details) {
264 if (type == chrome::NOTIFICATION_SESSION_STARTED) {
265 // Stop listening to any notification once session has started.
266 // Sign in screen objects are marked for deletion with DeleteSoon so
267 // make sure no object would be used after session has started.
268 // http://crbug.com/125276
269 registrar_.RemoveAll();
270 return;
272 if (type == chrome::NOTIFICATION_USER_LIST_CHANGED) {
273 DeviceSettingsChanged();
274 return;
276 if (type == chrome::NOTIFICATION_AUTH_SUPPLIED) {
277 // Possibly the user has authenticated against a proxy server and we might
278 // need the credentials for enrollment and other system requests from the
279 // main |g_browser_process| request context (see bug
280 // http://crosbug.com/24861). So we transfer any credentials to the global
281 // request context here.
282 // The issue we have here is that the NOTIFICATION_AUTH_SUPPLIED is sent
283 // just after the UI is closed but before the new credentials were stored
284 // in the profile. Therefore we have to give it some time to make sure it
285 // has been updated before we copy it.
286 VLOG(1) << "Authentication was entered manually, possibly for proxyauth.";
287 scoped_refptr<net::URLRequestContextGetter> browser_process_context_getter =
288 g_browser_process->system_request_context();
289 Profile* signin_profile = ProfileHelper::GetSigninProfile();
290 scoped_refptr<net::URLRequestContextGetter> signin_profile_context_getter =
291 signin_profile->GetRequestContext();
292 DCHECK(browser_process_context_getter.get());
293 DCHECK(signin_profile_context_getter.get());
294 content::BrowserThread::PostDelayedTask(
295 content::BrowserThread::IO, FROM_HERE,
296 base::Bind(&TransferContextAuthenticationsOnIOThread,
297 signin_profile_context_getter,
298 browser_process_context_getter),
299 base::TimeDelta::FromMilliseconds(kAuthCacheTransferDelayMs));
303 ////////////////////////////////////////////////////////////////////////////////
304 // ExistingUserController, private:
306 ExistingUserController::~ExistingUserController() {
307 UserSessionManager::GetInstance()->DelegateDeleted(this);
309 if (current_controller_ == this) {
310 current_controller_ = NULL;
311 } else {
312 NOTREACHED() << "More than one controller are alive.";
314 DCHECK(login_display_.get());
317 ////////////////////////////////////////////////////////////////////////////////
318 // ExistingUserController, LoginDisplay::Delegate implementation:
321 void ExistingUserController::CancelPasswordChangedFlow() {
322 login_performer_.reset(NULL);
323 PerformLoginFinishedActions(true /* start public session timer */);
326 void ExistingUserController::CreateAccount() {
327 content::RecordAction(base::UserMetricsAction("Login.CreateAccount"));
328 guest_mode_url_ = google_util::AppendGoogleLocaleParam(
329 GURL(kCreateAccountURL), g_browser_process->GetApplicationLocale());
330 Login(UserContext(user_manager::USER_TYPE_GUEST, std::string()),
331 SigninSpecifics());
334 void ExistingUserController::CompleteLogin(const UserContext& user_context) {
335 login_display_->set_signin_completed(true);
336 if (!host_) {
337 // Complete login event was generated already from UI. Ignore notification.
338 return;
341 ContinueLoginIfDeviceNotDisabled(base::Bind(
342 &ExistingUserController::DoCompleteLogin,
343 weak_factory_.GetWeakPtr(),
344 user_context));
347 base::string16 ExistingUserController::GetConnectedNetworkName() {
348 return network_state_helper_->GetCurrentNetworkName();
351 bool ExistingUserController::IsSigninInProgress() const {
352 return is_login_in_progress_;
355 void ExistingUserController::Login(const UserContext& user_context,
356 const SigninSpecifics& specifics) {
357 ContinueLoginIfDeviceNotDisabled(base::Bind(
358 &ExistingUserController::DoLogin,
359 weak_factory_.GetWeakPtr(),
360 user_context,
361 specifics));
364 void ExistingUserController::PerformLogin(
365 const UserContext& user_context,
366 LoginPerformer::AuthorizationMode auth_mode) {
367 VLOG(1) << "Setting flow from PerformLogin";
368 ChromeUserManager::Get()
369 ->GetUserFlow(user_context.GetUserID())
370 ->SetHost(host_);
372 BootTimesRecorder::Get()->RecordLoginAttempted();
374 // Use the same LoginPerformer for subsequent login as it has state
375 // such as Authenticator instance.
376 if (!login_performer_.get() || num_login_attempts_ <= 1) {
377 // Only one instance of LoginPerformer should exist at a time.
378 login_performer_.reset(NULL);
379 login_performer_.reset(new ChromeLoginPerformer(this));
382 if (gaia::ExtractDomainName(user_context.GetUserID()) ==
383 chromeos::login::kSupervisedUserDomain) {
384 login_performer_->LoginAsSupervisedUser(user_context);
385 } else {
386 login_performer_->PerformLogin(user_context, auth_mode);
387 RecordPasswordLoginEvent(user_context);
389 SendAccessibilityAlert(
390 l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNING_IN));
393 void ExistingUserController::MigrateUserData(const std::string& old_password) {
394 // LoginPerformer instance has state of the user so it should exist.
395 if (login_performer_.get())
396 login_performer_->RecoverEncryptedData(old_password);
400 void ExistingUserController::OnSigninScreenReady() {
401 signin_screen_ready_ = true;
402 StartPublicSessionAutoLoginTimer();
405 void ExistingUserController::OnStartEnterpriseEnrollment() {
406 if (KioskAppManager::Get()->IsConsumerKioskDeviceWithAutoLaunch()) {
407 LOG(WARNING) << "Enterprise enrollment is not available after kiosk auto "
408 "launch is set.";
409 return;
412 DeviceSettingsService::Get()->GetOwnershipStatusAsync(
413 base::Bind(&ExistingUserController::OnEnrollmentOwnershipCheckCompleted,
414 weak_factory_.GetWeakPtr()));
417 void ExistingUserController::OnStartEnableDebuggingScreen() {
418 if (CanShowDebuggingFeatures())
419 ShowEnableDebuggingScreen();
422 void ExistingUserController::OnStartKioskEnableScreen() {
423 KioskAppManager::Get()->GetConsumerKioskAutoLaunchStatus(
424 base::Bind(
425 &ExistingUserController::OnConsumerKioskAutoLaunchCheckCompleted,
426 weak_factory_.GetWeakPtr()));
429 void ExistingUserController::OnStartKioskAutolaunchScreen() {
430 ShowKioskAutolaunchScreen();
433 void ExistingUserController::ResyncUserData() {
434 // LoginPerformer instance has state of the user so it should exist.
435 if (login_performer_.get())
436 login_performer_->ResyncEncryptedData();
439 void ExistingUserController::SetDisplayEmail(const std::string& email) {
440 display_email_ = email;
443 void ExistingUserController::ShowWrongHWIDScreen() {
444 host_->StartWizard(WizardController::kWrongHWIDScreenName);
447 void ExistingUserController::Signout() {
448 NOTREACHED();
451 bool ExistingUserController::IsUserWhitelisted(const std::string& user_id) {
452 bool wildcard_match = false;
453 if (login_performer_.get())
454 return login_performer_->IsUserWhitelisted(user_id, &wildcard_match);
456 return chromeos::CrosSettings::IsWhitelisted(user_id, &wildcard_match);
459 void ExistingUserController::OnConsumerKioskAutoLaunchCheckCompleted(
460 KioskAppManager::ConsumerKioskAutoLaunchStatus status) {
461 if (status == KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE)
462 ShowKioskEnableScreen();
465 void ExistingUserController::OnEnrollmentOwnershipCheckCompleted(
466 DeviceSettingsService::OwnershipStatus status) {
467 if (status == DeviceSettingsService::OWNERSHIP_NONE) {
468 ShowEnrollmentScreen();
469 } else if (status == DeviceSettingsService::OWNERSHIP_TAKEN) {
470 // On a device that is already owned we might want to allow users to
471 // re-enroll if the policy information is invalid.
472 CrosSettingsProvider::TrustedStatus trusted_status =
473 CrosSettings::Get()->PrepareTrustedValues(
474 base::Bind(
475 &ExistingUserController::OnEnrollmentOwnershipCheckCompleted,
476 weak_factory_.GetWeakPtr(), status));
477 if (trusted_status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
478 ShowEnrollmentScreen();
480 } else {
481 // OwnershipService::GetStatusAsync is supposed to return either
482 // OWNERSHIP_NONE or OWNERSHIP_TAKEN.
483 NOTREACHED();
487 void ExistingUserController::ShowEnrollmentScreen() {
488 host_->StartWizard(WizardController::kEnrollmentScreenName);
491 void ExistingUserController::ShowResetScreen() {
492 host_->StartWizard(WizardController::kResetScreenName);
495 void ExistingUserController::ShowEnableDebuggingScreen() {
496 host_->StartWizard(WizardController::kEnableDebuggingScreenName);
499 void ExistingUserController::ShowKioskEnableScreen() {
500 host_->StartWizard(WizardController::kKioskEnableScreenName);
503 void ExistingUserController::ShowKioskAutolaunchScreen() {
504 host_->StartWizard(WizardController::kKioskAutolaunchScreenName);
507 void ExistingUserController::ShowTPMError() {
508 login_display_->SetUIEnabled(false);
509 login_display_->ShowErrorScreen(LoginDisplay::TPM_ERROR);
512 ////////////////////////////////////////////////////////////////////////////////
513 // ExistingUserController, LoginPerformer::Delegate implementation:
516 void ExistingUserController::OnAuthFailure(const AuthFailure& failure) {
517 guest_mode_url_ = GURL::EmptyGURL();
518 std::string error = failure.GetErrorString();
520 PerformLoginFinishedActions(false /* don't start public session timer */);
522 if (ChromeUserManager::Get()
523 ->GetUserFlow(last_login_attempt_username_)
524 ->HandleLoginFailure(failure)) {
525 return;
528 if (failure.reason() == AuthFailure::OWNER_REQUIRED) {
529 ShowError(IDS_LOGIN_ERROR_OWNER_REQUIRED, error);
530 content::BrowserThread::PostDelayedTask(
531 content::BrowserThread::UI, FROM_HERE,
532 base::Bind(&SessionManagerClient::StopSession,
533 base::Unretained(DBusThreadManager::Get()->
534 GetSessionManagerClient())),
535 base::TimeDelta::FromMilliseconds(kSafeModeRestartUiDelayMs));
536 } else if (failure.reason() == AuthFailure::TPM_ERROR) {
537 ShowTPMError();
538 } else if (last_login_attempt_username_ == chromeos::login::kGuestUserName) {
539 // Show no errors, just re-enable input.
540 login_display_->ClearAndEnablePassword();
541 StartPublicSessionAutoLoginTimer();
542 } else {
543 // Check networking after trying to login in case user is
544 // cached locally or the local admin account.
545 bool is_known_user = user_manager::UserManager::Get()->IsKnownUser(
546 last_login_attempt_username_);
547 if (!network_state_helper_->IsConnected()) {
548 if (is_known_user)
549 ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
550 else
551 ShowError(IDS_LOGIN_ERROR_OFFLINE_FAILED_NETWORK_NOT_CONNECTED, error);
552 } else {
553 // TODO(nkostylev): Cleanup rest of ClientLogin related code.
554 if (failure.reason() == AuthFailure::NETWORK_AUTH_FAILED &&
555 failure.error().state() ==
556 GoogleServiceAuthError::HOSTED_NOT_ALLOWED) {
557 ShowError(IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED, error);
558 } else {
559 if (!is_known_user)
560 ShowError(IDS_LOGIN_ERROR_AUTHENTICATING_NEW, error);
561 else
562 ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
565 login_display_->ClearAndEnablePassword();
566 StartPublicSessionAutoLoginTimer();
569 // Reset user flow to default, so that special flow will not affect next
570 // attempt.
571 ChromeUserManager::Get()->ResetUserFlow(last_login_attempt_username_);
573 if (auth_status_consumer_)
574 auth_status_consumer_->OnAuthFailure(failure);
576 // Clear the recorded displayed email so it won't affect any future attempts.
577 display_email_.clear();
579 // TODO(ginkage): Fix this case once crbug.com/469990 is ready.
581 if (failure.reason() == AuthFailure::COULD_NOT_MOUNT_CRYPTOHOME) {
582 RecordReauthReason(last_login_attempt_username_,
583 ReauthReason::MISSING_CRYPTOHOME);
588 void ExistingUserController::OnAuthSuccess(const UserContext& user_context) {
589 is_login_in_progress_ = false;
590 login_display_->set_signin_completed(true);
592 // Login performer will be gone so cache this value to use
593 // once profile is loaded.
594 password_changed_ = login_performer_->password_changed();
595 auth_mode_ = login_performer_->auth_mode();
597 ChromeUserManager::Get()
598 ->GetUserFlow(user_context.GetUserID())
599 ->HandleLoginSuccess(user_context);
601 StopPublicSessionAutoLoginTimer();
603 // Truth table of |has_auth_cookies|:
604 // Regular SAML
605 // /ServiceLogin T T
606 // /ChromeOsEmbeddedSetup F T
607 // Bootstrap experiment F N/A
608 const bool has_auth_cookies =
609 login_performer_->auth_mode() == LoginPerformer::AUTH_MODE_EXTENSION &&
610 (user_context.GetAccessToken().empty() ||
611 user_context.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITH_SAML) &&
612 user_context.GetAuthFlow() != UserContext::AUTH_FLOW_EASY_BOOTSTRAP;
614 // LoginPerformer instance will delete itself in case of successful auth.
615 login_performer_->set_delegate(NULL);
616 ignore_result(login_performer_.release());
618 UserSessionManager::StartSessionType start_session_type =
619 UserAddingScreen::Get()->IsRunning()
620 ? UserSessionManager::SECONDARY_USER_SESSION
621 : UserSessionManager::PRIMARY_USER_SESSION;
622 UserSessionManager::GetInstance()->StartSession(
623 user_context, start_session_type, has_auth_cookies,
624 false, // Start session for user.
625 this);
627 // Update user's displayed email.
628 if (!display_email_.empty()) {
629 user_manager::UserManager::Get()->SaveUserDisplayEmail(
630 user_context.GetUserID(), display_email_);
631 display_email_.clear();
635 void ExistingUserController::OnProfilePrepared(Profile* profile,
636 bool browser_launched) {
637 // Reenable clicking on other windows and status area.
638 login_display_->SetUIEnabled(true);
640 if (browser_launched)
641 host_ = NULL;
643 // Inform |auth_status_consumer_| about successful login.
644 // TODO(nkostylev): Pass UserContext back crbug.com/424550
645 if (auth_status_consumer_) {
646 auth_status_consumer_->
647 OnAuthSuccess(UserContext(last_login_attempt_username_));
651 void ExistingUserController::OnOffTheRecordAuthSuccess() {
652 is_login_in_progress_ = false;
654 // Mark the device as registered., i.e. the second part of OOBE as completed.
655 if (!StartupUtils::IsDeviceRegistered())
656 StartupUtils::MarkDeviceRegistered(base::Closure());
658 UserSessionManager::GetInstance()->CompleteGuestSessionLogin(guest_mode_url_);
660 if (auth_status_consumer_)
661 auth_status_consumer_->OnOffTheRecordAuthSuccess();
664 void ExistingUserController::OnPasswordChangeDetected() {
665 is_login_in_progress_ = false;
667 // Must not proceed without signature verification.
668 if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
669 base::Bind(&ExistingUserController::OnPasswordChangeDetected,
670 weak_factory_.GetWeakPtr()))) {
671 // Value of owner email is still not verified.
672 // Another attempt will be invoked after verification completion.
673 return;
676 if (ChromeUserManager::Get()
677 ->GetUserFlow(last_login_attempt_username_)
678 ->HandlePasswordChangeDetected()) {
679 return;
682 // True if user has already made an attempt to enter old password and failed.
683 bool show_invalid_old_password_error =
684 login_performer_->password_changed_callback_count() > 1;
686 // Note: We allow owner using "full sync" mode which will recreate
687 // cryptohome and deal with owner private key being lost. This also allows
688 // us to recover from a lost owner password/homedir.
689 // TODO(gspencer): We shouldn't have to erase stateful data when
690 // doing this. See http://crosbug.com/9115 http://crosbug.com/7792
691 login_display_->ShowPasswordChangedDialog(show_invalid_old_password_error,
692 display_email_);
694 if (auth_status_consumer_)
695 auth_status_consumer_->OnPasswordChangeDetected();
697 display_email_.clear();
700 void ExistingUserController::WhiteListCheckFailed(const std::string& email) {
701 PerformLoginFinishedActions(true /* start public session timer */);
703 login_display_->ShowWhitelistCheckFailedError();
705 if (auth_status_consumer_) {
706 auth_status_consumer_->OnAuthFailure(
707 AuthFailure(AuthFailure::WHITELIST_CHECK_FAILED));
710 display_email_.clear();
713 void ExistingUserController::PolicyLoadFailed() {
714 ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, "");
716 PerformLoginFinishedActions(false /* don't start public session timer */);
717 display_email_.clear();
720 ////////////////////////////////////////////////////////////////////////////////
721 // ExistingUserController, private:
723 void ExistingUserController::DeviceSettingsChanged() {
724 // If login was already completed, we should avoid any signin screen
725 // transitions, see http://crbug.com/461604 for example.
726 if (host_ != NULL && !login_display_->is_signin_completed()) {
727 // Signed settings or user list changed. Notify views and update them.
728 UpdateLoginDisplay(user_manager::UserManager::Get()->GetUsers());
729 ConfigurePublicSessionAutoLogin();
733 LoginPerformer::AuthorizationMode ExistingUserController::auth_mode() const {
734 if (login_performer_)
735 return login_performer_->auth_mode();
737 return auth_mode_;
740 bool ExistingUserController::password_changed() const {
741 if (login_performer_)
742 return login_performer_->password_changed();
744 return password_changed_;
747 void ExistingUserController::LoginAsGuest() {
748 PerformPreLoginActions(UserContext(user_manager::USER_TYPE_GUEST,
749 chromeos::login::kGuestUserName));
751 bool allow_guest;
752 cros_settings_->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
753 if (!allow_guest) {
754 // Disallowed. The UI should normally not show the guest session button.
755 LOG(ERROR) << "Guest login attempt when guest mode is disallowed.";
756 PerformLoginFinishedActions(true /* start public session timer */);
757 display_email_.clear();
758 return;
761 // Only one instance of LoginPerformer should exist at a time.
762 login_performer_.reset(NULL);
763 login_performer_.reset(new ChromeLoginPerformer(this));
764 login_performer_->LoginOffTheRecord();
765 SendAccessibilityAlert(
766 l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_OFFRECORD));
769 void ExistingUserController::LoginAsPublicSession(
770 const UserContext& user_context) {
771 PerformPreLoginActions(user_context);
773 // If there is no public account with the given user ID, logging in is not
774 // possible.
775 const user_manager::User* user =
776 user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
777 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
778 PerformLoginFinishedActions(true /* start public session timer */);
779 return;
782 UserContext new_user_context = user_context;
783 std::string locale = user_context.GetPublicSessionLocale();
784 if (locale.empty()) {
785 // When performing auto-login, no locale is chosen by the user. Check
786 // whether a list of recommended locales was set by policy. If so, use its
787 // first entry. Otherwise, |locale| will remain blank, indicating that the
788 // public session should use the current UI locale.
789 const policy::PolicyMap::Entry* entry = g_browser_process->platform_part()->
790 browser_policy_connector_chromeos()->
791 GetDeviceLocalAccountPolicyService()->
792 GetBrokerForUser(user_context.GetUserID())->core()->store()->
793 policy_map().Get(policy::key::kSessionLocales);
794 base::ListValue const* list = NULL;
795 if (entry &&
796 entry->level == policy::POLICY_LEVEL_RECOMMENDED &&
797 entry->value &&
798 entry->value->GetAsList(&list)) {
799 if (list->GetString(0, &locale))
800 new_user_context.SetPublicSessionLocale(locale);
804 if (!locale.empty() &&
805 new_user_context.GetPublicSessionInputMethod().empty()) {
806 // When |locale| is set, a suitable keyboard layout should be chosen. In
807 // most cases, this will already be the case because the UI shows a list of
808 // keyboard layouts suitable for the |locale| and ensures that one of them
809 // us selected. However, it is still possible that |locale| is set but no
810 // keyboard layout was chosen:
811 // * The list of keyboard layouts is updated asynchronously. If the user
812 // enters the public session before the list of keyboard layouts for the
813 // |locale| has been retrieved, the UI will indicate that no keyboard
814 // layout was chosen.
815 // * During auto-login, the |locale| is set in this method and a suitable
816 // keyboard layout must be chosen next.
818 // The list of suitable keyboard layouts is constructed asynchronously. Once
819 // it has been retrieved, |SetPublicSessionKeyboardLayoutAndLogin| will
820 // select the first layout from the list and continue login.
821 GetKeyboardLayoutsForLocale(
822 base::Bind(
823 &ExistingUserController::SetPublicSessionKeyboardLayoutAndLogin,
824 weak_factory_.GetWeakPtr(),
825 new_user_context),
826 locale);
827 return;
830 // The user chose a locale and a suitable keyboard layout or left both unset.
831 // Login can continue immediately.
832 LoginAsPublicSessionInternal(new_user_context);
835 void ExistingUserController::LoginAsKioskApp(const std::string& app_id,
836 bool diagnostic_mode) {
837 const bool auto_start = false;
838 host_->StartAppLaunch(app_id, diagnostic_mode, auto_start);
841 void ExistingUserController::ConfigurePublicSessionAutoLogin() {
842 std::string auto_login_account_id;
843 cros_settings_->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
844 &auto_login_account_id);
845 const std::vector<policy::DeviceLocalAccount> device_local_accounts =
846 policy::GetDeviceLocalAccounts(cros_settings_);
848 public_session_auto_login_username_.clear();
849 for (std::vector<policy::DeviceLocalAccount>::const_iterator
850 it = device_local_accounts.begin();
851 it != device_local_accounts.end(); ++it) {
852 if (it->account_id == auto_login_account_id) {
853 public_session_auto_login_username_ = it->user_id;
854 break;
858 const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
859 public_session_auto_login_username_);
860 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
861 public_session_auto_login_username_.clear();
863 if (!cros_settings_->GetInteger(
864 kAccountsPrefDeviceLocalAccountAutoLoginDelay,
865 &public_session_auto_login_delay_)) {
866 public_session_auto_login_delay_ = 0;
869 if (!public_session_auto_login_username_.empty())
870 StartPublicSessionAutoLoginTimer();
871 else
872 StopPublicSessionAutoLoginTimer();
875 void ExistingUserController::ResetPublicSessionAutoLoginTimer() {
876 // Only restart the auto-login timer if it's already running.
877 if (auto_login_timer_ && auto_login_timer_->IsRunning()) {
878 StopPublicSessionAutoLoginTimer();
879 StartPublicSessionAutoLoginTimer();
883 void ExistingUserController::OnPublicSessionAutoLoginTimerFire() {
884 CHECK(signin_screen_ready_ && !public_session_auto_login_username_.empty());
885 Login(UserContext(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
886 public_session_auto_login_username_),
887 SigninSpecifics());
890 void ExistingUserController::StopPublicSessionAutoLoginTimer() {
891 if (auto_login_timer_)
892 auto_login_timer_->Stop();
895 void ExistingUserController::StartPublicSessionAutoLoginTimer() {
896 if (!signin_screen_ready_ ||
897 is_login_in_progress_ ||
898 public_session_auto_login_username_.empty()) {
899 return;
902 // Start the auto-login timer.
903 if (!auto_login_timer_)
904 auto_login_timer_.reset(new base::OneShotTimer<ExistingUserController>);
906 auto_login_timer_->Start(
907 FROM_HERE,
908 base::TimeDelta::FromMilliseconds(
909 public_session_auto_login_delay_),
910 base::Bind(
911 &ExistingUserController::OnPublicSessionAutoLoginTimerFire,
912 weak_factory_.GetWeakPtr()));
915 gfx::NativeWindow ExistingUserController::GetNativeWindow() const {
916 return host_->GetNativeWindow();
919 void ExistingUserController::ShowError(int error_id,
920 const std::string& details) {
921 VLOG(1) << details;
922 HelpAppLauncher::HelpTopic help_topic_id;
923 if (login_performer_) {
924 switch (login_performer_->error().state()) {
925 case GoogleServiceAuthError::ACCOUNT_DISABLED:
926 help_topic_id = HelpAppLauncher::HELP_ACCOUNT_DISABLED;
927 break;
928 case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
929 help_topic_id = HelpAppLauncher::HELP_HOSTED_ACCOUNT;
930 break;
931 default:
932 help_topic_id = HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT;
933 break;
935 } else {
936 // login_performer_ will be null if an error occurred during OAuth2 token
937 // fetch. In this case, show a generic error.
938 help_topic_id = HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT;
941 if (error_id == IDS_LOGIN_ERROR_AUTHENTICATING) {
942 if (num_login_attempts_ > 1) {
943 const user_manager::User* user =
944 user_manager::UserManager::Get()->FindUser(
945 last_login_attempt_username_);
946 if (user && (user->GetType() == user_manager::USER_TYPE_SUPERVISED))
947 error_id = IDS_LOGIN_ERROR_AUTHENTICATING_2ND_TIME_SUPERVISED;
951 login_display_->ShowError(error_id, num_login_attempts_, help_topic_id);
954 void ExistingUserController::SendAccessibilityAlert(
955 const std::string& alert_text) {
956 AutomationManagerAura::GetInstance()->HandleAlert(
957 ProfileHelper::GetSigninProfile(), alert_text);
960 void ExistingUserController::SetPublicSessionKeyboardLayoutAndLogin(
961 const UserContext& user_context,
962 scoped_ptr<base::ListValue> keyboard_layouts) {
963 UserContext new_user_context = user_context;
964 std::string keyboard_layout;
965 for (size_t i = 0; i < keyboard_layouts->GetSize(); ++i) {
966 base::DictionaryValue* entry = NULL;
967 keyboard_layouts->GetDictionary(i, &entry);
968 bool selected = false;
969 entry->GetBoolean("selected", &selected);
970 if (selected) {
971 entry->GetString("value", &keyboard_layout);
972 break;
975 DCHECK(!keyboard_layout.empty());
976 new_user_context.SetPublicSessionInputMethod(keyboard_layout);
978 LoginAsPublicSessionInternal(new_user_context);
981 void ExistingUserController::LoginAsPublicSessionInternal(
982 const UserContext& user_context) {
983 // Only one instance of LoginPerformer should exist at a time.
984 login_performer_.reset(NULL);
985 login_performer_.reset(new ChromeLoginPerformer(this));
986 login_performer_->LoginAsPublicSession(user_context);
987 SendAccessibilityAlert(
988 l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_PUBLIC_ACCOUNT));
991 void ExistingUserController::PerformPreLoginActions(
992 const UserContext& user_context) {
993 // Disable clicking on other windows and status tray.
994 login_display_->SetUIEnabled(false);
996 if (last_login_attempt_username_ != user_context.GetUserID()) {
997 last_login_attempt_username_ = user_context.GetUserID();
998 num_login_attempts_ = 0;
1001 // Guard in cases when we're called twice but login process is still active.
1002 // This might happen when login process is paused till signed settings status
1003 // is verified which results in Login* method called again as a callback.
1004 if (!is_login_in_progress_)
1005 num_login_attempts_++;
1007 is_login_in_progress_ = true;
1009 // Stop the auto-login timer when attempting login.
1010 StopPublicSessionAutoLoginTimer();
1013 void ExistingUserController::PerformLoginFinishedActions(
1014 bool start_public_session_timer) {
1015 is_login_in_progress_ = false;
1017 // Reenable clicking on other windows and status area.
1018 login_display_->SetUIEnabled(true);
1020 if (start_public_session_timer)
1021 StartPublicSessionAutoLoginTimer();
1024 void ExistingUserController::ContinueLoginIfDeviceNotDisabled(
1025 const base::Closure& continuation) {
1026 // Disable clicking on other windows and status tray.
1027 login_display_->SetUIEnabled(false);
1029 // Stop the auto-login timer.
1030 StopPublicSessionAutoLoginTimer();
1032 // Wait for the |cros_settings_| to become either trusted or permanently
1033 // untrusted.
1034 const CrosSettingsProvider::TrustedStatus status =
1035 cros_settings_->PrepareTrustedValues(base::Bind(
1036 &ExistingUserController::ContinueLoginIfDeviceNotDisabled,
1037 weak_factory_.GetWeakPtr(),
1038 continuation));
1039 if (status == CrosSettingsProvider::TEMPORARILY_UNTRUSTED)
1040 return;
1042 if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
1043 // If the |cros_settings_| are permanently untrusted, show an error message
1044 // and refuse to log in.
1045 login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST,
1047 HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
1049 // Re-enable clicking on other windows and the status area. Do not start the
1050 // auto-login timer though. Without trusted |cros_settings_|, no auto-login
1051 // can succeed.
1052 login_display_->SetUIEnabled(true);
1053 return;
1056 bool device_disabled = false;
1057 cros_settings_->GetBoolean(kDeviceDisabled, &device_disabled);
1058 if (device_disabled && system::DeviceDisablingManager::
1059 HonorDeviceDisablingDuringNormalOperation()) {
1060 // If the device is disabled, bail out. A device disabled screen will be
1061 // shown by the DeviceDisablingManager.
1063 // Re-enable clicking on other windows and the status area. Do not start the
1064 // auto-login timer though. On a disabled device, no auto-login can succeed.
1065 login_display_->SetUIEnabled(true);
1066 return;
1069 continuation.Run();
1072 void ExistingUserController::DoCompleteLogin(
1073 const UserContext& user_context_wo_device_id) {
1074 UserContext user_context = user_context_wo_device_id;
1075 std::string device_id =
1076 user_manager::UserManager::Get()->GetKnownUserDeviceId(
1077 user_context.GetUserID());
1078 if (device_id.empty()) {
1079 bool is_ephemeral =
1080 ChromeUserManager::Get()->AreEphemeralUsersEnabled() &&
1081 user_context.GetUserID() != ChromeUserManager::Get()->GetOwnerEmail();
1082 device_id = SigninClient::GenerateSigninScopedDeviceID(is_ephemeral);
1084 user_context.SetDeviceId(device_id);
1086 const std::string& gaps_cookie = user_context.GetGAPSCookie();
1087 if (!gaps_cookie.empty()) {
1088 user_manager::UserManager::Get()->SetKnownUserGAPSCookie(
1089 user_context.GetUserID(), gaps_cookie);
1092 PerformPreLoginActions(user_context);
1094 if (!time_init_.is_null()) {
1095 base::TimeDelta delta = base::Time::Now() - time_init_;
1096 UMA_HISTOGRAM_MEDIUM_TIMES("Login.PromptToCompleteLoginTime", delta);
1097 time_init_ = base::Time(); // Reset to null.
1100 host_->OnCompleteLogin();
1102 if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_EASY_BOOTSTRAP) {
1103 bootstrap_user_context_initializer_.reset(
1104 new BootstrapUserContextInitializer());
1105 bootstrap_user_context_initializer_->Start(
1106 user_context.GetAuthCode(),
1107 base::Bind(&ExistingUserController::OnBootstrapUserContextInitialized,
1108 weak_factory_.GetWeakPtr()));
1109 return;
1112 // Fetch OAuth2 tokens if we have an auth code and are not using SAML.
1113 // SAML uses cookies to get tokens.
1114 if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML &&
1115 !user_context.GetAuthCode().empty()) {
1116 oauth2_token_initializer_.reset(new OAuth2TokenInitializer);
1117 oauth2_token_initializer_->Start(
1118 user_context, base::Bind(&ExistingUserController::OnOAuth2TokensFetched,
1119 weak_factory_.GetWeakPtr()));
1120 return;
1123 PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
1126 void ExistingUserController::DoLogin(const UserContext& user_context,
1127 const SigninSpecifics& specifics) {
1128 if (is_login_in_progress_) {
1129 // If there is another login in progress, bail out. Do not re-enable
1130 // clicking on other windows and the status area. Do not start the
1131 // auto-login timer.
1132 return;
1135 if (user_context.GetUserType() != user_manager::USER_TYPE_REGULAR &&
1136 user_manager::UserManager::Get()->IsUserLoggedIn()) {
1137 // Multi-login is only allowed for regular users. If we are attempting to
1138 // do multi-login as another type of user somehow, bail out. Do not
1139 // re-enable clicking on other windows and the status area. Do not start the
1140 // auto-login timer.
1141 return;
1144 if (user_context.GetUserType() == user_manager::USER_TYPE_GUEST) {
1145 if (!specifics.guest_mode_url.empty()) {
1146 guest_mode_url_ = GURL(specifics.guest_mode_url);
1147 if (specifics.guest_mode_url_append_locale)
1148 guest_mode_url_ = google_util::AppendGoogleLocaleParam(
1149 guest_mode_url_, g_browser_process->GetApplicationLocale());
1151 LoginAsGuest();
1152 return;
1155 if (user_context.GetUserType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
1156 LoginAsPublicSession(user_context);
1157 return;
1160 if (user_context.GetUserType() == user_manager::USER_TYPE_KIOSK_APP) {
1161 LoginAsKioskApp(user_context.GetUserID(), specifics.kiosk_diagnostic_mode);
1162 return;
1165 // Regular user or supervised user login.
1167 if (!user_context.HasCredentials()) {
1168 // If credentials are missing, refuse to log in.
1170 // Reenable clicking on other windows and status area.
1171 login_display_->SetUIEnabled(true);
1172 // Restart the auto-login timer.
1173 StartPublicSessionAutoLoginTimer();
1176 PerformPreLoginActions(user_context);
1177 PerformLogin(user_context, LoginPerformer::AUTH_MODE_INTERNAL);
1180 void ExistingUserController::OnBootstrapUserContextInitialized(
1181 bool success,
1182 const UserContext& user_context) {
1183 if (!success) {
1184 LOG(ERROR) << "Easy bootstrap failed.";
1185 OnAuthFailure(AuthFailure(AuthFailure::NETWORK_AUTH_FAILED));
1186 return;
1189 // Setting a customized login user flow to perform additional initializations
1190 // for bootstrap after the user session is started.
1191 ChromeUserManager::Get()->SetUserFlow(
1192 user_context.GetUserID(),
1193 new BootstrapUserFlow(
1194 user_context,
1195 bootstrap_user_context_initializer_->random_key_used()));
1197 PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
1200 void ExistingUserController::OnOAuth2TokensFetched(
1201 bool success,
1202 const UserContext& user_context) {
1203 if (!success) {
1204 LOG(ERROR) << "OAuth2 token fetch failed.";
1205 OnAuthFailure(AuthFailure(AuthFailure::FAILED_TO_INITIALIZE_TOKEN));
1206 return;
1208 UserSessionManager::GetInstance()->OnOAuth2TokensFetched(user_context);
1209 PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
1212 } // namespace chromeos