Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: chrome/browser/chromeos/login/login_utils.cc

Issue 318853004: Introduce SessionManager that will contain code to start user session on Chrome OS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/login/login_utils.h" 5 #include "chrome/browser/chromeos/login/login_utils.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/base_paths.h" 11 #include "base/base_paths.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
15 #include "base/file_util.h" 15 #include "base/file_util.h"
16 #include "base/files/file_path.h" 16 #include "base/files/file_path.h"
17 #include "base/location.h" 17 #include "base/location.h"
18 #include "base/memory/ref_counted.h" 18 #include "base/memory/ref_counted.h"
19 #include "base/memory/scoped_ptr.h" 19 #include "base/memory/scoped_ptr.h"
20 #include "base/memory/singleton.h" 20 #include "base/memory/singleton.h"
21 #include "base/memory/weak_ptr.h" 21 #include "base/memory/weak_ptr.h"
22 #include "base/path_service.h" 22 #include "base/path_service.h"
23 #include "base/prefs/pref_member.h" 23 #include "base/prefs/pref_member.h"
24 #include "base/prefs/pref_registry_simple.h"
25 #include "base/prefs/pref_service.h" 24 #include "base/prefs/pref_service.h"
26 #include "base/strings/string_util.h" 25 #include "base/strings/string_util.h"
27 #include "base/strings/utf_string_conversions.h" 26 #include "base/strings/utf_string_conversions.h"
28 #include "base/synchronization/lock.h" 27 #include "base/synchronization/lock.h"
29 #include "base/sys_info.h" 28 #include "base/sys_info.h"
30 #include "base/task_runner_util.h" 29 #include "base/task_runner_util.h"
31 #include "base/threading/worker_pool.h" 30 #include "base/threading/worker_pool.h"
32 #include "base/time/time.h" 31 #include "base/time/time.h"
33 #include "chrome/browser/about_flags.h" 32 #include "chrome/browser/about_flags.h"
34 #include "chrome/browser/app_mode/app_mode_utils.h" 33 #include "chrome/browser/app_mode/app_mode_utils.h"
35 #include "chrome/browser/browser_process.h" 34 #include "chrome/browser/browser_process.h"
36 #include "chrome/browser/browser_shutdown.h" 35 #include "chrome/browser/browser_shutdown.h"
37 #include "chrome/browser/chrome_notification_types.h" 36 #include "chrome/browser/chrome_notification_types.h"
38 #include "chrome/browser/chromeos/boot_times_loader.h" 37 #include "chrome/browser/chromeos/boot_times_loader.h"
39 #include "chrome/browser/chromeos/input_method/input_method_util.h"
40 #include "chrome/browser/chromeos/login/auth/parallel_authenticator.h" 38 #include "chrome/browser/chromeos/login/auth/parallel_authenticator.h"
41 #include "chrome/browser/chromeos/login/auth/user_context.h" 39 #include "chrome/browser/chromeos/login/auth/user_context.h"
42 #include "chrome/browser/chromeos/login/chrome_restart_request.h" 40 #include "chrome/browser/chromeos/login/chrome_restart_request.h"
43 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" 41 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
44 #include "chrome/browser/chromeos/login/lock/screen_locker.h" 42 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
45 #include "chrome/browser/chromeos/login/profile_auth_data.h" 43 #include "chrome/browser/chromeos/login/profile_auth_data.h"
46 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h" 44 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.h"
47 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory .h" 45 #include "chrome/browser/chromeos/login/saml/saml_offline_signin_limiter_factory .h"
46 #include "chrome/browser/chromeos/login/session/session_manager.h"
48 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h" 47 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h"
49 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h" 48 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
50 #include "chrome/browser/chromeos/login/startup_utils.h" 49 #include "chrome/browser/chromeos/login/startup_utils.h"
51 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h" 50 #include "chrome/browser/chromeos/login/ui/input_events_blocker.h"
52 #include "chrome/browser/chromeos/login/ui/login_display_host.h" 51 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
53 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 52 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
54 #include "chrome/browser/chromeos/login/users/user.h" 53 #include "chrome/browser/chromeos/login/users/user.h"
55 #include "chrome/browser/chromeos/login/users/user_manager.h" 54 #include "chrome/browser/chromeos/login/users/user_manager.h"
56 #include "chrome/browser/chromeos/settings/cros_settings.h" 55 #include "chrome/browser/chromeos/settings/cros_settings.h"
57 #include "chrome/browser/extensions/extension_service.h" 56 #include "chrome/browser/extensions/extension_service.h"
(...skipping 11 matching lines...) Expand all
69 #include "chrome/browser/ui/startup/startup_browser_creator.h" 68 #include "chrome/browser/ui/startup/startup_browser_creator.h"
70 #include "chrome/common/chrome_switches.h" 69 #include "chrome/common/chrome_switches.h"
71 #include "chrome/common/logging_chrome.h" 70 #include "chrome/common/logging_chrome.h"
72 #include "chrome/common/pref_names.h" 71 #include "chrome/common/pref_names.h"
73 #include "chromeos/chromeos_switches.h" 72 #include "chromeos/chromeos_switches.h"
74 #include "chromeos/cryptohome/cryptohome_util.h" 73 #include "chromeos/cryptohome/cryptohome_util.h"
75 #include "chromeos/dbus/cryptohome_client.h" 74 #include "chromeos/dbus/cryptohome_client.h"
76 #include "chromeos/dbus/dbus_method_call_status.h" 75 #include "chromeos/dbus/dbus_method_call_status.h"
77 #include "chromeos/dbus/dbus_thread_manager.h" 76 #include "chromeos/dbus/dbus_thread_manager.h"
78 #include "chromeos/dbus/session_manager_client.h" 77 #include "chromeos/dbus/session_manager_client.h"
79 #include "chromeos/ime/input_method_manager.h"
80 #include "chromeos/settings/cros_settings_names.h" 78 #include "chromeos/settings/cros_settings_names.h"
81 #include "components/signin/core/browser/signin_manager.h" 79 #include "components/signin/core/browser/signin_manager.h"
82 #include "content/public/browser/browser_thread.h" 80 #include "content/public/browser/browser_thread.h"
83 #include "content/public/browser/notification_service.h" 81 #include "content/public/browser/notification_service.h"
84 #include "google_apis/gaia/gaia_auth_consumer.h" 82 #include "google_apis/gaia/gaia_auth_consumer.h"
85 #include "net/base/network_change_notifier.h" 83 #include "net/base/network_change_notifier.h"
86 #include "net/url_request/url_request_context.h" 84 #include "net/url_request/url_request_context.h"
87 #include "net/url_request/url_request_context_getter.h" 85 #include "net/url_request/url_request_context_getter.h"
88 #include "url/gurl.h" 86 #include "url/gurl.h"
89 87
(...skipping 14 matching lines...) Expand all
104 return homedir.Append(kRLZDisabledFlagName); 102 return homedir.Append(kRLZDisabledFlagName);
105 } 103 }
106 #endif 104 #endif
107 105
108 } // namespace 106 } // namespace
109 107
110 struct DoBrowserLaunchOnLocaleLoadedData; 108 struct DoBrowserLaunchOnLocaleLoadedData;
111 109
112 class LoginUtilsImpl 110 class LoginUtilsImpl
113 : public LoginUtils, 111 : public LoginUtils,
114 public OAuth2LoginManager::Observer, 112 public base::SupportsWeakPtr<LoginUtilsImpl>,
115 public net::NetworkChangeNotifier::ConnectionTypeObserver, 113 public SessionManager::Delegate {
116 public base::SupportsWeakPtr<LoginUtilsImpl> {
117 public: 114 public:
118 LoginUtilsImpl() 115 LoginUtilsImpl()
119 : has_web_auth_cookies_(false), 116 : delegate_(NULL) {
120 delegate_(NULL),
121 exit_after_session_restore_(false),
122 session_restore_strategy_(
123 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN) {
124 net::NetworkChangeNotifier::AddConnectionTypeObserver(this);
125 } 117 }
126 118
127 virtual ~LoginUtilsImpl() { 119 virtual ~LoginUtilsImpl() {
128 net::NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
129 } 120 }
130 121
131 // LoginUtils implementation: 122 // LoginUtils implementation:
132 virtual void DoBrowserLaunch(Profile* profile, 123 virtual void DoBrowserLaunch(Profile* profile,
133 LoginDisplayHost* login_host) OVERRIDE; 124 LoginDisplayHost* login_host) OVERRIDE;
134 virtual void PrepareProfile( 125 virtual void PrepareProfile(
135 const UserContext& user_context, 126 const UserContext& user_context,
136 const std::string& display_email,
137 bool has_cookies, 127 bool has_cookies,
138 bool has_active_session, 128 bool has_active_session,
139 LoginUtils::Delegate* delegate) OVERRIDE; 129 LoginUtils::Delegate* delegate) OVERRIDE;
140 virtual void DelegateDeleted(LoginUtils::Delegate* delegate) OVERRIDE; 130 virtual void DelegateDeleted(LoginUtils::Delegate* delegate) OVERRIDE;
141 virtual void CompleteOffTheRecordLogin(const GURL& start_url) OVERRIDE; 131 virtual void CompleteOffTheRecordLogin(const GURL& start_url) OVERRIDE;
142 virtual void SetFirstLoginPrefs(PrefService* prefs) OVERRIDE;
143 virtual scoped_refptr<Authenticator> CreateAuthenticator( 132 virtual scoped_refptr<Authenticator> CreateAuthenticator(
144 LoginStatusConsumer* consumer) OVERRIDE; 133 LoginStatusConsumer* consumer) OVERRIDE;
145 virtual void RestoreAuthenticationSession(Profile* profile) OVERRIDE;
146 virtual void InitRlzDelayed(Profile* user_profile) OVERRIDE;
147 134
148 // OAuth2LoginManager::Observer overrides. 135 // SessionManager::Delegate implementation:
149 virtual void OnSessionRestoreStateChanged( 136 virtual void OnProfilePrepared(Profile* profile) OVERRIDE;
150 Profile* user_profile, 137 #if defined(ENABLE_RLZ)
151 OAuth2LoginManager::SessionRestoreState state) OVERRIDE; 138 virtual void OnRlzInitialized() OVERRIDE;
152 virtual void OnNewRefreshTokenAvaiable(Profile* user_profile) OVERRIDE; 139 #endif
153
154 // net::NetworkChangeNotifier::ConnectionTypeObserver overrides.
155 virtual void OnConnectionTypeChanged(
156 net::NetworkChangeNotifier::ConnectionType type) OVERRIDE;
157 140
158 private: 141 private:
159 typedef std::set<std::string> SessionRestoreStateSet;
160
161 // DoBrowserLaunch is split into two parts. 142 // DoBrowserLaunch is split into two parts.
162 // This one is called after anynchronous locale switch. 143 // This one is called after asynchronous locale switch.
163 void DoBrowserLaunchOnLocaleLoadedImpl(Profile* profile, 144 void DoBrowserLaunchOnLocaleLoadedImpl(Profile* profile,
164 LoginDisplayHost* login_host); 145 LoginDisplayHost* login_host);
165 146
166 // Callback for locale_util::SwitchLanguage(). 147 // Callback for locale_util::SwitchLanguage().
167 static void DoBrowserLaunchOnLocaleLoaded( 148 static void DoBrowserLaunchOnLocaleLoaded(
168 scoped_ptr<DoBrowserLaunchOnLocaleLoadedData> context, 149 scoped_ptr<DoBrowserLaunchOnLocaleLoadedData> context,
169 const std::string& locale, 150 const std::string& locale,
170 const std::string& loaded_locale, 151 const std::string& loaded_locale,
171 const bool success); 152 const bool success);
172 153
173 // Restarts OAuth session authentication check.
174 void KickStartAuthentication(Profile* profile);
175
176 // Callback for Profile::CREATE_STATUS_CREATED profile state.
177 // Initializes basic preferences for newly created profile. Any other
178 // early profile initialization that needs to happen before
179 // ProfileManager::DoFinalInit() gets called is done here.
180 void InitProfilePreferences(Profile* user_profile,
181 const std::string& email);
182
183 // Callback for asynchronous profile creation.
184 void OnProfileCreated(const std::string& email,
185 Profile* profile,
186 Profile::CreateStatus status);
187
188 // Callback for asynchronous off the record profile creation.
189 void OnOTRProfileCreated(const std::string& email,
190 Profile* profile,
191 Profile::CreateStatus status);
192
193 // Callback for Profile::CREATE_STATUS_INITIALIZED profile state.
194 // Profile is created, extensions and promo resources are initialized.
195 void UserProfileInitialized(Profile* user_profile);
196
197 // Callback for Profile::CREATE_STATUS_INITIALIZED profile state for an OTR
198 // login.
199 void OTRProfileInitialized(Profile* user_profile);
200
201 // Callback to resume profile creation after transferring auth data from
202 // the authentication profile.
203 void CompleteProfileCreate(Profile* user_profile);
204
205 // Finalized profile preparation.
206 void FinalizePrepareProfile(Profile* user_profile);
207
208 // Initializes member variables needed for session restore process via
209 // OAuthLoginManager.
210 void InitSessionRestoreStrategy();
211
212 // Restores GAIA auth cookies for the created user profile from OAuth2 token.
213 void RestoreAuthSession(Profile* user_profile,
214 bool restore_from_auth_cookies);
215
216 // Initializes RLZ. If |disabled| is true, RLZ pings are disabled.
217 void InitRlz(Profile* user_profile, bool disabled);
218
219 // Attempts restarting the browser process and esures that this does 154 // Attempts restarting the browser process and esures that this does
220 // not happen while we are still fetching new OAuth refresh tokens. 155 // not happen while we are still fetching new OAuth refresh tokens.
221 void AttemptRestart(Profile* profile); 156 void AttemptRestart(Profile* profile);
222 157
223 UserContext user_context_;
224
225 // True if the authentication profile's cookie jar should contain
226 // authentication cookies from the authentication extension log in flow.
227 bool has_web_auth_cookies_;
228 // Has to be scoped_refptr, see comment for CreateAuthenticator(...). 158 // Has to be scoped_refptr, see comment for CreateAuthenticator(...).
229 scoped_refptr<Authenticator> authenticator_; 159 scoped_refptr<Authenticator> authenticator_;
230 160
231 // Delegate to be fired when the profile will be prepared. 161 // Delegate to be fired when the profile will be prepared.
232 LoginUtils::Delegate* delegate_; 162 LoginUtils::Delegate* delegate_;
233 163
234 // Set of user_id for those users that we should restore authentication
235 // session when notified about online state change.
236 SessionRestoreStateSet pending_restore_sessions_;
237
238 // True if we should restart chrome right after session restore.
239 bool exit_after_session_restore_;
240
241 // Sesion restore strategy.
242 OAuth2LoginManager::SessionRestoreStrategy session_restore_strategy_;
243 // OAuth2 refresh token for session restore.
244 std::string oauth2_refresh_token_;
245
246 DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl); 164 DISALLOW_COPY_AND_ASSIGN(LoginUtilsImpl);
247 }; 165 };
248 166
249 class LoginUtilsWrapper { 167 class LoginUtilsWrapper {
250 public: 168 public:
251 static LoginUtilsWrapper* GetInstance() { 169 static LoginUtilsWrapper* GetInstance() {
252 return Singleton<LoginUtilsWrapper>::get(); 170 return Singleton<LoginUtilsWrapper>::get();
253 } 171 }
254 172
255 LoginUtils* get() { 173 LoginUtils* get() {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 base::Bind(&LoginUtilsImpl::DoBrowserLaunchOnLocaleLoaded, 296 base::Bind(&LoginUtilsImpl::DoBrowserLaunchOnLocaleLoaded,
379 base::Passed(data.Pass())))); 297 base::Passed(data.Pass()))));
380 if (!UserManager::Get()-> 298 if (!UserManager::Get()->
381 RespectLocalePreference(profile, user, callback.Pass())) { 299 RespectLocalePreference(profile, user, callback.Pass())) {
382 DoBrowserLaunchOnLocaleLoadedImpl(profile, login_host); 300 DoBrowserLaunchOnLocaleLoadedImpl(profile, login_host);
383 } 301 }
384 } 302 }
385 303
386 void LoginUtilsImpl::PrepareProfile( 304 void LoginUtilsImpl::PrepareProfile(
387 const UserContext& user_context, 305 const UserContext& user_context,
388 const std::string& display_email,
389 bool has_cookies, 306 bool has_cookies,
390 bool has_active_session, 307 bool has_active_session,
391 LoginUtils::Delegate* delegate) { 308 LoginUtils::Delegate* delegate) {
392 BootTimesLoader* btl = BootTimesLoader::Get(); 309 // TODO(nkostylev): We have to initialize LoginUtils delegate as long
310 // as it coexist with SessionManager.
311 delegate_ = delegate;
393 312
394 VLOG(1) << "Completing login for " << user_context.GetUserID(); 313 // For the transition part LoginUtils will just delegate profile
395 314 // creation and initialization to SessionManager. Later LoginUtils will be
396 if (!has_active_session) { 315 // removed and all LoginUtils clients will just work with SessionManager
397 btl->AddLoginTimeMarker("StartSession-Start", false); 316 // directly.
398 DBusThreadManager::Get()->GetSessionManagerClient()->StartSession( 317 SessionManager::GetInstance()->StartSession(user_context,
399 user_context.GetUserID()); 318 authenticator_,
400 btl->AddLoginTimeMarker("StartSession-End", false); 319 has_cookies,
401 } 320 has_active_session,
402 321 this);
403 btl->AddLoginTimeMarker("UserLoggedIn-Start", false);
404 UserManager* user_manager = UserManager::Get();
405 user_manager->UserLoggedIn(user_context.GetUserID(),
406 user_context.GetUserIDHash(),
407 false);
408 btl->AddLoginTimeMarker("UserLoggedIn-End", false);
409
410 // Switch log file as soon as possible.
411 if (base::SysInfo::IsRunningOnChromeOS())
412 logging::RedirectChromeLogging(*(CommandLine::ForCurrentProcess()));
413
414 // Update user's displayed email.
415 if (!display_email.empty())
416 user_manager->SaveUserDisplayEmail(user_context.GetUserID(), display_email);
417
418 user_context_ = user_context;
419
420 has_web_auth_cookies_ = has_cookies;
421 delegate_ = delegate;
422 InitSessionRestoreStrategy();
423
424 if (DemoAppLauncher::IsDemoAppSession(user_context.GetUserID())) {
425 g_browser_process->profile_manager()->CreateProfileAsync(
426 user_manager->GetUserProfileDir(user_context.GetUserID()),
427 base::Bind(&LoginUtilsImpl::OnOTRProfileCreated, AsWeakPtr(),
428 user_context.GetUserID()),
429 base::string16(), base::string16(), std::string());
430 } else {
431 // Can't use display_email because it is empty when existing user logs in
432 // using sing-in pod on login screen (i.e. user didn't type email).
433 g_browser_process->profile_manager()->CreateProfileAsync(
434 user_manager->GetUserProfileDir(user_context.GetUserID()),
435 base::Bind(&LoginUtilsImpl::OnProfileCreated, AsWeakPtr(),
436 user_context.GetUserID()),
437 base::string16(), base::string16(), std::string());
438 }
439 } 322 }
440 323
441 void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) { 324 void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) {
442 if (delegate_ == delegate) 325 if (delegate_ == delegate)
443 delegate_ = NULL; 326 delegate_ = NULL;
444 } 327 }
445 328
446 void LoginUtilsImpl::InitProfilePreferences(Profile* user_profile,
447 const std::string& user_id) {
448 if (UserManager::Get()->IsCurrentUserNew())
449 SetFirstLoginPrefs(user_profile->GetPrefs());
450
451 if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) {
452 User* active_user = UserManager::Get()->GetActiveUser();
453 std::string managed_user_sync_id =
454 UserManager::Get()->GetSupervisedUserManager()->
455 GetUserSyncId(active_user->email());
456
457 // TODO(ibraaaa): Remove that when 97% of our users are using M31.
458 // http://crbug.com/276163
459 if (managed_user_sync_id.empty())
460 managed_user_sync_id = "DUMMY_ID";
461
462 user_profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
463 managed_user_sync_id);
464 } else if (UserManager::Get()->IsLoggedInAsRegularUser()) {
465 // Make sure that the google service username is properly set (we do this
466 // on every sign in, not just the first login, to deal with existing
467 // profiles that might not have it set yet).
468 SigninManagerBase* signin_manager =
469 SigninManagerFactory::GetForProfile(user_profile);
470 signin_manager->SetAuthenticatedUsername(user_id);
471 }
472 }
473
474 void LoginUtilsImpl::InitSessionRestoreStrategy() {
475 CommandLine* command_line = CommandLine::ForCurrentProcess();
476 bool in_app_mode = chrome::IsRunningInForcedAppMode();
477
478 // Are we in kiosk app mode?
479 if (in_app_mode) {
480 if (command_line->HasSwitch(::switches::kAppModeOAuth2Token)) {
481 oauth2_refresh_token_ = command_line->GetSwitchValueASCII(
482 ::switches::kAppModeOAuth2Token);
483 }
484
485 if (command_line->HasSwitch(::switches::kAppModeAuthCode)) {
486 user_context_.SetAuthCode(command_line->GetSwitchValueASCII(
487 ::switches::kAppModeAuthCode));
488 }
489
490 DCHECK(!has_web_auth_cookies_);
491 if (!user_context_.GetAuthCode().empty()) {
492 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE;
493 } else if (!oauth2_refresh_token_.empty()) {
494 session_restore_strategy_ =
495 OAuth2LoginManager::RESTORE_FROM_PASSED_OAUTH2_REFRESH_TOKEN;
496 } else {
497 session_restore_strategy_ =
498 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN;
499 }
500 return;
501 }
502
503 if (has_web_auth_cookies_) {
504 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR;
505 } else if (!user_context_.GetAuthCode().empty()) {
506 session_restore_strategy_ = OAuth2LoginManager::RESTORE_FROM_AUTH_CODE;
507 } else {
508 session_restore_strategy_ =
509 OAuth2LoginManager::RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN;
510 }
511 }
512
513
514 void LoginUtilsImpl::OnProfileCreated(
515 const std::string& user_id,
516 Profile* user_profile,
517 Profile::CreateStatus status) {
518 CHECK(user_profile);
519
520 switch (status) {
521 case Profile::CREATE_STATUS_CREATED:
522 InitProfilePreferences(user_profile, user_id);
523 break;
524 case Profile::CREATE_STATUS_INITIALIZED:
525 UserProfileInitialized(user_profile);
526 break;
527 case Profile::CREATE_STATUS_LOCAL_FAIL:
528 case Profile::CREATE_STATUS_REMOTE_FAIL:
529 case Profile::CREATE_STATUS_CANCELED:
530 case Profile::MAX_CREATE_STATUS:
531 NOTREACHED();
532 break;
533 }
534 }
535
536 void LoginUtilsImpl::OnOTRProfileCreated(
537 const std::string& user_id,
538 Profile* user_profile,
539 Profile::CreateStatus status) {
540 CHECK(user_profile);
541
542 switch (status) {
543 case Profile::CREATE_STATUS_CREATED:
544 InitProfilePreferences(user_profile, user_id);
545 break;
546 case Profile::CREATE_STATUS_INITIALIZED:
547 OTRProfileInitialized(user_profile);
548 break;
549 case Profile::CREATE_STATUS_LOCAL_FAIL:
550 case Profile::CREATE_STATUS_REMOTE_FAIL:
551 case Profile::CREATE_STATUS_CANCELED:
552 case Profile::MAX_CREATE_STATUS:
553 NOTREACHED();
554 break;
555 }
556 }
557
558 void LoginUtilsImpl::UserProfileInitialized(Profile* user_profile) {
559 BootTimesLoader* btl = BootTimesLoader::Get();
560 btl->AddLoginTimeMarker("UserProfileGotten", false);
561
562 if (user_context_.IsUsingOAuth()) {
563 // Transfer proxy authentication cache, cookies (optionally) and server
564 // bound certs from the profile that was used for authentication. This
565 // profile contains cookies that auth extension should have already put in
566 // place that will ensure that the newly created session is authenticated
567 // for the websites that work with the used authentication schema.
568 ProfileAuthData::Transfer(authenticator_->authentication_profile(),
569 user_profile,
570 has_web_auth_cookies_, // transfer_cookies
571 base::Bind(
572 &LoginUtilsImpl::CompleteProfileCreate,
573 AsWeakPtr(),
574 user_profile));
575 return;
576 }
577
578 FinalizePrepareProfile(user_profile);
579 }
580
581 void LoginUtilsImpl::OTRProfileInitialized(Profile* user_profile) {
582 user_profile->OnLogin();
583 // Send the notification before creating the browser so additional objects
584 // that need the profile (e.g. the launcher) can be created first.
585 content::NotificationService::current()->Notify(
586 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
587 content::NotificationService::AllSources(),
588 content::Details<Profile>(user_profile));
589
590 if (delegate_)
591 delegate_->OnProfilePrepared(user_profile);
592 }
593
594 void LoginUtilsImpl::CompleteProfileCreate(Profile* user_profile) {
595 RestoreAuthSession(user_profile, has_web_auth_cookies_);
596 FinalizePrepareProfile(user_profile);
597 }
598
599 void LoginUtilsImpl::RestoreAuthSession(Profile* user_profile,
600 bool restore_from_auth_cookies) {
601 CHECK((authenticator_.get() && authenticator_->authentication_profile()) ||
602 !restore_from_auth_cookies);
603
604 if (chrome::IsRunningInForcedAppMode() ||
605 CommandLine::ForCurrentProcess()->HasSwitch(
606 chromeos::switches::kOobeSkipPostLogin)) {
607 return;
608 }
609
610 exit_after_session_restore_ = false;
611 // Remove legacy OAuth1 token if we have one. If it's valid, we should already
612 // have OAuth2 refresh token in OAuth2TokenService that could be used to
613 // retrieve all other tokens and user_context.
614 OAuth2LoginManager* login_manager =
615 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
616 login_manager->AddObserver(this);
617 login_manager->RestoreSession(
618 authenticator_.get() && authenticator_->authentication_profile()
619 ? authenticator_->authentication_profile()->GetRequestContext()
620 : NULL,
621 session_restore_strategy_,
622 oauth2_refresh_token_,
623 user_context_.GetAuthCode());
624 }
625
626 void LoginUtilsImpl::FinalizePrepareProfile(Profile* user_profile) {
627 BootTimesLoader* btl = BootTimesLoader::Get();
628 // Own TPM device if, for any reason, it has not been done in EULA
629 // wizard screen.
630 CryptohomeClient* client = DBusThreadManager::Get()->GetCryptohomeClient();
631 btl->AddLoginTimeMarker("TPMOwn-Start", false);
632 if (cryptohome_util::TpmIsEnabled() && !cryptohome_util::TpmIsBeingOwned()) {
633 if (cryptohome_util::TpmIsOwned()) {
634 client->CallTpmClearStoredPasswordAndBlock();
635 } else {
636 client->TpmCanAttemptOwnership(EmptyVoidDBusMethodCallback());
637 }
638 }
639 btl->AddLoginTimeMarker("TPMOwn-End", false);
640
641 if (UserManager::Get()->IsLoggedInAsRegularUser()) {
642 SAMLOfflineSigninLimiter* saml_offline_signin_limiter =
643 SAMLOfflineSigninLimiterFactory::GetForProfile(user_profile);
644 if (saml_offline_signin_limiter)
645 saml_offline_signin_limiter->SignedIn(user_context_.GetAuthFlow());
646 }
647
648 user_profile->OnLogin();
649
650 // Send the notification before creating the browser so additional objects
651 // that need the profile (e.g. the launcher) can be created first.
652 content::NotificationService::current()->Notify(
653 chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
654 content::NotificationService::AllSources(),
655 content::Details<Profile>(user_profile));
656
657 // Initialize RLZ only for primary user.
658 if (UserManager::Get()->GetPrimaryUser() ==
659 UserManager::Get()->GetUserByProfile(user_profile)) {
660 InitRlzDelayed(user_profile);
661 }
662 // TODO(altimofeev): This pointer should probably never be NULL, but it looks
663 // like LoginUtilsImpl::OnProfileCreated() may be getting called before
664 // LoginUtilsImpl::PrepareProfile() has set |delegate_| when Chrome is killed
665 // during shutdown in tests -- see http://crosbug.com/18269. Replace this
666 // 'if' statement with a CHECK(delegate_) once the underlying issue is
667 // resolved.
668 if (delegate_)
669 delegate_->OnProfilePrepared(user_profile);
670 }
671
672 void LoginUtilsImpl::InitRlzDelayed(Profile* user_profile) {
673 #if defined(ENABLE_RLZ)
674 if (!g_browser_process->local_state()->HasPrefPath(prefs::kRLZBrand)) {
675 // Read brand code asynchronously from an OEM data and repost ourselves.
676 google_brand::chromeos::InitBrand(
677 base::Bind(&LoginUtilsImpl::InitRlzDelayed, AsWeakPtr(), user_profile));
678 return;
679 }
680 base::PostTaskAndReplyWithResult(
681 base::WorkerPool::GetTaskRunner(false),
682 FROM_HERE,
683 base::Bind(&base::PathExists, GetRlzDisabledFlagPath()),
684 base::Bind(&LoginUtilsImpl::InitRlz, AsWeakPtr(), user_profile));
685 #endif
686 }
687
688 void LoginUtilsImpl::InitRlz(Profile* user_profile, bool disabled) {
689 #if defined(ENABLE_RLZ)
690 PrefService* local_state = g_browser_process->local_state();
691 if (disabled) {
692 // Empty brand code means an organic install (no RLZ pings are sent).
693 google_brand::chromeos::ClearBrandForCurrentSession();
694 }
695 if (disabled != local_state->GetBoolean(prefs::kRLZDisabled)) {
696 // When switching to RLZ enabled/disabled state, clear all recorded events.
697 RLZTracker::ClearRlzState();
698 local_state->SetBoolean(prefs::kRLZDisabled, disabled);
699 }
700 // Init the RLZ library.
701 int ping_delay = user_profile->GetPrefs()->GetInteger(
702 first_run::GetPingDelayPrefName().c_str());
703 // Negative ping delay means to send ping immediately after a first search is
704 // recorded.
705 RLZTracker::InitRlzFromProfileDelayed(
706 user_profile, UserManager::Get()->IsCurrentUserNew(),
707 ping_delay < 0, base::TimeDelta::FromMilliseconds(abs(ping_delay)));
708 if (delegate_)
709 delegate_->OnRlzInitialized(user_profile);
710 #endif
711 }
712
713 void LoginUtilsImpl::CompleteOffTheRecordLogin(const GURL& start_url) { 329 void LoginUtilsImpl::CompleteOffTheRecordLogin(const GURL& start_url) {
714 VLOG(1) << "Completing incognito login"; 330 VLOG(1) << "Completing incognito login";
715 331
716 // For guest session we ask session manager to restart Chrome with --bwsi 332 // For guest session we ask session manager to restart Chrome with --bwsi
717 // flag. We keep only some of the arguments of this process. 333 // flag. We keep only some of the arguments of this process.
718 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); 334 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
719 CommandLine command_line(browser_command_line.GetProgram()); 335 CommandLine command_line(browser_command_line.GetProgram());
720 std::string cmd_line_str = 336 std::string cmd_line_str =
721 GetOffTheRecordCommandLine(start_url, 337 GetOffTheRecordCommandLine(start_url,
722 StartupUtils::IsOobeCompleted(), 338 StartupUtils::IsOobeCompleted(),
723 browser_command_line, 339 browser_command_line,
724 &command_line); 340 &command_line);
725 341
726 RestartChrome(cmd_line_str); 342 RestartChrome(cmd_line_str);
727 } 343 }
728 344
729 void LoginUtilsImpl::SetFirstLoginPrefs(PrefService* prefs) {
730 VLOG(1) << "Setting first login prefs";
731 BootTimesLoader* btl = BootTimesLoader::Get();
732 std::string locale = g_browser_process->GetApplicationLocale();
733
734 // First, we'll set kLanguagePreloadEngines.
735 input_method::InputMethodManager* manager =
736 input_method::InputMethodManager::Get();
737 std::vector<std::string> input_method_ids;
738 manager->GetInputMethodUtil()->GetFirstLoginInputMethodIds(
739 locale, manager->GetCurrentInputMethod(), &input_method_ids);
740 // Save the input methods in the user's preferences.
741 StringPrefMember language_preload_engines;
742 language_preload_engines.Init(prefs::kLanguagePreloadEngines,
743 prefs);
744 language_preload_engines.SetValue(JoinString(input_method_ids, ','));
745 btl->AddLoginTimeMarker("IMEStarted", false);
746
747 // Second, we'll set kLanguagePreferredLanguages.
748 std::vector<std::string> language_codes;
749 // The current locale should be on the top.
750 language_codes.push_back(locale);
751
752 // Add input method IDs based on the input methods, as there may be
753 // input methods that are unrelated to the current locale. Example: the
754 // hardware keyboard layout xkb:us::eng is used for logging in, but the
755 // UI language is set to French. In this case, we should set "fr,en"
756 // to the preferred languages preference.
757 std::vector<std::string> candidates;
758 manager->GetInputMethodUtil()->GetLanguageCodesFromInputMethodIds(
759 input_method_ids, &candidates);
760 for (size_t i = 0; i < candidates.size(); ++i) {
761 const std::string& candidate = candidates[i];
762 // Skip if it's already in language_codes.
763 if (std::count(language_codes.begin(), language_codes.end(),
764 candidate) == 0) {
765 language_codes.push_back(candidate);
766 }
767 }
768 // Save the preferred languages in the user's preferences.
769 StringPrefMember language_preferred_languages;
770 language_preferred_languages.Init(prefs::kLanguagePreferredLanguages,
771 prefs);
772 language_preferred_languages.SetValue(JoinString(language_codes, ','));
773 }
774
775 scoped_refptr<Authenticator> LoginUtilsImpl::CreateAuthenticator( 345 scoped_refptr<Authenticator> LoginUtilsImpl::CreateAuthenticator(
776 LoginStatusConsumer* consumer) { 346 LoginStatusConsumer* consumer) {
777 // Screen locker needs new Authenticator instance each time. 347 // Screen locker needs new Authenticator instance each time.
778 if (ScreenLocker::default_screen_locker()) { 348 if (ScreenLocker::default_screen_locker()) {
779 if (authenticator_.get()) 349 if (authenticator_.get())
780 authenticator_->SetConsumer(NULL); 350 authenticator_->SetConsumer(NULL);
781 authenticator_ = NULL; 351 authenticator_ = NULL;
782 } 352 }
783 353
784 if (authenticator_.get() == NULL) { 354 if (authenticator_.get() == NULL) {
785 authenticator_ = new ParallelAuthenticator(consumer); 355 authenticator_ = new ParallelAuthenticator(consumer);
786 } else { 356 } else {
787 // TODO(nkostylev): Fix this hack by improving Authenticator dependencies. 357 // TODO(nkostylev): Fix this hack by improving Authenticator dependencies.
788 authenticator_->SetConsumer(consumer); 358 authenticator_->SetConsumer(consumer);
789 } 359 }
790 return authenticator_; 360 return authenticator_;
791 } 361 }
792 362
793 void LoginUtilsImpl::RestoreAuthenticationSession(Profile* user_profile) { 363 void LoginUtilsImpl::OnProfilePrepared(Profile* profile) {
794 UserManager* user_manager = UserManager::Get(); 364 if (delegate_)
795 // We don't need to restore session for demo/guest/stub/public account users. 365 delegate_->OnProfilePrepared(profile);
796 if (!user_manager->IsUserLoggedIn() ||
797 user_manager->IsLoggedInAsGuest() ||
798 user_manager->IsLoggedInAsPublicAccount() ||
799 user_manager->IsLoggedInAsDemoUser() ||
800 user_manager->IsLoggedInAsStub()) {
801 return;
802 }
803
804 User* user = user_manager->GetUserByProfile(user_profile);
805 DCHECK(user);
806 if (!net::NetworkChangeNotifier::IsOffline()) {
807 pending_restore_sessions_.erase(user->email());
808 RestoreAuthSession(user_profile, false);
809 } else {
810 // Even if we're online we should wait till initial
811 // OnConnectionTypeChanged() call. Otherwise starting fetchers too early may
812 // end up canceling all request when initial network connection type is
813 // processed. See http://crbug.com/121643.
814 pending_restore_sessions_.insert(user->email());
815 }
816 } 366 }
817 367
818 void LoginUtilsImpl::OnSessionRestoreStateChanged( 368 #if defined(ENABLE_RLZ)
819 Profile* user_profile, 369 void LoginUtilsImpl::OnRlzInitialized() {
820 OAuth2LoginManager::SessionRestoreState state) { 370 if (delegate_)
821 User::OAuthTokenStatus user_status = User::OAUTH_TOKEN_STATUS_UNKNOWN; 371 delegate_->OnRlzInitialized();
822 OAuth2LoginManager* login_manager =
823 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
824
825 bool connection_error = false;
826 switch (state) {
827 case OAuth2LoginManager::SESSION_RESTORE_DONE:
828 user_status = User::OAUTH2_TOKEN_STATUS_VALID;
829 break;
830 case OAuth2LoginManager::SESSION_RESTORE_FAILED:
831 user_status = User::OAUTH2_TOKEN_STATUS_INVALID;
832 break;
833 case OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED:
834 connection_error = true;
835 break;
836 case OAuth2LoginManager::SESSION_RESTORE_NOT_STARTED:
837 case OAuth2LoginManager::SESSION_RESTORE_PREPARING:
838 case OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS:
839 return;
840 }
841
842 // We should not be clearing existing token state if that was a connection
843 // error. http://crbug.com/295245
844 if (!connection_error) {
845 // We are in one of "done" states here.
846 UserManager::Get()->SaveUserOAuthStatus(
847 UserManager::Get()->GetLoggedInUser()->email(),
848 user_status);
849 }
850
851 login_manager->RemoveObserver(this);
852 } 372 }
853 373 #endif
854 void LoginUtilsImpl::OnNewRefreshTokenAvaiable(Profile* user_profile) {
855 // Check if we were waiting to restart chrome.
856 if (!exit_after_session_restore_)
857 return;
858
859 OAuth2LoginManager* login_manager =
860 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
861 login_manager->RemoveObserver(this);
862
863 // Mark user auth token status as valid.
864 UserManager::Get()->SaveUserOAuthStatus(
865 UserManager::Get()->GetLoggedInUser()->email(),
866 User::OAUTH2_TOKEN_STATUS_VALID);
867
868 LOG(WARNING) << "Exiting after new refresh token fetched";
869 // We need to restart cleanly in this case to make sure OAuth2 RT is actually
870 // saved.
871 chrome::AttemptRestart();
872 }
873
874 void LoginUtilsImpl::OnConnectionTypeChanged(
875 net::NetworkChangeNotifier::ConnectionType type) {
876 UserManager* user_manager = UserManager::Get();
877 if (type == net::NetworkChangeNotifier::CONNECTION_NONE ||
878 user_manager->IsLoggedInAsGuest() || !user_manager->IsUserLoggedIn()) {
879 return;
880 }
881
882 // Need to iterate over all users and their OAuth2 session state.
883 const UserList& users = user_manager->GetLoggedInUsers();
884 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
885 Profile* user_profile = user_manager->GetProfileByUser(*it);
886 bool should_restore_session =
887 pending_restore_sessions_.find((*it)->email()) !=
888 pending_restore_sessions_.end();
889 OAuth2LoginManager* login_manager =
890 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(user_profile);
891 if (login_manager->state() ==
892 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) {
893 // If we come online for the first time after successful offline login,
894 // we need to kick off OAuth token verification process again.
895 login_manager->ContinueSessionRestore();
896 } else if (should_restore_session) {
897 pending_restore_sessions_.erase((*it)->email());
898 RestoreAuthSession(user_profile, has_web_auth_cookies_);
899 }
900 }
901 }
902 374
903 void LoginUtilsImpl::AttemptRestart(Profile* profile) { 375 void LoginUtilsImpl::AttemptRestart(Profile* profile) {
904 if (session_restore_strategy_ != 376 if (SessionManager::GetInstance()->GetSigninSessionRestoreStrategy() !=
905 OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR) { 377 OAuth2LoginManager::RESTORE_FROM_COOKIE_JAR) {
906 chrome::AttemptRestart(); 378 chrome::AttemptRestart();
907 return; 379 return;
908 } 380 }
909 381
910 // We can't really quit if the session restore process that mints new 382 // We can't really quit if the session restore process that mints new
911 // refresh token is still in progress. 383 // refresh token is still in progress.
912 OAuth2LoginManager* login_manager = 384 OAuth2LoginManager* login_manager =
913 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile); 385 OAuth2LoginManagerFactory::GetInstance()->GetForProfile(profile);
914 if (login_manager->state() != 386 if (login_manager->state() !=
915 OAuth2LoginManager::SESSION_RESTORE_PREPARING && 387 OAuth2LoginManager::SESSION_RESTORE_PREPARING &&
916 login_manager->state() != 388 login_manager->state() !=
917 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) { 389 OAuth2LoginManager::SESSION_RESTORE_IN_PROGRESS) {
918 chrome::AttemptRestart(); 390 chrome::AttemptRestart();
919 return; 391 return;
920 } 392 }
921 393
922 LOG(WARNING) << "Attempting browser restart during session restore."; 394 LOG(WARNING) << "Attempting browser restart during session restore.";
923 exit_after_session_restore_ = true; 395 SessionManager::GetInstance()->set_exit_after_session_restore(true);
924 } 396 }
925 397
926 // static 398 // static
927 void LoginUtils::RegisterPrefs(PrefRegistrySimple* registry) {
928 registry->RegisterBooleanPref(prefs::kFactoryResetRequested, false);
929 registry->RegisterBooleanPref(prefs::kRollbackRequested, false);
930 registry->RegisterStringPref(prefs::kRLZBrand, std::string());
931 registry->RegisterBooleanPref(prefs::kRLZDisabled, false);
932 }
933
934 // static
935 LoginUtils* LoginUtils::Get() { 399 LoginUtils* LoginUtils::Get() {
936 return LoginUtilsWrapper::GetInstance()->get(); 400 return LoginUtilsWrapper::GetInstance()->get();
937 } 401 }
938 402
939 // static 403 // static
940 void LoginUtils::Set(LoginUtils* mock) { 404 void LoginUtils::Set(LoginUtils* mock) {
941 LoginUtilsWrapper::GetInstance()->reset(mock); 405 LoginUtilsWrapper::GetInstance()->reset(mock);
942 } 406 }
943 407
944 // static 408 // static
945 bool LoginUtils::IsWhitelisted(const std::string& username, 409 bool LoginUtils::IsWhitelisted(const std::string& username,
946 bool* wildcard_match) { 410 bool* wildcard_match) {
947 // Skip whitelist check for tests. 411 // Skip whitelist check for tests.
948 if (CommandLine::ForCurrentProcess()->HasSwitch( 412 if (CommandLine::ForCurrentProcess()->HasSwitch(
949 chromeos::switches::kOobeSkipPostLogin)) { 413 chromeos::switches::kOobeSkipPostLogin)) {
950 return true; 414 return true;
951 } 415 }
952 416
953 CrosSettings* cros_settings = CrosSettings::Get(); 417 CrosSettings* cros_settings = CrosSettings::Get();
954 bool allow_new_user = false; 418 bool allow_new_user = false;
955 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); 419 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user);
956 if (allow_new_user) 420 if (allow_new_user)
957 return true; 421 return true;
958 return cros_settings->FindEmailInList( 422 return cros_settings->FindEmailInList(
959 kAccountsPrefUsers, username, wildcard_match); 423 kAccountsPrefUsers, username, wildcard_match);
960 } 424 }
961 425
962 } // namespace chromeos 426 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/login_utils.h ('k') | chrome/browser/chromeos/login/login_utils_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698