login_utils.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
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. 4 5#include "chrome/browser/chromeos/login/login_utils.h" 6 7#include <algorithm> 8#include <vector> 9 10#include "base/chromeos/chromeos_version.h" 11#include "base/command_line.h" 12#include "base/compiler_specific.h" 13#include "base/file_util.h" 14#include "base/files/file_path.h" 15#include "base/location.h" 16#include "base/memory/ref_counted.h" 17#include "base/memory/scoped_ptr.h" 18#include "base/memory/singleton.h" 19#include "base/memory/weak_ptr.h" 20#include "base/path_service.h" 21#include "base/prefs/pref_member.h" 22#include "base/prefs/pref_registry_simple.h" 23#include "base/prefs/pref_service.h" 24#include "base/strings/string_util.h" 25#include "base/strings/utf_string_conversions.h" 26#include "base/synchronization/lock.h" 27#include "base/task_runner_util.h" 28#include "base/threading/worker_pool.h" 29#include "base/time.h" 30#include "chrome/browser/about_flags.h" 31#include "chrome/browser/app_mode/app_mode_utils.h" 32#include "chrome/browser/browser_process.h" 33#include "chrome/browser/browser_shutdown.h" 34#include "chrome/browser/chromeos/boot_times_loader.h" 35#include "chrome/browser/chromeos/input_method/input_method_util.h" 36#include "chrome/browser/chromeos/login/chrome_restart_request.h" 37#include "chrome/browser/chromeos/login/language_switch_menu.h" 38#include "chrome/browser/chromeos/login/login_display_host.h" 39#include "chrome/browser/chromeos/login/oauth_login_manager.h" 40#include "chrome/browser/chromeos/login/parallel_authenticator.h" 41#include "chrome/browser/chromeos/login/profile_auth_data.h" 42#include "chrome/browser/chromeos/login/screen_locker.h" 43#include "chrome/browser/chromeos/login/user_manager.h" 44#include "chrome/browser/chromeos/settings/cros_settings.h" 45#include "chrome/browser/chromeos/settings/cros_settings_names.h" 46#include "chrome/browser/extensions/extension_service.h" 47#include "chrome/browser/first_run/first_run.h" 48#include "chrome/browser/google/google_util_chromeos.h" 49#include "chrome/browser/lifetime/application_lifetime.h" 50#include "chrome/browser/managed_mode/managed_mode.h" 51#include "chrome/browser/pref_service_flags_storage.h" 52#include "chrome/browser/profiles/profile.h" 53#include "chrome/browser/profiles/profile_manager.h" 54#include "chrome/browser/rlz/rlz.h" 55#include "chrome/browser/signin/signin_manager.h" 56#include "chrome/browser/signin/signin_manager_factory.h" 57#include "chrome/browser/signin/token_service.h" 58#include "chrome/browser/signin/token_service_factory.h" 59#include "chrome/browser/sync/profile_sync_service.h" 60#include "chrome/browser/sync/profile_sync_service_factory.h" 61#include "chrome/browser/ui/startup/startup_browser_creator.h" 62#include "chrome/common/chrome_notification_types.h" 63#include "chrome/common/chrome_paths.h" 64#include "chrome/common/chrome_switches.h" 65#include "chrome/common/logging_chrome.h" 66#include "chrome/common/pref_names.h" 67#include "chromeos/chromeos_switches.h" 68#include "chromeos/cryptohome/cryptohome_library.h" 69#include "chromeos/dbus/dbus_thread_manager.h" 70#include "chromeos/dbus/session_manager_client.h" 71#include "chromeos/ime/input_method_manager.h" 72#include "content/public/browser/browser_thread.h" 73#include "content/public/browser/notification_service.h" 74#include "google_apis/gaia/gaia_auth_consumer.h" 75#include "googleurl/src/gurl.h" 76#include "net/base/network_change_notifier.h" 77#include "net/url_request/url_request_context.h" 78#include "net/url_request/url_request_context_getter.h" 79 80using content::BrowserThread; 81 82namespace chromeos { 83 84namespace { 85 86#if defined(ENABLE_RLZ) 87// Flag file that disables RLZ tracking, when present. 88const base::FilePath::CharType kRLZDisabledFlagName[] = 89 FILE_PATH_LITERAL(".rlz_disabled"); 90 91base::FilePath GetRlzDisabledFlagPath() { 92 return file_util::GetHomeDir().Append(kRLZDisabledFlagName); 93} 94#endif 95 96} // namespace 97 98class LoginUtilsImpl 99 : public LoginUtils, 100 public OAuthLoginManager::Delegate, 101 public net::NetworkChangeNotifier::ConnectionTypeObserver, 102 public base::SupportsWeakPtr<LoginUtilsImpl> { 103 public: 104 LoginUtilsImpl() 105 : using_oauth_(false), 106 has_web_auth_cookies_(false), 107 login_manager_(OAuthLoginManager::Create(this)), 108 delegate_(NULL), 109 should_restore_auth_session_(false), 110 session_restore_strategy_( 111 OAuthLoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN) { 112 net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 113 } 114 115 virtual ~LoginUtilsImpl() { 116 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 117 } 118 119 // LoginUtils implementation: 120 virtual void DoBrowserLaunch(Profile* profile, 121 LoginDisplayHost* login_host) OVERRIDE; 122 virtual void PrepareProfile( 123 const UserContext& user_context, 124 const std::string& display_email, 125 bool using_oauth, 126 bool has_cookies, 127 bool has_active_session, 128 LoginUtils::Delegate* delegate) OVERRIDE; 129 virtual void DelegateDeleted(LoginUtils::Delegate* delegate) OVERRIDE; 130 virtual void CompleteOffTheRecordLogin(const GURL& start_url) OVERRIDE; 131 virtual void SetFirstLoginPrefs(PrefService* prefs) OVERRIDE; 132 virtual scoped_refptr<Authenticator> CreateAuthenticator( 133 LoginStatusConsumer* consumer) OVERRIDE; 134 virtual void RestoreAuthenticationSession(Profile* profile) OVERRIDE; 135 virtual void StopBackgroundFetchers() OVERRIDE; 136 virtual void InitRlzDelayed(Profile* user_profile) OVERRIDE; 137 138 // OAuthLoginManager::Delegate overrides. 139 virtual void OnCompletedMergeSession() OVERRIDE; 140 virtual void OnCompletedAuthentication(Profile* user_profile) OVERRIDE; 141 virtual void OnFoundStoredTokens() OVERRIDE; 142 143 // net::NetworkChangeNotifier::ConnectionTypeObserver overrides. 144 virtual void OnConnectionTypeChanged( 145 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE; 146 147 private: 148 // Restarts OAuth session authentication check. 149 void KickStartAuthentication(Profile* profile); 150 151 // Check user's profile for kApplicationLocale setting. 152 void RespectLocalePreference(Profile* pref); 153 154 // Callback for Profile::CREATE_STATUS_CREATED profile state. 155 // Initializes basic preferences for newly created profile. Any other 156 // early profile initialization that needs to happen before 157 // ProfileManager::DoFinalInit() gets called is done here. 158 void InitProfilePreferences(Profile* user_profile); 159 160 // Callback for asynchronous profile creation. 161 void OnProfileCreated(Profile* profile, 162 Profile::CreateStatus status); 163 164 // Callback for Profile::CREATE_STATUS_INITIALIZED profile state. 165 // Profile is created, extensions and promo resources are initialized. 166 void UserProfileInitialized(Profile* user_profile); 167 168 // Callback to resume profile creation after transferring auth data from 169 // the authentication profile. 170 void CompleteProfileCreate(Profile* user_profile); 171 172 // Finalized profile preparation. 173 void FinalizePrepareProfile(Profile* user_profile); 174 175 // Initializes member variables needed for session restore process via 176 // OAuthLoginManager. 177 void InitSessionRestoreStrategy(); 178 179 // Restores GAIA auth cookies for the created user profile from OAuth2 token. 180 void RestoreAuthSession(Profile* user_profile, 181 bool restore_from_auth_cookies); 182 183 // Callback when managed mode preferences have been applied. 184 void EnteredManagedMode(bool success); 185 186 // Initializes RLZ. If |disabled| is true, RLZ pings are disabled. 187 void InitRlz(Profile* user_profile, bool disabled); 188 189 // Starts signing related services. Initiates TokenService token retrieval. 190 void StartSignedInServices(Profile* profile); 191 192 UserContext user_context_; 193 bool using_oauth_; 194 // True if the authentication profile's cookie jar should contain 195 // authentication cookies from the authentication extension log in flow. 196 bool has_web_auth_cookies_; 197 // Has to be scoped_refptr, see comment for CreateAuthenticator(...). 198 scoped_refptr<Authenticator> authenticator_; 199 scoped_ptr<OAuthLoginManager> login_manager_; 200 201 // Delegate to be fired when the profile will be prepared. 202 LoginUtils::Delegate* delegate_; 203 204 // True if should restore authentication session when notified about 205 // online state change. 206 bool should_restore_auth_session_; 207 208 // Sesion restore strategy. 209 OAuthLoginManager::SessionRestoreStrategy session_restore_strategy_; 210 // OAuth2 refresh token for session restore. 211 std::string oauth2_refresh_token_; 212 213 DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl); 214}; 215 216class LoginUtilsWrapper { 217 public: 218 static LoginUtilsWrapper* GetInstance() { 219 return Singleton<LoginUtilsWrapper>::get(); 220 } 221 222 LoginUtils* get() { 223 base::AutoLock create(create_lock_); 224 if (!ptr_.get()) 225 reset(new LoginUtilsImpl); 226 return ptr_.get(); 227 } 228 229 void reset(LoginUtils* ptr) { 230 ptr_.reset(ptr); 231 } 232 233 private: 234 friend struct DefaultSingletonTraits<LoginUtilsWrapper>; 235 236 LoginUtilsWrapper() {} 237 238 base::Lock create_lock_; 239 scoped_ptr<LoginUtils> ptr_; 240 241 DISALLOW_COPY_AND_ASSIGN(LoginUtilsWrapper); 242}; 243 244void LoginUtilsImpl::DoBrowserLaunch(Profile* profile, 245 LoginDisplayHost* login_host) { 246 if (browser_shutdown::IsTryingToQuit()) 247 return; 248 249 if (!UserManager::Get()->GetCurrentUserFlow()->ShouldLaunchBrowser()) { 250 UserManager::Get()->GetCurrentUserFlow()->LaunchExtraSteps(profile); 251 return; 252 } 253 254 CommandLine user_flags(CommandLine::NO_PROGRAM); 255 about_flags::PrefServiceFlagsStorage flags_storage_(profile->GetPrefs()); 256 about_flags::ConvertFlagsToSwitches(&flags_storage_, &user_flags); 257 if (!about_flags::AreSwitchesIdenticalToCurrentCommandLine( 258 user_flags, *CommandLine::ForCurrentProcess())) { 259 CommandLine::StringVector flags; 260 // argv[0] is the program name |CommandLine::NO_PROGRAM|. 261 flags.assign(user_flags.argv().begin() + 1, user_flags.argv().end()); 262 VLOG(1) << "Restarting to apply per-session flags..."; 263 DBusThreadManager::Get()->GetSessionManagerClient()->SetFlagsForUser( 264 UserManager::Get()->GetActiveUser()->email(), flags); 265 chrome::ExitCleanly(); 266 return; 267 } 268 269 if (login_host) { 270 login_host->SetStatusAreaVisible(true); 271 login_host->BeforeSessionStart(); 272 } 273 274 BootTimesLoader::Get()->AddLoginTimeMarker("BrowserLaunched", false); 275 276 VLOG(1) << "Launching browser..."; 277 StartupBrowserCreator browser_creator; 278 int return_code; 279 chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? 280 chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; 281 282 browser_creator.LaunchBrowser(*CommandLine::ForCurrentProcess(), 283 profile, 284 base::FilePath(), 285 chrome::startup::IS_PROCESS_STARTUP, 286 first_run, 287 &return_code); 288 289 // Mark login host for deletion after browser starts. This 290 // guarantees that the message loop will be referenced by the 291 // browser before it is dereferenced by the login host. 292 if (login_host) 293 login_host->Finalize(); 294 UserManager::Get()->SessionStarted(); 295} 296 297void LoginUtilsImpl::PrepareProfile( 298 const UserContext& user_context, 299 const std::string& display_email, 300 bool using_oauth, 301 bool has_cookies, 302 bool has_active_session, 303 LoginUtils::Delegate* delegate) { 304 BootTimesLoader* btl = BootTimesLoader::Get(); 305 306 VLOG(1) << "Completing login for " << user_context.username; 307 308 if (!has_active_session) { 309 btl->AddLoginTimeMarker("StartSession-Start", false); 310 DBusThreadManager::Get()->GetSessionManagerClient()->StartSession( 311 user_context.username); 312 btl->AddLoginTimeMarker("StartSession-End", false); 313 } 314 315 btl->AddLoginTimeMarker("UserLoggedIn-Start", false); 316 UserManager* user_manager = UserManager::Get(); 317 user_manager->UserLoggedIn(user_context.username, 318 user_context.username_hash, 319 false); 320 btl->AddLoginTimeMarker("UserLoggedIn-End", false); 321 322 // Switch log file as soon as possible. 323 if (base::chromeos::IsRunningOnChromeOS()) 324 logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess())); 325 326 // Update user's displayed email. 327 if (!display_email.empty()) 328 user_manager->SaveUserDisplayEmail(user_context.username, display_email); 329 330 user_context_ = user_context; 331 332 using_oauth_ = using_oauth; 333 has_web_auth_cookies_ = has_cookies; 334 delegate_ = delegate; 335 InitSessionRestoreStrategy(); 336 337 // The default profile will have been changed because the ProfileManager 338 // will process the notification that the UserManager sends out so 339 // username_hash has been already propogated to ProfileManager. 340 ProfileManager::CreateDefaultProfileAsync( 341 base::Bind(&LoginUtilsImpl::OnProfileCreated, AsWeakPtr())); 342} 343 344void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) { 345 if (delegate_ == delegate) 346 delegate_ = NULL; 347} 348 349void LoginUtilsImpl::InitProfilePreferences(Profile* user_profile) { 350 if (UserManager::Get()->IsCurrentUserNew()) 351 SetFirstLoginPrefs(user_profile->GetPrefs()); 352 353 if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) { 354 user_profile->GetPrefs()->SetBoolean(prefs::kProfileIsManaged, true); 355 } else { 356 // Make sure that the google service username is properly set (we do this 357 // on every sign in, not just the first login, to deal with existing 358 // profiles that might not have it set yet). 359 StringPrefMember google_services_username; 360 google_services_username.Init(prefs::kGoogleServicesUsername, 361 user_profile->GetPrefs()); 362 google_services_username.SetValue( 363 UserManager::Get()->GetLoggedInUser()->display_email()); 364 } 365 366 // Make sure we flip every profile to not share proxies if the user hasn't 367 // specified so explicitly. 368 const PrefService::Preference* use_shared_proxies_pref = 369 user_profile->GetPrefs()->FindPreference(prefs::kUseSharedProxies); 370 if (use_shared_proxies_pref->IsDefaultValue()) 371 user_profile->GetPrefs()->SetBoolean(prefs::kUseSharedProxies, false); 372 373 RespectLocalePreference(user_profile); 374} 375 376void LoginUtilsImpl::InitSessionRestoreStrategy() { 377 CommandLine* command_line = CommandLine::ForCurrentProcess(); 378 bool in_app_mode = chrome::IsRunningInForcedAppMode(); 379 380 // Are we in kiosk app mode? 381 if (in_app_mode) { 382 if (command_line->HasSwitch(::switches::kAppModeOAuth2Token)) { 383 oauth2_refresh_token_ = command_line->GetSwitchValueASCII( 384 ::switches::kAppModeOAuth2Token); 385 } 386 387 if (command_line->HasSwitch(::switches::kAppModeAuthCode)) { 388 user_context_.auth_code = command_line->GetSwitchValueASCII( 389 ::switches::kAppModeAuthCode); 390 } 391 392 DCHECK(!has_web_auth_cookies_); 393 if (!user_context_.auth_code.empty()) { 394 session_restore_strategy_ = OAuthLoginManager::RESTORE_FROM_AUTH_CODE; 395 } else if (!oauth2_refresh_token_.empty()) { 396 session_restore_strategy_ = 397 OAuthLoginManager::RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN; 398 } else { 399 session_restore_strategy_ = 400 OAuthLoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; 401 } 402 return; 403 } 404 405 if (has_web_auth_cookies_) { 406 session_restore_strategy_ = OAuthLoginManager::RESTORE_FROM_COOKIE_JAR; 407 } else if (!user_context_.auth_code.empty()) { 408 session_restore_strategy_ = OAuthLoginManager::RESTORE_FROM_AUTH_CODE; 409 } else { 410 session_restore_strategy_ = 411 OAuthLoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; 412 } 413} 414 415 416void LoginUtilsImpl::OnProfileCreated( 417 Profile* user_profile, 418 Profile::CreateStatus status) { 419 CHECK(user_profile); 420 421 switch (status) { 422 case Profile::CREATE_STATUS_INITIALIZED: 423 UserProfileInitialized(user_profile); 424 break; 425 case Profile::CREATE_STATUS_CREATED: 426 InitProfilePreferences(user_profile); 427 break; 428 case Profile::CREATE_STATUS_LOCAL_FAIL: 429 case Profile::CREATE_STATUS_REMOTE_FAIL: 430 case Profile::CREATE_STATUS_CANCELED: 431 case Profile::MAX_CREATE_STATUS: 432 NOTREACHED(); 433 break; 434 } 435} 436 437void LoginUtilsImpl::UserProfileInitialized(Profile* user_profile) { 438 BootTimesLoader* btl = BootTimesLoader::Get(); 439 btl->AddLoginTimeMarker("UserProfileGotten", false); 440 441 if (using_oauth_) { 442 // Transfer proxy authentication cache, cookies (optionally) and server 443 // bound certs from the profile that was used for authentication. This 444 // profile contains cookies that auth extension should have already put in 445 // place that will ensure that the newly created session is authenticated 446 // for the websites that work with the used authentication schema. 447 ProfileAuthData::Transfer(authenticator_->authentication_profile(), 448 user_profile, 449 has_web_auth_cookies_, // transfer_cookies 450 base::Bind( 451 &LoginUtilsImpl::CompleteProfileCreate, 452 AsWeakPtr(), 453 user_profile)); 454 return; 455 } 456 457 if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) { 458 // Apply managed mode first. 459 ManagedMode::EnterManagedMode( 460 user_profile, 461 base::Bind(&LoginUtilsImpl::EnteredManagedMode, AsWeakPtr())); 462 } else { 463 FinalizePrepareProfile(user_profile); 464 } 465} 466 467void LoginUtilsImpl::EnteredManagedMode(bool success) { 468 // TODO(nkostylev): What if entering managed mode fails? 469 FinalizePrepareProfile(ProfileManager::GetDefaultProfile()); 470} 471 472void LoginUtilsImpl::CompleteProfileCreate(Profile* user_profile) { 473 RestoreAuthSession(user_profile, has_web_auth_cookies_); 474 FinalizePrepareProfile(user_profile); 475} 476 477void LoginUtilsImpl::RestoreAuthSession(Profile* user_profile, 478 bool restore_from_auth_cookies) { 479 CHECK((authenticator_.get() && authenticator_->authentication_profile()) || 480 !restore_from_auth_cookies); 481 if (!login_manager_.get()) 482 return; 483 484 if (chrome::IsRunningInForcedAppMode()) 485 return; 486 487 UserManager::Get()->SetMergeSessionState( 488 UserManager::MERGE_STATUS_IN_PROCESS); 489 490 // Remove legacy OAuth1 token if we have one. If it's valid, we should already 491 // have OAuth2 refresh token in TokenService that could be used to retrieve 492 // all other tokens and user_context. 493 login_manager_->RestoreSession( 494 user_profile, 495 authenticator_.get() && authenticator_->authentication_profile() 496 ? authenticator_->authentication_profile()->GetRequestContext() 497 : NULL, 498 session_restore_strategy_, 499 oauth2_refresh_token_, 500 user_context_.auth_code); 501} 502 503void LoginUtilsImpl::FinalizePrepareProfile(Profile* user_profile) { 504 BootTimesLoader* btl = BootTimesLoader::Get(); 505 // Own TPM device if, for any reason, it has not been done in EULA 506 // wizard screen. 507 CryptohomeLibrary* cryptohome = CryptohomeLibrary::Get(); 508 btl->AddLoginTimeMarker("TPMOwn-Start", false); 509 if (cryptohome->TpmIsEnabled() && !cryptohome->TpmIsBeingOwned()) { 510 if (cryptohome->TpmIsOwned()) { 511 cryptohome->TpmClearStoredPassword(); 512 } else { 513 cryptohome->TpmCanAttemptOwnership(); 514 } 515 } 516 btl->AddLoginTimeMarker("TPMOwn-End", false); 517 518 user_profile->OnLogin(); 519 520 // Send the notification before creating the browser so additional objects 521 // that need the profile (e.g. the launcher) can be created first. 522 content::NotificationService::current()->Notify( 523 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, 524 content::NotificationService::AllSources(), 525 content::Details<Profile>(user_profile)); 526 527 InitRlzDelayed(user_profile); 528 529 // TODO(altimofeev): This pointer should probably never be NULL, but it looks 530 // like LoginUtilsImpl::OnProfileCreated() may be getting called before 531 // LoginUtilsImpl::PrepareProfile() has set |delegate_| when Chrome is killed 532 // during shutdown in tests -- see http://crosbug.com/18269. Replace this 533 // 'if' statement with a CHECK(delegate_) once the underlying issue is 534 // resolved. 535 if (delegate_) 536 delegate_->OnProfilePrepared(user_profile); 537} 538 539void LoginUtilsImpl::InitRlzDelayed(Profile* user_profile) { 540#if defined(ENABLE_RLZ) 541 if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) { 542 // Read brand code asynchronously from an OEM file and repost ourselves. 543 google_util::chromeos::SetBrandFromFile( 544 base::Bind(&LoginUtilsImpl::InitRlzDelayed, AsWeakPtr(), user_profile)); 545 return; 546 } 547 base::PostTaskAndReplyWithResult( 548 base::WorkerPool::GetTaskRunner(false), 549 FROM_HERE, 550 base::Bind(&file_util::PathExists, GetRlzDisabledFlagPath()), 551 base::Bind(&LoginUtilsImpl::InitRlz, AsWeakPtr(), user_profile)); 552#endif 553} 554 555void LoginUtilsImpl::InitRlz(Profile* user_profile, bool disabled) { 556#if defined(ENABLE_RLZ) 557 PrefService* local_state = g_browser_process->local_state(); 558 if (disabled) { 559 // Empty brand code means an organic install (no RLZ pings are sent). 560 google_util::chromeos::ClearBrandForCurrentSession(); 561 } 562 if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) { 563 // When switching to RLZ enabled/disabled state, clear all recorded events. 564 RLZTracker::ClearRlzState(); 565 local_state->SetBoolean(prefs::kRLZDisabled, disabled); 566 } 567 // Init the RLZ library. 568 int ping_delay = user_profile->GetPrefs()->GetInteger( 569 first_run::GetPingDelayPrefName().c_str()); 570 // Negative ping delay means to send ping immediately after a first search is 571 // recorded. 572 RLZTracker::InitRlzFromProfileDelayed( 573 user_profile, UserManager::Get()->IsCurrentUserNew(), 574 ping_delay < 0, base::TimeDelta::FromMilliseconds(abs(ping_delay))); 575 if (delegate_) 576 delegate_->OnRlzInitialized(user_profile); 577#endif 578} 579 580void LoginUtilsImpl::StartSignedInServices(Profile* user_profile) { 581 // Fetch/Create the SigninManager - this will cause the TokenService to load 582 // tokens for the currently signed-in user if the SigninManager hasn't 583 // already been initialized. 584 SigninManagerBase* signin = 585 SigninManagerFactory::GetForProfile(user_profile); 586 DCHECK(signin); 587 // Make sure SigninManager is connected to our current user (this should 588 // happen automatically because we set kGoogleServicesUsername in 589 // OnProfileCreated()). 590 DCHECK_EQ(UserManager::Get()->GetLoggedInUser()->display_email(), 591 signin->GetAuthenticatedUsername()); 592 static bool initialized = false; 593 if (!initialized) { 594 initialized = true; 595 // Notify the sync service that signin was successful. Note: Since the sync 596 // service is lazy-initialized, we need to make sure it has been created. 597 ProfileSyncService* sync_service = 598 ProfileSyncServiceFactory::GetInstance()->GetForProfile(user_profile); 599 // We may not always have a passphrase (for example, on a restart after a 600 // browser crash). Only notify the sync service if we have a passphrase, 601 // so it can do any required re-encryption. 602 if (!user_context_.password.empty() && sync_service) { 603 GoogleServiceSigninSuccessDetails details( 604 signin->GetAuthenticatedUsername(), 605 user_context_.password); 606 content::NotificationService::current()->Notify( 607 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, 608 content::Source<Profile>(user_profile), 609 content::Details<const GoogleServiceSigninSuccessDetails>(&details)); 610 } 611 } 612 user_context_.password.clear(); 613 user_context_.auth_code.clear(); 614} 615 616void LoginUtilsImpl::RespectLocalePreference(Profile* profile) { 617 DCHECK(profile != NULL); 618 PrefService* prefs = profile->GetPrefs(); 619 DCHECK(prefs != NULL); 620 if (g_browser_process == NULL) 621 return; 622 623 std::string pref_locale = prefs->GetString(prefs::kApplicationLocale); 624 if (pref_locale.empty()) 625 pref_locale = prefs->GetString(prefs::kApplicationLocaleBackup); 626 if (pref_locale.empty()) 627 pref_locale = g_browser_process->GetApplicationLocale(); 628 DCHECK(!pref_locale.empty()); 629 profile->ChangeAppLocale(pref_locale, Profile::APP_LOCALE_CHANGED_VIA_LOGIN); 630 // Here we don't enable keyboard layouts. Input methods are set up when 631 // the user first logs in. Then the user may customize the input methods. 632 // Hence changing input methods here, just because the user's UI language 633 // is different from the login screen UI language, is not desirable. Note 634 // that input method preferences are synced, so users can use their 635 // farovite input methods as soon as the preferences are synced. 636 LanguageSwitchMenu::SwitchLanguage(pref_locale); 637} 638 639void LoginUtilsImpl::CompleteOffTheRecordLogin(const GURL& start_url) { 640 VLOG(1) << "Completing incognito login"; 641 642 // For guest session we ask session manager to restart Chrome with --bwsi 643 // flag. We keep only some of the arguments of this process. 644 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); 645 CommandLine command_line(browser_command_line.GetProgram()); 646 std::string cmd_line_str = GetOffTheRecordCommandLine(start_url, 647 browser_command_line, 648 &command_line); 649 650 RestartChrome(cmd_line_str); 651} 652 653void LoginUtilsImpl::SetFirstLoginPrefs(PrefService* prefs) { 654 VLOG(1) << "Setting first login prefs"; 655 BootTimesLoader* btl = BootTimesLoader::Get(); 656 std::string locale = g_browser_process->GetApplicationLocale(); 657 658 // First, we'll set kLanguagePreloadEngines. 659 input_method::InputMethodManager* manager = 660 input_method::InputMethodManager::Get(); 661 std::vector<std::string> input_method_ids; 662 manager->GetInputMethodUtil()->GetFirstLoginInputMethodIds( 663 locale, manager->GetCurrentInputMethod(), &input_method_ids); 664 // Save the input methods in the user's preferences. 665 StringPrefMember language_preload_engines; 666 language_preload_engines.Init(prefs::kLanguagePreloadEngines, 667 prefs); 668 language_preload_engines.SetValue(JoinString(input_method_ids, ',')); 669 btl->AddLoginTimeMarker("IMEStarted", false); 670 671 // Second, we'll set kLanguagePreferredLanguages. 672 std::vector<std::string> language_codes; 673 // The current locale should be on the top. 674 language_codes.push_back(locale); 675 676 // Add input method IDs based on the input methods, as there may be 677 // input methods that are unrelated to the current locale. Example: the 678 // hardware keyboard layout xkb:us::eng is used for logging in, but the 679 // UI language is set to French. In this case, we should set "fr,en" 680 // to the preferred languages preference. 681 std::vector<std::string> candidates; 682 manager->GetInputMethodUtil()->GetLanguageCodesFromInputMethodIds( 683 input_method_ids, &candidates); 684 for (size_t i = 0; i < candidates.size(); ++i) { 685 const std::string& candidate = candidates[i]; 686 // Skip if it's already in language_codes. 687 if (std::count(language_codes.begin(), language_codes.end(), 688 candidate) == 0) { 689 language_codes.push_back(candidate); 690 } 691 } 692 // Save the preferred languages in the user's preferences. 693 StringPrefMember language_preferred_languages; 694 language_preferred_languages.Init(prefs::kLanguagePreferredLanguages, 695 prefs); 696 language_preferred_languages.SetValue(JoinString(language_codes, ',')); 697} 698 699scoped_refptr<Authenticator> LoginUtilsImpl::CreateAuthenticator( 700 LoginStatusConsumer* consumer) { 701 // Screen locker needs new Authenticator instance each time. 702 if (ScreenLocker::default_screen_locker()) { 703 if (authenticator_.get()) 704 authenticator_->SetConsumer(NULL); 705 authenticator_ = NULL; 706 } 707 708 if (authenticator_.get() == NULL) { 709 authenticator_ = new ParallelAuthenticator(consumer); 710 } else { 711 // TODO(nkostylev): Fix this hack by improving Authenticator dependencies. 712 authenticator_->SetConsumer(consumer); 713 } 714 return authenticator_; 715} 716 717void LoginUtilsImpl::RestoreAuthenticationSession(Profile* user_profile) { 718 // We don't need to restore session for demo/guest/stub/public account users. 719 if (!UserManager::Get()->IsUserLoggedIn() || 720 UserManager::Get()->IsLoggedInAsGuest() || 721 UserManager::Get()->IsLoggedInAsPublicAccount() || 722 UserManager::Get()->IsLoggedInAsDemoUser() || 723 UserManager::Get()->IsLoggedInAsStub()) { 724 return; 725 } 726 727 if (!net::NetworkChangeNotifier::IsOffline()) { 728 should_restore_auth_session_ = false; 729 RestoreAuthSession(user_profile, false); 730 } else { 731 // Even if we're online we should wait till initial 732 // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may 733 // end up cancelling all request when initial network connection type is 734 // processed. See http://crbug.com/121643. 735 should_restore_auth_session_ = true; 736 } 737} 738 739void LoginUtilsImpl::StopBackgroundFetchers() { 740 login_manager_.reset(); 741} 742 743void LoginUtilsImpl::OnCompletedAuthentication(Profile* user_profile) { 744 StartSignedInServices(user_profile); 745} 746 747void LoginUtilsImpl::OnCompletedMergeSession() { 748 UserManager::Get()->SetMergeSessionState(UserManager::MERGE_STATUS_DONE); 749} 750 751void LoginUtilsImpl::OnFoundStoredTokens() { 752 // We don't need authenticator instance any more since its cookie jar 753 // is not going to needed to mint OAuth tokens. Reset it so that 754 // ScreenLocker would create a separate instance. 755 authenticator_ = NULL; 756} 757 758void LoginUtilsImpl::OnConnectionTypeChanged( 759 net::NetworkChangeNotifier::ConnectionType type) { 760 if (!login_manager_.get()) 761 return; 762 763 if (type != net::NetworkChangeNotifier::CONNECTION_NONE && 764 UserManager::Get()->IsUserLoggedIn()) { 765 if (login_manager_->state() == 766 OAuthLoginManager::SESSION_RESTORE_IN_PROGRESS) { 767 // If we come online for the first time after successful offline login, 768 // we need to kick off OAuth token verification process again. 769 login_manager_->ContinueSessionRestore(); 770 } else if (should_restore_auth_session_) { 771 should_restore_auth_session_ = false; 772 Profile* user_profile = ProfileManager::GetDefaultProfile(); 773 RestoreAuthSession(user_profile, has_web_auth_cookies_); 774 } 775 } 776} 777 778// static 779void LoginUtils::RegisterPrefs(PrefRegistrySimple* registry) { 780 registry->RegisterBooleanPref(prefs::kFactoryResetRequested, false); 781 registry->RegisterStringPref(prefs::kRLZBrand, std::string()); 782 registry->RegisterBooleanPref(prefs::kRLZDisabled, false); 783} 784 785// static 786LoginUtils* LoginUtils::Get() { 787 return LoginUtilsWrapper::GetInstance()->get(); 788} 789 790// static 791void LoginUtils::Set(LoginUtils* mock) { 792 LoginUtilsWrapper::GetInstance()->reset(mock); 793} 794 795// static 796bool LoginUtils::IsWhitelisted(const std::string& username) { 797 CrosSettings* cros_settings = CrosSettings::Get(); 798 bool allow_new_user = false; 799 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); 800 if (allow_new_user) 801 return true; 802 return cros_settings->FindEmailInList(kAccountsPrefUsers, username); 803} 804 805} // namespace chromeos 806