login_utils.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/login/login_utils.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/bind.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/compiler_specific.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/location.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/ref_counted.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/singleton.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/weak_ptr.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/path_service.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_member.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/prefs/pref_registry_simple.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/prefs/pref_service.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/string_util.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/sys_info.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/task_runner_util.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/worker_pool.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/time/time.h" 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/about_flags.h" 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/browser_shutdown.h" 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/boot_times_loader.h" 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/input_method/input_method_util.h" 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/chrome_restart_request.h" 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/input_events_blocker.h" 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_display_host.h" 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/oauth2_login_manager.h" 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/oauth2_login_manager_factory.h" 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/parallel_authenticator.h" 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/profile_auth_data.h" 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h" 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory.h" 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/screen_locker.h" 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/startup_utils.h" 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/supervised_user_manager.h" 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/user.h" 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h" 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h" 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/first_run/first_run.h" 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/google/google_util_chromeos.h" 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/lifetime/application_lifetime.h" 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/pref_service_flags_storage.h" 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/rlz/rlz.h" 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/signin/signin_manager.h" 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h" 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service.h" 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_factory.h" 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/app_list/start_page_service.h" 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/ui/startup/startup_browser_creator.h" 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/logging_chrome.h" 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/chromeos_switches.h" 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/cryptohome/cryptohome_util.h" 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/cryptohome_client.h" 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_method_call_status.h" 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h" 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chromeos/dbus/session_manager_client.h" 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chromeos/ime/input_method_manager.h" 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chromeos/settings/cros_settings_names.h" 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/public/browser/notification_service.h" 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h" 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/base/network_change_notifier.h" 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/url_request/url_request_context.h" 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "url/gurl.h" 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)using content::BrowserThread; 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace chromeos { 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(ENABLE_RLZ) 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Flag file that disables RLZ tracking, when present. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kRLZDisabledFlagName[] = 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FILE_PATH_LITERAL(".rlz_disabled"); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)base::FilePath GetRlzDisabledFlagPath() { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::GetHomeDir().Append(kRLZDisabledFlagName); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct DoBrowserLaunchOnLocaleLoadedData; 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class LoginUtilsImpl 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public LoginUtils, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public OAuth2LoginManager::Observer, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public net::NetworkChangeNotifier::ConnectionTypeObserver, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::SupportsWeakPtr<LoginUtilsImpl> { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoginUtilsImpl() 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : has_web_auth_cookies_(false), 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delegate_(NULL), 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) exit_after_session_restore_(false), 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) session_restore_strategy_( 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN) { 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::NetworkChangeNotifier::AddConnectionTypeObserver(this); 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual ~LoginUtilsImpl() { 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this); 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // LoginUtils implementation: 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void DoBrowserLaunch(Profile* profile, 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LoginDisplayHost* login_host) OVERRIDE; 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void PrepareProfile( 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const UserContext& user_context, 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& display_email, 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool has_cookies, 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool has_active_session, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoginUtils::Delegate* delegate) OVERRIDE; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void DelegateDeleted(LoginUtils::Delegate* delegate) OVERRIDE; 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void CompleteOffTheRecordLogin(const GURL& start_url) OVERRIDE; 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void SetFirstLoginPrefs(PrefService* prefs) OVERRIDE; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual scoped_refptr<Authenticator> CreateAuthenticator( 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoginStatusConsumer* consumer) OVERRIDE; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void RestoreAuthenticationSession(Profile* profile) OVERRIDE; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void InitRlzDelayed(Profile* user_profile) OVERRIDE; 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // OAuth2LoginManager::Observer overrides. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnSessionRestoreStateChanged( 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* user_profile, 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OAuth2LoginManager::SessionRestoreState state) OVERRIDE; 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void OnNewRefreshTokenAvaiable(Profile* user_profile) OVERRIDE; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // net::NetworkChangeNotifier::ConnectionTypeObserver overrides. 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void OnConnectionTypeChanged( 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkChangeNotifier::ConnectionType type) OVERRIDE; 154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) typedef std::set<std::string> SessionRestoreStateSet; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // DoBrowserLaunch is split into two parts. 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // This one is called after anynchronous locale switch. 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void DoBrowserLaunchOnLocaleLoadedImpl(Profile* profile, 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LoginDisplayHost* login_host); 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Callback for locale_util::SwitchLanguage(). 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static void DoBrowserLaunchOnLocaleLoaded( 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<DoBrowserLaunchOnLocaleLoadedData> context, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& locale, 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& loaded_locale, 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const bool success); 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Restarts OAuth session authentication check. 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void KickStartAuthentication(Profile* profile); 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Callback for Profile::CREATE_STATUS_CREATED profile state. 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Initializes basic preferences for newly created profile. Any other 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // early profile initialization that needs to happen before 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // ProfileManager::DoFinalInit() gets called is done here. 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void InitProfilePreferences(Profile* user_profile, 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& email); 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Callback for asynchronous profile creation. 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void OnProfileCreated(const std::string& email, 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile, 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Profile::CreateStatus status); 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callback for asynchronous off the record profile creation. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnOTRProfileCreated(const std::string& email, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Profile::CreateStatus status); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Callback for Profile::CREATE_STATUS_INITIALIZED profile state. 191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Profile is created, extensions and promo resources are initialized. 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void UserProfileInitialized(Profile* user_profile); 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Callback for Profile::CREATE_STATUS_INITIALIZED profile state for an OTR 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // login. 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void OTRProfileInitialized(Profile* user_profile); 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Callback to resume profile creation after transferring auth data from 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // the authentication profile. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CompleteProfileCreate(Profile* user_profile); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Finalized profile preparation. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FinalizePrepareProfile(Profile* user_profile); 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Initializes member variables needed for session restore process via 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // OAuthLoginManager. 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void InitSessionRestoreStrategy(); 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Restores GAIA auth cookies for the created user profile from OAuth2 token. 210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void RestoreAuthSession(Profile* user_profile, 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool restore_from_auth_cookies); 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Initializes RLZ. If |disabled| is true, RLZ pings are disabled. 214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void InitRlz(Profile* user_profile, bool disabled); 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Attempts restarting the browser process and esures that this does 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // not happen while we are still fetching new OAuth refresh tokens. 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void AttemptRestart(Profile* profile); 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UserContext user_context_; 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // True if the authentication profile's cookie jar should contain 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // authentication cookies from the authentication extension log in flow. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool has_web_auth_cookies_; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Has to be scoped_refptr, see comment for CreateAuthenticator(...). 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<Authenticator> authenticator_; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delegate to be fired when the profile will be prepared. 229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LoginUtils::Delegate* delegate_; 230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set of user_id for those users that we should restore authentication 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // session when notified about online state change. 233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SessionRestoreStateSet pending_restore_sessions_; 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // True if we should restart chrome right after session restore. 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool exit_after_session_restore_; 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Sesion restore strategy. 239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) OAuth2LoginManager::SessionRestoreStrategy session_restore_strategy_; 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // OAuth2 refresh token for session restore. 241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string oauth2_refresh_token_; 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl); 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class LoginUtilsWrapper { 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static LoginUtilsWrapper* GetInstance() { 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return Singleton<LoginUtilsWrapper>::get(); 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoginUtils* get() { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock create(create_lock_); 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!ptr_.get()) 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) reset(new LoginUtilsImpl); 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return ptr_.get(); 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void reset(LoginUtils* ptr) { 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ptr_.reset(ptr); 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) friend struct DefaultSingletonTraits<LoginUtilsWrapper>; 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LoginUtilsWrapper() {} 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Lock create_lock_; 269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<LoginUtils> ptr_; 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(LoginUtilsWrapper); 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)struct DoBrowserLaunchOnLocaleLoadedData { 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DoBrowserLaunchOnLocaleLoadedData(LoginUtilsImpl* login_utils_impl, 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Profile* profile, 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LoginDisplayHost* display_host) 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : login_utils_impl(login_utils_impl), 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) profile(profile), 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) display_host(display_host) {} 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoginUtilsImpl* login_utils_impl; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile; 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::LoginDisplayHost* display_host; 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Block UI events untill ResourceBundle is reloaded. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InputEventsBlocker input_events_blocker; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginUtilsImpl::DoBrowserLaunchOnLocaleLoaded( 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<DoBrowserLaunchOnLocaleLoadedData> context, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& /* locale */, 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& /* loaded_locale */, 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const bool /* success */) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context->login_utils_impl->DoBrowserLaunchOnLocaleLoadedImpl( 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context->profile, context->display_host); 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called from DoBrowserLaunch() or from 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DoBrowserLaunchOnLocaleLoaded() depending on 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// if locale switch was needed. 303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void LoginUtilsImpl::DoBrowserLaunchOnLocaleLoadedImpl( 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Profile* profile, 305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LoginDisplayHost* login_host) { 306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!UserManager::Get()->GetCurrentUserFlow()->ShouldLaunchBrowser()) { 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) UserManager::Get()->GetCurrentUserFlow()->LaunchExtraSteps(profile); 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CommandLine user_flags(CommandLine::NO_PROGRAM); 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) about_flags::PrefServiceFlagsStorage flags_storage_(profile->GetPrefs()); 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) about_flags::ConvertFlagsToSwitches(&flags_storage_, &user_flags, 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) about_flags::kAddSentinels); 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Only restart if needed and if not going into managed mode. 316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Don't restart browser if it is not first profile in session. 317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (UserManager::Get()->GetLoggedInUsers().size() == 1 && 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !UserManager::Get()->IsLoggedInAsLocallyManagedUser() && 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !about_flags::AreSwitchesIdenticalToCurrentCommandLine( 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) user_flags, *CommandLine::ForCurrentProcess())) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::StringVector flags; 322 // argv[0] is the program name |CommandLine::NO_PROGRAM|. 323 flags.assign(user_flags.argv().begin() + 1, user_flags.argv().end()); 324 VLOG(1) << "Restarting to apply per-session flags..."; 325 DBusThreadManager::Get()->GetSessionManagerClient()->SetFlagsForUser( 326 UserManager::Get()->GetActiveUser()->email(), flags); 327 AttemptRestart(profile); 328 return; 329 } 330 331 if (login_host) { 332 login_host->SetStatusAreaVisible(true); 333 login_host->BeforeSessionStart(); 334 } 335 336 BootTimesLoader::Get()->AddLoginTimeMarker("BrowserLaunched", false); 337 338 VLOG(1) << "Launching browser..."; 339 StartupBrowserCreator browser_creator; 340 int return_code; 341 chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? 342 chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; 343 344 browser_creator.LaunchBrowser(*CommandLine::ForCurrentProcess(), 345 profile, 346 base::FilePath(), 347 chrome::startup::IS_PROCESS_STARTUP, 348 first_run, 349 &return_code); 350 351 // Triggers app launcher start page service to load start page web contents. 352 app_list::StartPageService::Get(profile); 353 354 // Mark login host for deletion after browser starts. This 355 // guarantees that the message loop will be referenced by the 356 // browser before it is dereferenced by the login host. 357 if (login_host) 358 login_host->Finalize(); 359 UserManager::Get()->SessionStarted(); 360} 361 362void LoginUtilsImpl::DoBrowserLaunch(Profile* profile, 363 LoginDisplayHost* login_host) { 364 if (browser_shutdown::IsTryingToQuit()) 365 return; 366 367 User* const user = UserManager::Get()->GetUserByProfile(profile); 368 scoped_ptr<DoBrowserLaunchOnLocaleLoadedData> data( 369 new DoBrowserLaunchOnLocaleLoadedData(this, profile, login_host)); 370 371 scoped_ptr<locale_util::SwitchLanguageCallback> callback( 372 new locale_util::SwitchLanguageCallback( 373 base::Bind(&LoginUtilsImpl::DoBrowserLaunchOnLocaleLoaded, 374 base::Passed(data.Pass())))); 375 if (!UserManager::Get()-> 376 RespectLocalePreference(profile, user, callback.Pass())) { 377 DoBrowserLaunchOnLocaleLoadedImpl(profile, login_host); 378 } 379} 380 381void LoginUtilsImpl::PrepareProfile( 382 const UserContext& user_context, 383 const std::string& display_email, 384 bool has_cookies, 385 bool has_active_session, 386 LoginUtils::Delegate* delegate) { 387 BootTimesLoader* btl = BootTimesLoader::Get(); 388 389 VLOG(1) << "Completing login for " << user_context.username; 390 391 if (!has_active_session) { 392 btl->AddLoginTimeMarker("StartSession-Start", false); 393 DBusThreadManager::Get()->GetSessionManagerClient()->StartSession( 394 user_context.username); 395 btl->AddLoginTimeMarker("StartSession-End", false); 396 } 397 398 btl->AddLoginTimeMarker("UserLoggedIn-Start", false); 399 UserManager* user_manager = UserManager::Get(); 400 user_manager->UserLoggedIn(user_context.username, 401 user_context.username_hash, 402 false); 403 btl->AddLoginTimeMarker("UserLoggedIn-End", false); 404 405 // Switch log file as soon as possible. 406 if (base::SysInfo::IsRunningOnChromeOS()) 407 logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess())); 408 409 // Update user's displayed email. 410 if (!display_email.empty()) 411 user_manager->SaveUserDisplayEmail(user_context.username, display_email); 412 413 user_context_ = user_context; 414 415 has_web_auth_cookies_ = has_cookies; 416 delegate_ = delegate; 417 InitSessionRestoreStrategy(); 418 419 if (DemoAppLauncher::IsDemoAppSession(user_context.username)) { 420 g_browser_process->profile_manager()->CreateProfileAsync( 421 user_manager->GetUserProfileDir(user_context.username), 422 base::Bind(&LoginUtilsImpl::OnOTRProfileCreated, AsWeakPtr(), 423 user_context.username), 424 base::string16(), base::string16(), std::string()); 425 } else { 426 // Can't use display_email because it is empty when existing user logs in 427 // using sing-in pod on login screen (i.e. user didn't type email). 428 g_browser_process->profile_manager()->CreateProfileAsync( 429 user_manager->GetUserProfileDir(user_context.username), 430 base::Bind(&LoginUtilsImpl::OnProfileCreated, AsWeakPtr(), 431 user_context.username), 432 base::string16(), base::string16(), std::string()); 433 } 434} 435 436void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) { 437 if (delegate_ == delegate) 438 delegate_ = NULL; 439} 440 441void LoginUtilsImpl::InitProfilePreferences(Profile* user_profile, 442 const std::string& user_id) { 443 if (UserManager::Get()->IsCurrentUserNew()) 444 SetFirstLoginPrefs(user_profile->GetPrefs()); 445 446 if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) { 447 User* active_user = UserManager::Get()->GetActiveUser(); 448 std::string managed_user_sync_id = 449 UserManager::Get()->GetSupervisedUserManager()-> 450 GetUserSyncId(active_user->email()); 451 452 // TODO(ibraaaa): Remove that when 97% of our users are using M31. 453 // http://crbug.com/276163 454 if (managed_user_sync_id.empty()) 455 managed_user_sync_id = "DUMMY_ID"; 456 457 user_profile->GetPrefs()->SetString(prefs::kManagedUserId, 458 managed_user_sync_id); 459 } else { 460 // Make sure that the google service username is properly set (we do this 461 // on every sign in, not just the first login, to deal with existing 462 // profiles that might not have it set yet). 463 SigninManagerBase* signin_manager = 464 SigninManagerFactory::GetForProfile(user_profile); 465 signin_manager->SetAuthenticatedUsername(user_id); 466 } 467} 468 469void LoginUtilsImpl::InitSessionRestoreStrategy() { 470 CommandLine* command_line = CommandLine::ForCurrentProcess(); 471 bool in_app_mode = chrome::IsRunningInForcedAppMode(); 472 473 // Are we in kiosk app mode? 474 if (in_app_mode) { 475 if (command_line->HasSwitch(::switches::kAppModeOAuth2Token)) { 476 oauth2_refresh_token_ = command_line->GetSwitchValueASCII( 477 ::switches::kAppModeOAuth2Token); 478 } 479 480 if (command_line->HasSwitch(::switches::kAppModeAuthCode)) { 481 user_context_.auth_code = command_line->GetSwitchValueASCII( 482 ::switches::kAppModeAuthCode); 483 } 484 485 DCHECK(!has_web_auth_cookies_); 486 if (!user_context_.auth_code.empty()) { 487 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE; 488 } else if (!oauth2_refresh_token_.empty()) { 489 session_restore_strategy_ = 490 OAuth2LoginManager::RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN; 491 } else { 492 session_restore_strategy_ = 493 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; 494 } 495 return; 496 } 497 498 if (has_web_auth_cookies_) { 499 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR; 500 } else if (!user_context_.auth_code.empty()) { 501 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE; 502 } else { 503 session_restore_strategy_ = 504 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN; 505 } 506} 507 508 509void LoginUtilsImpl::OnProfileCreated( 510 const std::string& user_id, 511 Profile* user_profile, 512 Profile::CreateStatus status) { 513 CHECK(user_profile); 514 515 switch (status) { 516 case Profile::CREATE_STATUS_CREATED: 517 InitProfilePreferences(user_profile, user_id); 518 break; 519 case Profile::CREATE_STATUS_INITIALIZED: 520 UserProfileInitialized(user_profile); 521 break; 522 case Profile::CREATE_STATUS_LOCAL_FAIL: 523 case Profile::CREATE_STATUS_REMOTE_FAIL: 524 case Profile::CREATE_STATUS_CANCELED: 525 case Profile::MAX_CREATE_STATUS: 526 NOTREACHED(); 527 break; 528 } 529} 530 531void LoginUtilsImpl::OnOTRProfileCreated( 532 const std::string& user_id, 533 Profile* user_profile, 534 Profile::CreateStatus status) { 535 CHECK(user_profile); 536 537 switch (status) { 538 case Profile::CREATE_STATUS_CREATED: 539 InitProfilePreferences(user_profile, user_id); 540 break; 541 case Profile::CREATE_STATUS_INITIALIZED: 542 OTRProfileInitialized(user_profile); 543 break; 544 case Profile::CREATE_STATUS_LOCAL_FAIL: 545 case Profile::CREATE_STATUS_REMOTE_FAIL: 546 case Profile::CREATE_STATUS_CANCELED: 547 case Profile::MAX_CREATE_STATUS: 548 NOTREACHED(); 549 break; 550 } 551} 552 553void LoginUtilsImpl::UserProfileInitialized(Profile* user_profile) { 554 BootTimesLoader* btl = BootTimesLoader::Get(); 555 btl->AddLoginTimeMarker("UserProfileGotten", false); 556 557 if (user_context_.using_oauth) { 558 // Transfer proxy authentication cache, cookies (optionally) and server 559 // bound certs from the profile that was used for authentication. This 560 // profile contains cookies that auth extension should have already put in 561 // place that will ensure that the newly created session is authenticated 562 // for the websites that work with the used authentication schema. 563 ProfileAuthData::Transfer(authenticator_->authentication_profile(), 564 user_profile, 565 has_web_auth_cookies_, // transfer_cookies 566 base::Bind( 567 &LoginUtilsImpl::CompleteProfileCreate, 568 AsWeakPtr(), 569 user_profile)); 570 return; 571 } 572 573 FinalizePrepareProfile(user_profile); 574} 575 576void LoginUtilsImpl::OTRProfileInitialized(Profile* user_profile) { 577 user_profile->OnLogin(); 578 // Send the notification before creating the browser so additional objects 579 // that need the profile (e.g. the launcher) can be created first. 580 content::NotificationService::current()->Notify( 581 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, 582 content::NotificationService::AllSources(), 583 content::Details<Profile>(user_profile)); 584 585 if (delegate_) 586 delegate_->OnProfilePrepared(user_profile); 587} 588 589void LoginUtilsImpl::CompleteProfileCreate(Profile* user_profile) { 590 RestoreAuthSession(user_profile, has_web_auth_cookies_); 591 FinalizePrepareProfile(user_profile); 592} 593 594void LoginUtilsImpl::RestoreAuthSession(Profile* user_profile, 595 bool restore_from_auth_cookies) { 596 CHECK((authenticator_.get() && authenticator_->authentication_profile()) || 597 !restore_from_auth_cookies); 598 599 if (chrome::IsRunningInForcedAppMode() || 600 CommandLine::ForCurrentProcess()->HasSwitch( 601 chromeos::switches::kOobeSkipPostLogin)) { 602 return; 603 } 604 605 exit_after_session_restore_ = false; 606 // Remove legacy OAuth1 token if we have one. If it's valid, we should already 607 // have OAuth2 refresh token in OAuth2TokenService that could be used to 608 // retrieve all other tokens and user_context. 609 OAuth2LoginManager* login_manager = 610 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); 611 login_manager->AddObserver(this); 612 login_manager->RestoreSession( 613 authenticator_.get() && authenticator_->authentication_profile() 614 ? authenticator_->authentication_profile()->GetRequestContext() 615 : NULL, 616 session_restore_strategy_, 617 oauth2_refresh_token_, 618 user_context_.auth_code); 619} 620 621void LoginUtilsImpl::FinalizePrepareProfile(Profile* user_profile) { 622 BootTimesLoader* btl = BootTimesLoader::Get(); 623 // Own TPM device if, for any reason, it has not been done in EULA 624 // wizard screen. 625 CryptohomeClient* client = DBusThreadManager::Get()->GetCryptohomeClient(); 626 btl->AddLoginTimeMarker("TPMOwn-Start", false); 627 if (cryptohome_util::TpmIsEnabled() && !cryptohome_util::TpmIsBeingOwned()) { 628 if (cryptohome_util::TpmIsOwned()) { 629 client->CallTpmClearStoredPasswordAndBlock(); 630 } else { 631 client->TpmCanAttemptOwnership(EmptyVoidDBusMethodCallback()); 632 } 633 } 634 btl->AddLoginTimeMarker("TPMOwn-End", false); 635 636 if (UserManager::Get()->IsLoggedInAsRegularUser()) { 637 SAMLOfflineSigninLimiter* saml_offline_signin_limiter = 638 SAMLOfflineSigninLimiterFactory::GetForProfile(user_profile); 639 if (saml_offline_signin_limiter) 640 saml_offline_signin_limiter->SignedIn(user_context_.auth_flow); 641 } 642 643 user_profile->OnLogin(); 644 645 // Send the notification before creating the browser so additional objects 646 // that need the profile (e.g. the launcher) can be created first. 647 content::NotificationService::current()->Notify( 648 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, 649 content::NotificationService::AllSources(), 650 content::Details<Profile>(user_profile)); 651 652 // Initialize RLZ only for primary user. 653 if (UserManager::Get()->GetPrimaryUser() == 654 UserManager::Get()->GetUserByProfile(user_profile)) { 655 InitRlzDelayed(user_profile); 656 } 657 // TODO(altimofeev): This pointer should probably never be NULL, but it looks 658 // like LoginUtilsImpl::OnProfileCreated() may be getting called before 659 // LoginUtilsImpl::PrepareProfile() has set |delegate_| when Chrome is killed 660 // during shutdown in tests -- see http://crosbug.com/18269. Replace this 661 // 'if' statement with a CHECK(delegate_) once the underlying issue is 662 // resolved. 663 if (delegate_) 664 delegate_->OnProfilePrepared(user_profile); 665} 666 667void LoginUtilsImpl::InitRlzDelayed(Profile* user_profile) { 668#if defined(ENABLE_RLZ) 669 if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) { 670 // Read brand code asynchronously from an OEM data and repost ourselves. 671 google_util::chromeos::InitBrand( 672 base::Bind(&LoginUtilsImpl::InitRlzDelayed, AsWeakPtr(), user_profile)); 673 return; 674 } 675 base::PostTaskAndReplyWithResult( 676 base::WorkerPool::GetTaskRunner(false), 677 FROM_HERE, 678 base::Bind(&base::PathExists, GetRlzDisabledFlagPath()), 679 base::Bind(&LoginUtilsImpl::InitRlz, AsWeakPtr(), user_profile)); 680#endif 681} 682 683void LoginUtilsImpl::InitRlz(Profile* user_profile, bool disabled) { 684#if defined(ENABLE_RLZ) 685 PrefService* local_state = g_browser_process->local_state(); 686 if (disabled) { 687 // Empty brand code means an organic install (no RLZ pings are sent). 688 google_util::chromeos::ClearBrandForCurrentSession(); 689 } 690 if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) { 691 // When switching to RLZ enabled/disabled state, clear all recorded events. 692 RLZTracker::ClearRlzState(); 693 local_state->SetBoolean(prefs::kRLZDisabled, disabled); 694 } 695 // Init the RLZ library. 696 int ping_delay = user_profile->GetPrefs()->GetInteger( 697 first_run::GetPingDelayPrefName().c_str()); 698 // Negative ping delay means to send ping immediately after a first search is 699 // recorded. 700 RLZTracker::InitRlzFromProfileDelayed( 701 user_profile, UserManager::Get()->IsCurrentUserNew(), 702 ping_delay < 0, base::TimeDelta::FromMilliseconds(abs(ping_delay))); 703 if (delegate_) 704 delegate_->OnRlzInitialized(user_profile); 705#endif 706} 707 708void LoginUtilsImpl::CompleteOffTheRecordLogin(const GURL& start_url) { 709 VLOG(1) << "Completing incognito login"; 710 711 // For guest session we ask session manager to restart Chrome with --bwsi 712 // flag. We keep only some of the arguments of this process. 713 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); 714 CommandLine command_line(browser_command_line.GetProgram()); 715 std::string cmd_line_str = 716 GetOffTheRecordCommandLine(start_url, 717 StartupUtils::IsOobeCompleted(), 718 browser_command_line, 719 &command_line); 720 721 RestartChrome(cmd_line_str); 722} 723 724void LoginUtilsImpl::SetFirstLoginPrefs(PrefService* prefs) { 725 VLOG(1) << "Setting first login prefs"; 726 BootTimesLoader* btl = BootTimesLoader::Get(); 727 std::string locale = g_browser_process->GetApplicationLocale(); 728 729 // First, we'll set kLanguagePreloadEngines. 730 input_method::InputMethodManager* manager = 731 input_method::InputMethodManager::Get(); 732 std::vector<std::string> input_method_ids; 733 manager->GetInputMethodUtil()->GetFirstLoginInputMethodIds( 734 locale, manager->GetCurrentInputMethod(), &input_method_ids); 735 // Save the input methods in the user's preferences. 736 StringPrefMember language_preload_engines; 737 language_preload_engines.Init(prefs::kLanguagePreloadEngines, 738 prefs); 739 language_preload_engines.SetValue(JoinString(input_method_ids, ',')); 740 btl->AddLoginTimeMarker("IMEStarted", false); 741 742 // Second, we'll set kLanguagePreferredLanguages. 743 std::vector<std::string> language_codes; 744 // The current locale should be on the top. 745 language_codes.push_back(locale); 746 747 // Add input method IDs based on the input methods, as there may be 748 // input methods that are unrelated to the current locale. Example: the 749 // hardware keyboard layout xkb:us::eng is used for logging in, but the 750 // UI language is set to French. In this case, we should set "fr,en" 751 // to the preferred languages preference. 752 std::vector<std::string> candidates; 753 manager->GetInputMethodUtil()->GetLanguageCodesFromInputMethodIds( 754 input_method_ids, &candidates); 755 for (size_t i = 0; i < candidates.size(); ++i) { 756 const std::string& candidate = candidates[i]; 757 // Skip if it's already in language_codes. 758 if (std::count(language_codes.begin(), language_codes.end(), 759 candidate) == 0) { 760 language_codes.push_back(candidate); 761 } 762 } 763 // Save the preferred languages in the user's preferences. 764 StringPrefMember language_preferred_languages; 765 language_preferred_languages.Init(prefs::kLanguagePreferredLanguages, 766 prefs); 767 language_preferred_languages.SetValue(JoinString(language_codes, ',')); 768} 769 770scoped_refptr<Authenticator> LoginUtilsImpl::CreateAuthenticator( 771 LoginStatusConsumer* consumer) { 772 // Screen locker needs new Authenticator instance each time. 773 if (ScreenLocker::default_screen_locker()) { 774 if (authenticator_.get()) 775 authenticator_->SetConsumer(NULL); 776 authenticator_ = NULL; 777 } 778 779 if (authenticator_.get() == NULL) { 780 authenticator_ = new ParallelAuthenticator(consumer); 781 } else { 782 // TODO(nkostylev): Fix this hack by improving Authenticator dependencies. 783 authenticator_->SetConsumer(consumer); 784 } 785 return authenticator_; 786} 787 788void LoginUtilsImpl::RestoreAuthenticationSession(Profile* user_profile) { 789 UserManager* user_manager = UserManager::Get(); 790 // We don't need to restore session for demo/guest/stub/public account users. 791 if (!user_manager->IsUserLoggedIn() || 792 user_manager->IsLoggedInAsGuest() || 793 user_manager->IsLoggedInAsPublicAccount() || 794 user_manager->IsLoggedInAsDemoUser() || 795 user_manager->IsLoggedInAsStub()) { 796 return; 797 } 798 799 User* user = user_manager->GetUserByProfile(user_profile); 800 DCHECK(user); 801 if (!net::NetworkChangeNotifier::IsOffline()) { 802 pending_restore_sessions_.erase(user->email()); 803 RestoreAuthSession(user_profile, false); 804 } else { 805 // Even if we're online we should wait till initial 806 // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may 807 // end up canceling all request when initial network connection type is 808 // processed. See http://crbug.com/121643. 809 pending_restore_sessions_.insert(user->email()); 810 } 811} 812 813void LoginUtilsImpl::OnSessionRestoreStateChanged( 814 Profile* user_profile, 815 OAuth2LoginManager::SessionRestoreState state) { 816 User::OAuthTokenStatus user_status = User::OAUTH_TOKEN_STATUS_UNKNOWN; 817 OAuth2LoginManager* login_manager = 818 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); 819 820 bool connection_error = false; 821 switch (state) { 822 case OAuth2LoginManager::SESSION_RESTORE_DONE: 823 user_status = User::OAUTH2_TOKEN_STATUS_VALID; 824 break; 825 case OAuth2LoginManager::SESSION_RESTORE_FAILED: 826 user_status = User::OAUTH2_TOKEN_STATUS_INVALID; 827 break; 828 case OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED: 829 connection_error = true; 830 break; 831 case OAuth2LoginManager::SESSION_RESTORE_NOT_STARTED: 832 case OAuth2LoginManager::SESSION_RESTORE_PREPARING: 833 case OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS: 834 return; 835 } 836 837 // We should not be clearing existing token state if that was a connection 838 // error. http://crbug.com/295245 839 if (!connection_error) { 840 // We are in one of "done" states here. 841 UserManager::Get()->SaveUserOAuthStatus( 842 UserManager::Get()->GetLoggedInUser()->email(), 843 user_status); 844 } 845 846 login_manager->RemoveObserver(this); 847} 848 849void LoginUtilsImpl::OnNewRefreshTokenAvaiable(Profile* user_profile) { 850 // Check if we were waiting to restart chrome. 851 if (!exit_after_session_restore_) 852 return; 853 854 OAuth2LoginManager* login_manager = 855 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); 856 login_manager->RemoveObserver(this); 857 858 // Mark user auth token status as valid. 859 UserManager::Get()->SaveUserOAuthStatus( 860 UserManager::Get()->GetLoggedInUser()->email(), 861 User::OAUTH2_TOKEN_STATUS_VALID); 862 863 LOG(WARNING) << "Exiting after new refresh token fetched"; 864 // We need to restart cleanly in this case to make sure OAuth2 RT is actually 865 // saved. 866 chrome::AttemptRestart(); 867} 868 869void LoginUtilsImpl::OnConnectionTypeChanged( 870 net::NetworkChangeNotifier::ConnectionType type) { 871 UserManager* user_manager = UserManager::Get(); 872 if (type == net::NetworkChangeNotifier::CONNECTION_NONE || 873 user_manager->IsLoggedInAsGuest() || !user_manager->IsUserLoggedIn()) { 874 return; 875 } 876 877 // Need to iterate over all users and their OAuth2 session state. 878 const UserList& users = user_manager->GetLoggedInUsers(); 879 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { 880 Profile* user_profile = user_manager->GetProfileByUser(*it); 881 bool should_restore_session = 882 pending_restore_sessions_.find((*it)->email()) != 883 pending_restore_sessions_.end(); 884 OAuth2LoginManager* login_manager = 885 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile); 886 if (login_manager->state() == 887 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) { 888 // If we come online for the first time after successful offline login, 889 // we need to kick off OAuth token verification process again. 890 login_manager->ContinueSessionRestore(); 891 } else if (should_restore_session) { 892 pending_restore_sessions_.erase((*it)->email()); 893 RestoreAuthSession(user_profile, has_web_auth_cookies_); 894 } 895 } 896} 897 898void LoginUtilsImpl::AttemptRestart(Profile* profile) { 899 if (session_restore_strategy_ != 900 OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR) { 901 chrome::AttemptRestart(); 902 return; 903 } 904 905 // We can't really quit if the session restore process that mints new 906 // refresh token is still in progress. 907 OAuth2LoginManager* login_manager = 908 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile); 909 if (login_manager->state() != 910 OAuth2LoginManager::SESSION_RESTORE_PREPARING && 911 login_manager->state() != 912 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) { 913 chrome::AttemptRestart(); 914 return; 915 } 916 917 LOG(WARNING) << "Attempting browser restart during session restore."; 918 exit_after_session_restore_ = true; 919} 920 921// static 922void LoginUtils::RegisterPrefs(PrefRegistrySimple* registry) { 923 registry->RegisterBooleanPref(prefs::kFactoryResetRequested, false); 924 registry->RegisterBooleanPref(prefs::kRollbackRequested, false); 925 registry->RegisterStringPref(prefs::kRLZBrand, std::string()); 926 registry->RegisterBooleanPref(prefs::kRLZDisabled, false); 927} 928 929// static 930LoginUtils* LoginUtils::Get() { 931 return LoginUtilsWrapper::GetInstance()->get(); 932} 933 934// static 935void LoginUtils::Set(LoginUtils* mock) { 936 LoginUtilsWrapper::GetInstance()->reset(mock); 937} 938 939// static 940bool LoginUtils::IsWhitelisted(const std::string& username, 941 bool* wildcard_match) { 942 // Skip whitelist check for tests. 943 if (CommandLine::ForCurrentProcess()->HasSwitch( 944 chromeos::switches::kOobeSkipPostLogin)) { 945 return true; 946 } 947 948 CrosSettings* cros_settings = CrosSettings::Get(); 949 bool allow_new_user = false; 950 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); 951 if (allow_new_user) 952 return true; 953 return cros_settings->FindEmailInList( 954 kAccountsPrefUsers, username, wildcard_match); 955} 956 957} // namespace chromeos 958