Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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_performer.h" | 5 #include "chrome/browser/chromeos/login/login_performer.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | |
| 9 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 12 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 13 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 14 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
| 15 #include "chrome/browser/chromeos/boot_times_loader.h" | 16 #include "chrome/browser/chromeos/boot_times_loader.h" |
| 16 #include "chrome/browser/chromeos/cros/cros_library.h" | 17 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 17 #include "chrome/browser/chromeos/cros/screen_lock_library.h" | 18 #include "chrome/browser/chromeos/cros/screen_lock_library.h" |
| 19 #include "chrome/browser/chromeos/cros_settings.h" | |
| 18 #include "chrome/browser/chromeos/cros_settings_names.h" | 20 #include "chrome/browser/chromeos/cros_settings_names.h" |
| 19 #include "chrome/browser/chromeos/login/login_utils.h" | 21 #include "chrome/browser/chromeos/login/login_utils.h" |
| 20 #include "chrome/browser/chromeos/login/screen_locker.h" | 22 #include "chrome/browser/chromeos/login/screen_locker.h" |
| 21 #include "chrome/browser/chromeos/user_cros_settings_provider.h" | |
| 22 #include "chrome/browser/prefs/pref_service.h" | 23 #include "chrome/browser/prefs/pref_service.h" |
| 23 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
| 24 #include "chrome/browser/profiles/profile_manager.h" | 25 #include "chrome/browser/profiles/profile_manager.h" |
| 25 #include "chrome/common/chrome_notification_types.h" | 26 #include "chrome/common/chrome_notification_types.h" |
| 26 #include "chrome/common/chrome_switches.h" | 27 #include "chrome/common/chrome_switches.h" |
| 27 #include "chrome/common/pref_names.h" | 28 #include "chrome/common/pref_names.h" |
| 28 #include "content/browser/browser_thread.h" | 29 #include "content/browser/browser_thread.h" |
| 29 #include "content/browser/user_metrics.h" | 30 #include "content/browser/user_metrics.h" |
| 30 #include "content/common/content_notification_types.h" | 31 #include "content/common/content_notification_types.h" |
| 31 #include "content/common/notification_service.h" | 32 #include "content/common/notification_service.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 48 delegate_(delegate), | 49 delegate_(delegate), |
| 49 password_changed_(false), | 50 password_changed_(false), |
| 50 screen_lock_requested_(false), | 51 screen_lock_requested_(false), |
| 51 initial_online_auth_pending_(false), | 52 initial_online_auth_pending_(false), |
| 52 auth_mode_(AUTH_MODE_INTERNAL), | 53 auth_mode_(AUTH_MODE_INTERNAL), |
| 53 using_oauth_( | 54 using_oauth_( |
| 54 CommandLine::ForCurrentProcess()->HasSwitch( | 55 CommandLine::ForCurrentProcess()->HasSwitch( |
| 55 switches::kWebUILogin) && | 56 switches::kWebUILogin) && |
| 56 !CommandLine::ForCurrentProcess()->HasSwitch( | 57 !CommandLine::ForCurrentProcess()->HasSwitch( |
| 57 switches::kSkipOAuthLogin)), | 58 switches::kSkipOAuthLogin)), |
| 58 method_factory_(this) { | 59 pointer_factory_(this) { |
| 59 DCHECK(default_performer_ == NULL) | 60 DCHECK(default_performer_ == NULL) |
| 60 << "LoginPerformer should have only one instance."; | 61 << "LoginPerformer should have only one instance."; |
| 61 default_performer_ = this; | 62 default_performer_ = this; |
| 62 } | 63 } |
| 63 | 64 |
| 64 LoginPerformer::~LoginPerformer() { | 65 LoginPerformer::~LoginPerformer() { |
| 65 DVLOG(1) << "Deleting LoginPerformer"; | 66 DVLOG(1) << "Deleting LoginPerformer"; |
| 66 DCHECK(default_performer_ != NULL) << "Default instance should exist."; | 67 DCHECK(default_performer_ != NULL) << "Default instance should exist."; |
| 67 default_performer_ = NULL; | 68 default_performer_ = NULL; |
| 68 } | 69 } |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 last_login_failure_ = | 220 last_login_failure_ = |
| 220 LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError( | 221 LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError( |
| 221 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); | 222 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); |
| 222 password_changed_ = true; | 223 password_changed_ = true; |
| 223 DVLOG(1) << "Password change detected - locking screen."; | 224 DVLOG(1) << "Password change detected - locking screen."; |
| 224 RequestScreenLock(); | 225 RequestScreenLock(); |
| 225 } | 226 } |
| 226 } | 227 } |
| 227 | 228 |
| 228 //////////////////////////////////////////////////////////////////////////////// | 229 //////////////////////////////////////////////////////////////////////////////// |
| 229 // LoginPerformer, SignedSettingsHelper::Callback implementation: | |
| 230 | |
| 231 void LoginPerformer::OnCheckWhitelistCompleted(SignedSettings::ReturnCode code, | |
| 232 const std::string& email) { | |
| 233 if (code == SignedSettings::SUCCESS) { | |
| 234 // Whitelist check passed, continue with authentication. | |
| 235 if (auth_mode_ == AUTH_MODE_EXTENSION) { | |
| 236 StartLoginCompletion(); | |
| 237 } else { | |
| 238 StartAuthentication(); | |
| 239 } | |
| 240 } else { | |
| 241 if (delegate_) | |
| 242 delegate_->WhiteListCheckFailed(email); | |
| 243 else | |
| 244 NOTREACHED(); | |
| 245 } | |
| 246 } | |
| 247 | |
| 248 //////////////////////////////////////////////////////////////////////////////// | |
| 249 // LoginPerformer, NotificationObserver implementation: | 230 // LoginPerformer, NotificationObserver implementation: |
| 250 // | 231 // |
| 251 | 232 |
| 252 void LoginPerformer::Observe(int type, | 233 void LoginPerformer::Observe(int type, |
| 253 const NotificationSource& source, | 234 const NotificationSource& source, |
| 254 const NotificationDetails& details) { | 235 const NotificationDetails& details) { |
| 255 if (type != chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED) | 236 if (type != chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED) |
| 256 return; | 237 return; |
| 257 | 238 |
| 258 bool is_screen_locked = *Details<bool>(details).ptr(); | 239 bool is_screen_locked = *Details<bool>(details).ptr(); |
| 259 if (is_screen_locked) { | 240 if (is_screen_locked) { |
| 260 if (screen_lock_requested_) { | 241 if (screen_lock_requested_) { |
| 261 screen_lock_requested_ = false; | 242 screen_lock_requested_ = false; |
| 262 ResolveScreenLocked(); | 243 ResolveScreenLocked(); |
| 263 } | 244 } |
| 264 } else { | 245 } else { |
| 265 ResolveScreenUnlocked(); | 246 ResolveScreenUnlocked(); |
| 266 } | 247 } |
| 267 } | 248 } |
| 268 | 249 |
| 269 //////////////////////////////////////////////////////////////////////////////// | 250 //////////////////////////////////////////////////////////////////////////////// |
| 270 // LoginPerformer, public: | 251 // LoginPerformer, public: |
| 271 void LoginPerformer::CompleteLogin(const std::string& username, | 252 void LoginPerformer::CompleteLogin(const std::string& username, |
| 272 const std::string& password) { | 253 const std::string& password) { |
| 273 auth_mode_ = AUTH_MODE_EXTENSION; | 254 auth_mode_ = AUTH_MODE_EXTENSION; |
| 274 username_ = username; | 255 username_ = username; |
| 275 password_ = password; | 256 password_ = password; |
| 257 | |
| 258 CrosSettings* cros_settings = CrosSettings::Get(); | |
| 259 | |
| 276 // Whitelist check is always performed during initial login and | 260 // Whitelist check is always performed during initial login and |
| 277 // should not be performed when ScreenLock is active (pending online auth). | 261 // should not be performed when ScreenLock is active (pending online auth). |
| 278 if (!ScreenLocker::default_screen_locker()) { | 262 if (!ScreenLocker::default_screen_locker()) { |
| 279 // Must not proceed without signature verification. | 263 // Must not proceed without signature verification or valid user list. |
| 280 UserCrosSettingsProvider user_settings; | 264 bool trusted_settings_available = |
| 281 bool trusted_setting_available = user_settings.RequestTrustedAllowNewUser( | 265 cros_settings->GetTrusted( |
| 282 method_factory_.NewRunnableMethod(&LoginPerformer::CompleteLogin, | 266 kAccountsPrefAllowNewUser, |
| 283 username, | 267 base::Bind(&LoginPerformer::CompleteLogin, |
| 284 password)); | 268 pointer_factory_.GetWeakPtr(), |
| 285 if (!trusted_setting_available) { | 269 username, password)); |
| 270 if (!trusted_settings_available) { | |
| 286 // Value of AllowNewUser setting is still not verified. | 271 // Value of AllowNewUser setting is still not verified. |
| 287 // Another attempt will be invoked after verification completion. | 272 // Another attempt will be invoked after verification completion. |
| 288 return; | 273 return; |
| 289 } | 274 } |
| 290 } | 275 } |
| 291 | 276 |
| 292 if (ScreenLocker::default_screen_locker() || | 277 bool allow_new_user = false; |
| 293 UserCrosSettingsProvider::cached_allow_new_user()) { | 278 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); |
| 279 if (ScreenLocker::default_screen_locker() || allow_new_user) { | |
| 294 // Starts authentication if guest login is allowed or online auth pending. | 280 // Starts authentication if guest login is allowed or online auth pending. |
| 295 StartLoginCompletion(); | 281 StartLoginCompletion(); |
| 296 } else { | 282 } else { |
| 297 // Otherwise, do whitelist check first. | 283 const base::ListValue *user_list; |
|
Chris Masone
2011/10/05 18:43:12
Can we keep the comment here, explaining that this
pastarmovj
2011/10/13 11:23:02
Done.
| |
| 298 PrefService* local_state = g_browser_process->local_state(); | 284 base::StringValue username_value(username); |
| 299 CHECK(local_state); | 285 if (cros_settings->GetList(kAccountsPrefUsers, &user_list) && |
|
Chris Masone
2011/10/05 18:43:12
Where is the whitelist check now?
pastarmovj
2011/10/13 11:23:02
Line 285 fetches the whitelist from the UserCrosSe
| |
| 300 if (local_state->IsManagedPreference(kAccountsPrefUsers)) { | 286 user_list->Find(username_value) != user_list->end()) { |
| 301 if (UserCrosSettingsProvider::IsEmailInCachedWhitelist(username)) { | 287 StartLoginCompletion(); |
| 302 StartLoginCompletion(); | |
| 303 } else { | |
| 304 if (delegate_) | |
| 305 delegate_->WhiteListCheckFailed(username); | |
| 306 else | |
| 307 NOTREACHED(); | |
| 308 } | |
| 309 } else { | 288 } else { |
| 310 // In case of signed settings: with current implementation we do not | 289 if (delegate_) |
| 311 // trust whitelist returned by PrefService. So make separate check. | 290 delegate_->WhiteListCheckFailed(username); |
| 312 SignedSettingsHelper::Get()->StartCheckWhitelistOp( | 291 else |
| 313 username, this); | 292 NOTREACHED(); |
| 314 } | 293 } |
| 315 } | 294 } |
| 316 } | 295 } |
| 317 | 296 |
| 318 void LoginPerformer::Login(const std::string& username, | 297 void LoginPerformer::Login(const std::string& username, |
| 319 const std::string& password) { | 298 const std::string& password) { |
| 320 auth_mode_ = AUTH_MODE_INTERNAL; | 299 auth_mode_ = AUTH_MODE_INTERNAL; |
| 321 username_ = username; | 300 username_ = username; |
| 322 password_ = password; | 301 password_ = password; |
| 323 | 302 |
| 303 CrosSettings* cros_settings = CrosSettings::Get(); | |
| 304 | |
| 324 // Whitelist check is always performed during initial login and | 305 // Whitelist check is always performed during initial login and |
| 325 // should not be performed when ScreenLock is active (pending online auth). | 306 // should not be performed when ScreenLock is active (pending online auth). |
| 326 if (!ScreenLocker::default_screen_locker()) { | 307 if (!ScreenLocker::default_screen_locker()) { |
| 327 // Must not proceed without signature verification. | 308 // Must not proceed without signature verification. |
| 328 UserCrosSettingsProvider user_settings; | 309 bool trusted_settings_available = |
| 329 bool trusted_setting_available = user_settings.RequestTrustedAllowNewUser( | 310 cros_settings->GetTrusted( |
| 330 method_factory_.NewRunnableMethod(&LoginPerformer::Login, | 311 kAccountsPrefAllowNewUser, |
| 331 username, | 312 base::Bind(&LoginPerformer::CompleteLogin, |
|
Chris Masone
2011/10/05 18:43:12
This used to call Login again, not CompleteLogin
pastarmovj
2011/10/13 11:23:02
True sorry this was copy paste error :(
| |
| 332 password)); | 313 pointer_factory_.GetWeakPtr(), |
| 333 if (!trusted_setting_available) { | 314 username, password)); |
| 315 if (!trusted_settings_available) { | |
| 334 // Value of AllowNewUser setting is still not verified. | 316 // Value of AllowNewUser setting is still not verified. |
| 335 // Another attempt will be invoked after verification completion. | 317 // Another attempt will be invoked after verification completion. |
| 336 return; | 318 return; |
| 337 } | 319 } |
| 338 } | 320 } |
| 339 | 321 |
| 340 if (ScreenLocker::default_screen_locker() || | 322 bool allow_new_user = false; |
| 341 UserCrosSettingsProvider::cached_allow_new_user()) { | 323 cros_settings->GetBoolean(kAccountsPrefAllowNewUser, &allow_new_user); |
| 324 if (ScreenLocker::default_screen_locker() || allow_new_user) { | |
| 342 // Starts authentication if guest login is allowed or online auth pending. | 325 // Starts authentication if guest login is allowed or online auth pending. |
| 343 StartAuthentication(); | 326 StartAuthentication(); |
| 344 } else { | 327 } else { |
| 345 // Otherwise, do whitelist check first. | 328 const base::ListValue *user_list; |
| 346 PrefService* local_state = g_browser_process->local_state(); | 329 base::StringValue username_value(username); |
| 347 CHECK(local_state); | 330 if (cros_settings->GetList(kAccountsPrefUsers, &user_list) && |
| 348 if (local_state->IsManagedPreference(kAccountsPrefUsers)) { | 331 user_list->Find(username_value) != user_list->end()) { |
| 349 if (UserCrosSettingsProvider::IsEmailInCachedWhitelist(username)) { | 332 StartAuthentication(); |
| 350 StartAuthentication(); | |
| 351 } else { | |
| 352 if (delegate_) | |
| 353 delegate_->WhiteListCheckFailed(username); | |
| 354 else | |
| 355 NOTREACHED(); | |
| 356 } | |
| 357 } else { | 333 } else { |
| 358 // In case of signed settings: with current implementation we do not | 334 if (delegate_) |
| 359 // trust whitelist returned by PrefService. So make separate check. | 335 delegate_->WhiteListCheckFailed(username); |
| 360 SignedSettingsHelper::Get()->StartCheckWhitelistOp( | 336 else |
| 361 username, this); | 337 NOTREACHED(); |
| 362 } | 338 } |
| 363 } | 339 } |
| 364 } | 340 } |
| 365 | 341 |
| 366 void LoginPerformer::LoginOffTheRecord() { | 342 void LoginPerformer::LoginOffTheRecord() { |
| 367 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); | 343 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); |
| 368 BrowserThread::PostTask( | 344 BrowserThread::PostTask( |
| 369 BrowserThread::UI, FROM_HERE, | 345 BrowserThread::UI, FROM_HERE, |
| 370 NewRunnableMethod(authenticator_.get(), | 346 base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get())); |
| 371 &Authenticator::LoginOffTheRecord)); | |
| 372 } | 347 } |
| 373 | 348 |
| 374 void LoginPerformer::RecoverEncryptedData(const std::string& old_password) { | 349 void LoginPerformer::RecoverEncryptedData(const std::string& old_password) { |
| 375 BrowserThread::PostTask( | 350 BrowserThread::PostTask( |
| 376 BrowserThread::UI, FROM_HERE, | 351 BrowserThread::UI, FROM_HERE, |
| 377 NewRunnableMethod(authenticator_.get(), | 352 base::Bind(&Authenticator::RecoverEncryptedData, authenticator_.get(), |
| 378 &Authenticator::RecoverEncryptedData, | 353 old_password, |
| 379 old_password, | 354 cached_credentials_)); |
| 380 cached_credentials_)); | |
| 381 cached_credentials_ = GaiaAuthConsumer::ClientLoginResult(); | 355 cached_credentials_ = GaiaAuthConsumer::ClientLoginResult(); |
| 382 } | 356 } |
| 383 | 357 |
| 384 void LoginPerformer::ResyncEncryptedData() { | 358 void LoginPerformer::ResyncEncryptedData() { |
| 385 BrowserThread::PostTask( | 359 BrowserThread::PostTask( |
| 386 BrowserThread::UI, FROM_HERE, | 360 BrowserThread::UI, FROM_HERE, |
| 387 NewRunnableMethod(authenticator_.get(), | 361 base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get(), |
| 388 &Authenticator::ResyncEncryptedData, | 362 cached_credentials_)); |
| 389 cached_credentials_)); | |
| 390 cached_credentials_ = GaiaAuthConsumer::ClientLoginResult(); | 363 cached_credentials_ = GaiaAuthConsumer::ClientLoginResult(); |
| 391 } | 364 } |
| 392 | 365 |
| 393 //////////////////////////////////////////////////////////////////////////////// | 366 //////////////////////////////////////////////////////////////////////////////// |
| 394 // LoginPerformer, private: | 367 // LoginPerformer, private: |
| 395 | 368 |
| 396 void LoginPerformer::RequestScreenLock() { | 369 void LoginPerformer::RequestScreenLock() { |
| 397 DVLOG(1) << "Screen lock requested"; | 370 DVLOG(1) << "Screen lock requested"; |
| 398 // Will receive notifications on screen unlock and delete itself. | 371 // Will receive notifications on screen unlock and delete itself. |
| 399 registrar_.Add(this, | 372 registrar_.Add(this, |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 544 } | 517 } |
| 545 | 518 |
| 546 void LoginPerformer::StartLoginCompletion() { | 519 void LoginPerformer::StartLoginCompletion() { |
| 547 DVLOG(1) << "Login completion started"; | 520 DVLOG(1) << "Login completion started"; |
| 548 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); | 521 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); |
| 549 Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); | 522 Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); |
| 550 | 523 |
| 551 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); | 524 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); |
| 552 BrowserThread::PostTask( | 525 BrowserThread::PostTask( |
| 553 BrowserThread::UI, FROM_HERE, | 526 BrowserThread::UI, FROM_HERE, |
| 554 NewRunnableMethod(authenticator_.get(), | 527 base::Bind(&Authenticator::CompleteLogin, authenticator_.get(), |
| 555 &Authenticator::CompleteLogin, | 528 profile, |
| 556 profile, | 529 username_, |
| 557 username_, | 530 password_)); |
| 558 password_)); | |
| 559 | 531 |
| 560 password_.clear(); | 532 password_.clear(); |
| 561 } | 533 } |
| 562 | 534 |
| 563 void LoginPerformer::StartAuthentication() { | 535 void LoginPerformer::StartAuthentication() { |
| 564 DVLOG(1) << "Auth started"; | 536 DVLOG(1) << "Auth started"; |
| 565 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); | 537 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); |
| 566 Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); | 538 Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile(); |
| 567 if (delegate_) { | 539 if (delegate_) { |
| 568 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); | 540 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); |
| 569 BrowserThread::PostTask( | 541 BrowserThread::PostTask( |
| 570 BrowserThread::UI, FROM_HERE, | 542 BrowserThread::UI, FROM_HERE, |
| 571 NewRunnableMethod(authenticator_.get(), | 543 base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(), |
| 572 &Authenticator::AuthenticateToLogin, | 544 profile, |
| 573 profile, | 545 username_, |
| 574 username_, | 546 password_, |
| 575 password_, | 547 captcha_token_, |
| 576 captcha_token_, | 548 captcha_)); |
| 577 captcha_)); | |
| 578 } else { | 549 } else { |
| 579 DCHECK(authenticator_.get()) | 550 DCHECK(authenticator_.get()) |
| 580 << "Authenticator instance doesn't exist for login attempt retry."; | 551 << "Authenticator instance doesn't exist for login attempt retry."; |
| 581 // At this point offline auth has been successful, | 552 // At this point offline auth has been successful, |
| 582 // retry online auth, using existing Authenticator instance. | 553 // retry online auth, using existing Authenticator instance. |
| 583 BrowserThread::PostTask( | 554 BrowserThread::PostTask( |
| 584 BrowserThread::UI, FROM_HERE, | 555 BrowserThread::UI, FROM_HERE, |
| 585 NewRunnableMethod(authenticator_.get(), | 556 base::Bind(&Authenticator::RetryAuth, authenticator_.get(), |
| 586 &Authenticator::RetryAuth, | 557 profile, |
| 587 profile, | 558 username_, |
| 588 username_, | 559 password_, |
| 589 password_, | 560 captcha_token_, |
| 590 captcha_token_, | 561 captcha_)); |
| 591 captcha_)); | |
| 592 } | 562 } |
| 593 password_.clear(); | 563 password_.clear(); |
| 594 } | 564 } |
| 595 | 565 |
| 596 } // namespace chromeos | 566 } // namespace chromeos |
| OLD | NEW |