| OLD | NEW |
| 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_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/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 15 #include "base/threading/thread_restrictions.h" | 15 #include "base/threading/thread_restrictions.h" |
| 16 #include "chrome/browser/browser_process.h" | 16 #include "chrome/browser/browser_process.h" |
| 17 #include "chrome/browser/chrome_notification_types.h" | 17 #include "chrome/browser/chrome_notification_types.h" |
| 18 #include "chrome/browser/chromeos/boot_times_loader.h" | 18 #include "chrome/browser/chromeos/boot_times_loader.h" |
| 19 #include "chrome/browser/chromeos/login/login_utils.h" | 19 #include "chrome/browser/chromeos/login/login_utils.h" |
| 20 #include "chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.
h" | 20 #include "chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.
h" |
| 21 #include "chrome/browser/chromeos/login/screen_locker.h" | |
| 22 #include "chrome/browser/chromeos/login/user_manager.h" | 21 #include "chrome/browser/chromeos/login/user_manager.h" |
| 23 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" | 22 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" |
| 24 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 23 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 25 #include "chrome/browser/chromeos/settings/cros_settings.h" | 24 #include "chrome/browser/chromeos/settings/cros_settings.h" |
| 26 #include "chrome/browser/chromeos/settings/cros_settings_names.h" | 25 #include "chrome/browser/chromeos/settings/cros_settings_names.h" |
| 27 #include "chrome/browser/policy/browser_policy_connector.h" | 26 #include "chrome/browser/policy/browser_policy_connector.h" |
| 28 #include "chrome/common/pref_names.h" | 27 #include "chrome/common/pref_names.h" |
| 29 #include "chromeos/dbus/dbus_thread_manager.h" | 28 #include "chromeos/dbus/dbus_thread_manager.h" |
| 30 #include "chromeos/dbus/session_manager_client.h" | 29 #include "chromeos/dbus/session_manager_client.h" |
| 31 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 32 #include "content/public/browser/notification_service.h" | 31 #include "content/public/browser/notification_service.h" |
| 33 #include "content/public/browser/notification_types.h" | 32 #include "content/public/browser/notification_types.h" |
| 34 #include "content/public/browser/user_metrics.h" | 33 #include "content/public/browser/user_metrics.h" |
| 35 #include "google_apis/gaia/gaia_auth_util.h" | 34 #include "google_apis/gaia/gaia_auth_util.h" |
| 36 #include "grit/generated_resources.h" | 35 #include "grit/generated_resources.h" |
| 37 #include "net/cookies/cookie_monster.h" | 36 #include "net/cookies/cookie_monster.h" |
| 38 #include "net/cookies/cookie_store.h" | 37 #include "net/cookies/cookie_store.h" |
| 39 #include "net/url_request/url_request_context.h" | 38 #include "net/url_request/url_request_context.h" |
| 40 #include "net/url_request/url_request_context_getter.h" | 39 #include "net/url_request/url_request_context_getter.h" |
| 41 #include "ui/base/l10n/l10n_util.h" | 40 #include "ui/base/l10n/l10n_util.h" |
| 42 #include "ui/base/resource/resource_bundle.h" | 41 #include "ui/base/resource/resource_bundle.h" |
| 43 | 42 |
| 44 using content::BrowserThread; | 43 using content::BrowserThread; |
| 45 using content::UserMetricsAction; | 44 using content::UserMetricsAction; |
| 46 | 45 |
| 47 namespace chromeos { | 46 namespace chromeos { |
| 48 | 47 |
| 49 // Initialize default LoginPerformer. | |
| 50 // static | |
| 51 LoginPerformer* LoginPerformer::default_performer_ = NULL; | |
| 52 | |
| 53 LoginPerformer::LoginPerformer(Delegate* delegate) | 48 LoginPerformer::LoginPerformer(Delegate* delegate) |
| 54 : online_attempt_host_(this), | 49 : online_attempt_host_(this), |
| 55 last_login_failure_(LoginFailure::LoginFailureNone()), | 50 last_login_failure_(LoginFailure::LoginFailureNone()), |
| 56 delegate_(delegate), | 51 delegate_(delegate), |
| 57 password_changed_(false), | 52 password_changed_(false), |
| 58 password_changed_callback_count_(0), | 53 password_changed_callback_count_(0), |
| 59 screen_lock_requested_(false), | |
| 60 initial_online_auth_pending_(false), | |
| 61 auth_mode_(AUTH_MODE_INTERNAL), | 54 auth_mode_(AUTH_MODE_INTERNAL), |
| 62 weak_factory_(this) { | 55 weak_factory_(this) { |
| 63 DCHECK(default_performer_ == NULL) | |
| 64 << "LoginPerformer should have only one instance."; | |
| 65 default_performer_ = this; | |
| 66 } | 56 } |
| 67 | 57 |
| 68 LoginPerformer::~LoginPerformer() { | 58 LoginPerformer::~LoginPerformer() { |
| 69 DVLOG(1) << "Deleting LoginPerformer"; | 59 DVLOG(1) << "Deleting LoginPerformer"; |
| 70 DCHECK(default_performer_ != NULL) << "Default instance should exist."; | |
| 71 default_performer_ = NULL; | |
| 72 if (authenticator_.get()) | 60 if (authenticator_.get()) |
| 73 authenticator_->SetConsumer(NULL); | 61 authenticator_->SetConsumer(NULL); |
| 74 } | 62 } |
| 75 | 63 |
| 76 //////////////////////////////////////////////////////////////////////////////// | 64 //////////////////////////////////////////////////////////////////////////////// |
| 77 // LoginPerformer, LoginStatusConsumer implementation: | 65 // LoginPerformer, LoginStatusConsumer implementation: |
| 78 | 66 |
| 79 void LoginPerformer::OnLoginFailure(const LoginFailure& failure) { | 67 void LoginPerformer::OnLoginFailure(const LoginFailure& failure) { |
| 80 content::RecordAction(UserMetricsAction("Login_Failure")); | 68 content::RecordAction(UserMetricsAction("Login_Failure")); |
| 81 UMA_HISTOGRAM_ENUMERATION("Login.FailureReason", failure.reason(), | 69 UMA_HISTOGRAM_ENUMERATION("Login.FailureReason", failure.reason(), |
| 82 LoginFailure::NUM_FAILURE_REASONS); | 70 LoginFailure::NUM_FAILURE_REASONS); |
| 83 | 71 |
| 84 DVLOG(1) << "failure.reason " << failure.reason(); | 72 DVLOG(1) << "failure.reason " << failure.reason(); |
| 85 DVLOG(1) << "failure.error.state " << failure.error().state(); | 73 DVLOG(1) << "failure.error.state " << failure.error().state(); |
| 86 | 74 |
| 87 last_login_failure_ = failure; | 75 last_login_failure_ = failure; |
| 88 if (delegate_) { | 76 if (delegate_) { |
| 89 delegate_->OnLoginFailure(failure); | 77 delegate_->OnLoginFailure(failure); |
| 90 return; | 78 return; |
| 91 } | |
| 92 | |
| 93 // Consequent online login failure with blocking UI on. | |
| 94 // No difference between cases whether screen was locked by the user or | |
| 95 // by LoginPerformer except for the very first screen lock while waiting | |
| 96 // for online auth. Otherwise it will be SL active > timeout > screen unlock. | |
| 97 // Display recoverable error message using ScreenLocker, | |
| 98 // force sign out otherwise. | |
| 99 if (ScreenLocker::default_screen_locker() && !initial_online_auth_pending_) { | |
| 100 ResolveLockLoginFailure(); | |
| 101 return; | |
| 102 } | |
| 103 initial_online_auth_pending_ = false; | |
| 104 | |
| 105 // Offline auth - OK, online auth - failed. | |
| 106 if (failure.reason() == LoginFailure::NETWORK_AUTH_FAILED) { | |
| 107 ResolveInitialNetworkAuthFailure(); | |
| 108 } else if (failure.reason() == LoginFailure::LOGIN_TIMED_OUT) { | |
| 109 VLOG(1) << "Online login timed out. " | |
| 110 << "Granting user access based on offline auth only."; | |
| 111 // ScreenLock is not active, it's ok to delete itself. | |
| 112 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | |
| 113 } else { | 79 } else { |
| 114 // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS: | 80 // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS: |
| 115 // happens during offline auth only. | 81 // happens during offline auth only. |
| 116 // UNLOCK_FAILED is used during normal screen lock case. | |
| 117 // TODO(nkostylev) DATA_REMOVAL_FAILED - ? | |
| 118 NOTREACHED(); | 82 NOTREACHED(); |
| 119 } | 83 } |
| 120 } | 84 } |
| 121 | 85 |
| 122 void LoginPerformer::OnRetailModeLoginSuccess( | 86 void LoginPerformer::OnRetailModeLoginSuccess( |
| 123 const UserContext& user_context) { | 87 const UserContext& user_context) { |
| 124 content::RecordAction( | 88 content::RecordAction( |
| 125 UserMetricsAction("Login_DemoUserLoginSuccess")); | 89 UserMetricsAction("Login_DemoUserLoginSuccess")); |
| 126 LoginStatusConsumer::OnRetailModeLoginSuccess(user_context); | 90 LoginStatusConsumer::OnRetailModeLoginSuccess(user_context); |
| 127 } | 91 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 139 // - or - | 103 // - or - |
| 140 // Public account user, login successful. | 104 // Public account user, login successful. |
| 141 // 1 - Existing regular user, login success offline only. | 105 // 1 - Existing regular user, login success offline only. |
| 142 UMA_HISTOGRAM_ENUMERATION("Login.SuccessReason", pending_requests, 2); | 106 UMA_HISTOGRAM_ENUMERATION("Login.SuccessReason", pending_requests, 2); |
| 143 | 107 |
| 144 VLOG(1) << "LoginSuccess hash: " << user_context.username_hash | 108 VLOG(1) << "LoginSuccess hash: " << user_context.username_hash |
| 145 << ", pending_requests " << pending_requests; | 109 << ", pending_requests " << pending_requests; |
| 146 DCHECK(delegate_); | 110 DCHECK(delegate_); |
| 147 // After delegate_->OnLoginSuccess(...) is called, delegate_ releases | 111 // After delegate_->OnLoginSuccess(...) is called, delegate_ releases |
| 148 // LoginPerformer ownership. LP now manages it's lifetime on its own. | 112 // LoginPerformer ownership. LP now manages it's lifetime on its own. |
| 149 // 2 things could make it exist longer: | 113 DCHECK(!pending_requests); |
| 150 // 1. ScreenLock active (pending correct new password input) | 114 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 151 // 2. Pending online auth request. | |
| 152 if (!pending_requests) | |
| 153 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | |
| 154 else | |
| 155 initial_online_auth_pending_ = true; | |
| 156 | 115 |
| 157 delegate_->OnLoginSuccess(user_context, | 116 delegate_->OnLoginSuccess(user_context, |
| 158 pending_requests, | 117 pending_requests, |
| 159 using_oauth); | 118 using_oauth); |
| 160 } | 119 } |
| 161 | 120 |
| 162 void LoginPerformer::OnOffTheRecordLoginSuccess() { | 121 void LoginPerformer::OnOffTheRecordLoginSuccess() { |
| 163 content::RecordAction( | 122 content::RecordAction( |
| 164 UserMetricsAction("Login_GuestLoginSuccess")); | 123 UserMetricsAction("Login_GuestLoginSuccess")); |
| 165 | 124 |
| 166 if (delegate_) | 125 if (delegate_) |
| 167 delegate_->OnOffTheRecordLoginSuccess(); | 126 delegate_->OnOffTheRecordLoginSuccess(); |
| 168 else | 127 else |
| 169 NOTREACHED(); | 128 NOTREACHED(); |
| 170 } | 129 } |
| 171 | 130 |
| 172 void LoginPerformer::OnPasswordChangeDetected() { | 131 void LoginPerformer::OnPasswordChangeDetected() { |
| 173 password_changed_ = true; | 132 password_changed_ = true; |
| 174 password_changed_callback_count_++; | 133 password_changed_callback_count_++; |
| 175 if (delegate_) { | 134 if (delegate_) { |
| 176 delegate_->OnPasswordChangeDetected(); | 135 delegate_->OnPasswordChangeDetected(); |
| 177 } else { | 136 } else { |
| 178 last_login_failure_ = | 137 NOTREACHED(); |
| 179 LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError( | |
| 180 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); | |
| 181 DVLOG(1) << "Password change detected - locking screen."; | |
| 182 RequestScreenLock(); | |
| 183 } | 138 } |
| 184 } | 139 } |
| 185 | 140 |
| 186 void LoginPerformer::OnChecked(const std::string& username, bool success) { | 141 void LoginPerformer::OnChecked(const std::string& username, bool success) { |
| 187 if (!delegate_) { | 142 if (!delegate_) { |
| 188 // Delegate is reset in case of successful offline login. | 143 // Delegate is reset in case of successful offline login. |
| 189 // See ExistingUserConstoller::OnLoginSuccess(). | 144 // See ExistingUserConstoller::OnLoginSuccess(). |
| 190 // Case when user has changed password and enters old password | 145 // Case when user has changed password and enters old password |
| 191 // does not block user from sign in yet. | 146 // does not block user from sign in yet. |
| 192 return; | 147 return; |
| 193 } | 148 } |
| 194 delegate_->OnOnlineChecked(username, success); | 149 delegate_->OnOnlineChecked(username, success); |
| 195 } | 150 } |
| 196 | 151 |
| 197 //////////////////////////////////////////////////////////////////////////////// | 152 //////////////////////////////////////////////////////////////////////////////// |
| 198 // LoginPerformer, content::NotificationObserver implementation: | |
| 199 // | |
| 200 | |
| 201 void LoginPerformer::Observe(int type, | |
| 202 const content::NotificationSource& source, | |
| 203 const content::NotificationDetails& details) { | |
| 204 if (type != chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED) | |
| 205 return; | |
| 206 | |
| 207 bool is_screen_locked = *content::Details<bool>(details).ptr(); | |
| 208 if (is_screen_locked) { | |
| 209 if (screen_lock_requested_) { | |
| 210 screen_lock_requested_ = false; | |
| 211 ResolveScreenLocked(); | |
| 212 } | |
| 213 } else { | |
| 214 ResolveScreenUnlocked(); | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 //////////////////////////////////////////////////////////////////////////////// | |
| 219 // LoginPerformer, public: | 153 // LoginPerformer, public: |
| 220 | 154 |
| 221 void LoginPerformer::PerformLogin(const UserContext& user_context, | 155 void LoginPerformer::PerformLogin(const UserContext& user_context, |
| 222 AuthorizationMode auth_mode) { | 156 AuthorizationMode auth_mode) { |
| 223 auth_mode_ = auth_mode; | 157 auth_mode_ = auth_mode; |
| 224 user_context_ = user_context; | 158 user_context_ = user_context; |
| 225 | 159 |
| 226 CrosSettings* cros_settings = CrosSettings::Get(); | 160 CrosSettings* cros_settings = CrosSettings::Get(); |
| 227 | 161 |
| 228 // Whitelist check is always performed during initial login and | 162 // Whitelist check is always performed during initial login. |
| 229 // should not be performed when ScreenLock is active (pending online auth). | 163 CrosSettingsProvider::TrustedStatus status = |
| 230 if (!ScreenLocker::default_screen_locker()) { | 164 cros_settings->PrepareTrustedValues( |
| 231 CrosSettingsProvider::TrustedStatus status = | 165 base::Bind(&LoginPerformer::PerformLogin, |
| 232 cros_settings->PrepareTrustedValues( | 166 weak_factory_.GetWeakPtr(), |
| 233 base::Bind(&LoginPerformer::PerformLogin, | 167 user_context_, auth_mode)); |
| 234 weak_factory_.GetWeakPtr(), | 168 // Must not proceed without signature verification. |
| 235 user_context_, auth_mode)); | 169 if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) { |
| 236 // Must not proceed without signature verification. | 170 if (delegate_) |
| 237 if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) { | 171 delegate_->PolicyLoadFailed(); |
| 238 if (delegate_) | 172 else |
| 239 delegate_->PolicyLoadFailed(); | 173 NOTREACHED(); |
| 240 else | 174 return; |
| 241 NOTREACHED(); | 175 } else if (status != CrosSettingsProvider::TRUSTED) { |
| 242 return; | 176 // Value of AllowNewUser setting is still not verified. |
| 243 } else if (status != CrosSettingsProvider::TRUSTED) { | 177 // Another attempt will be invoked after verification completion. |
| 244 // Value of AllowNewUser setting is still not verified. | 178 return; |
| 245 // Another attempt will be invoked after verification completion. | |
| 246 return; | |
| 247 } | |
| 248 } | 179 } |
| 249 | 180 |
| 250 bool is_whitelisted = LoginUtils::IsWhitelisted( | 181 bool is_whitelisted = LoginUtils::IsWhitelisted( |
| 251 gaia::CanonicalizeEmail(user_context.username)); | 182 gaia::CanonicalizeEmail(user_context.username)); |
| 252 if (ScreenLocker::default_screen_locker() || is_whitelisted) { | 183 if (is_whitelisted) { |
| 253 switch (auth_mode_) { | 184 switch (auth_mode_) { |
| 254 case AUTH_MODE_EXTENSION: | 185 case AUTH_MODE_EXTENSION: |
| 255 StartLoginCompletion(); | 186 StartLoginCompletion(); |
| 256 break; | 187 break; |
| 257 case AUTH_MODE_INTERNAL: | 188 case AUTH_MODE_INTERNAL: |
| 258 StartAuthentication(); | 189 StartAuthentication(); |
| 259 break; | 190 break; |
| 260 } | 191 } |
| 261 } else { | 192 } else { |
| 262 if (delegate_) | 193 if (delegate_) |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 | 257 |
| 327 void LoginPerformer::ResyncEncryptedData() { | 258 void LoginPerformer::ResyncEncryptedData() { |
| 328 BrowserThread::PostTask( | 259 BrowserThread::PostTask( |
| 329 BrowserThread::UI, FROM_HERE, | 260 BrowserThread::UI, FROM_HERE, |
| 330 base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get())); | 261 base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get())); |
| 331 } | 262 } |
| 332 | 263 |
| 333 //////////////////////////////////////////////////////////////////////////////// | 264 //////////////////////////////////////////////////////////////////////////////// |
| 334 // LoginPerformer, private: | 265 // LoginPerformer, private: |
| 335 | 266 |
| 336 void LoginPerformer::RequestScreenLock() { | |
| 337 DVLOG(1) << "Screen lock requested"; | |
| 338 // Will receive notifications on screen unlock and delete itself. | |
| 339 registrar_.Add(this, | |
| 340 chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, | |
| 341 content::NotificationService::AllSources()); | |
| 342 if (ScreenLocker::default_screen_locker()) { | |
| 343 DVLOG(1) << "Screen already locked"; | |
| 344 ResolveScreenLocked(); | |
| 345 } else { | |
| 346 screen_lock_requested_ = true; | |
| 347 // TODO(antrim) : additional logging for crbug/173178 | |
| 348 LOG(WARNING) << "Requesting screen lock from LoginPerformer"; | |
| 349 DBusThreadManager::Get()->GetSessionManagerClient()->RequestLockScreen(); | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 void LoginPerformer::RequestScreenUnlock() { | |
| 354 DVLOG(1) << "Screen unlock requested"; | |
| 355 if (ScreenLocker::default_screen_locker()) { | |
| 356 DBusThreadManager::Get()->GetSessionManagerClient()->RequestUnlockScreen(); | |
| 357 // Will unsubscribe from notifications once unlock is successful. | |
| 358 } else { | |
| 359 LOG(ERROR) << "Screen is not locked"; | |
| 360 NOTREACHED(); | |
| 361 } | |
| 362 } | |
| 363 | |
| 364 void LoginPerformer::ResolveInitialNetworkAuthFailure() { | |
| 365 DVLOG(1) << "auth_error: " << last_login_failure_.error().state(); | |
| 366 | |
| 367 switch (last_login_failure_.error().state()) { | |
| 368 case GoogleServiceAuthError::CONNECTION_FAILED: | |
| 369 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: | |
| 370 case GoogleServiceAuthError::TWO_FACTOR: | |
| 371 case GoogleServiceAuthError::REQUEST_CANCELED: | |
| 372 // Offline auth already done. Online auth will be done next time | |
| 373 // or once user accesses web property. | |
| 374 VLOG(1) << "Granting user access based on offline auth only. " | |
| 375 << "Online login failed with " | |
| 376 << last_login_failure_.error().state(); | |
| 377 // Resolving initial online auth failure, no ScreenLock is active. | |
| 378 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | |
| 379 return; | |
| 380 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: | |
| 381 // Offline auth OK, so it might be the case of changed password. | |
| 382 password_changed_ = true; | |
| 383 case GoogleServiceAuthError::USER_NOT_SIGNED_UP: | |
| 384 case GoogleServiceAuthError::ACCOUNT_DELETED: | |
| 385 case GoogleServiceAuthError::ACCOUNT_DISABLED: | |
| 386 // Access not granted. User has to sign out. | |
| 387 // Request screen lock & show error message there. | |
| 388 case GoogleServiceAuthError::CAPTCHA_REQUIRED: | |
| 389 default: | |
| 390 // Unless there's new GoogleServiceAuthErrors state has been added. | |
| 391 NOTREACHED(); | |
| 392 return; | |
| 393 } | |
| 394 } | |
| 395 | |
| 396 void LoginPerformer::ResolveLockLoginFailure() { | |
| 397 if (last_login_failure_.reason() == LoginFailure::LOGIN_TIMED_OUT) { | |
| 398 LOG(WARNING) << "Online login timed out - unlocking screen. " | |
| 399 << "Granting user access based on offline auth only."; | |
| 400 RequestScreenUnlock(); | |
| 401 return; | |
| 402 } else if (last_login_failure_.reason() == | |
| 403 LoginFailure::NETWORK_AUTH_FAILED) { | |
| 404 ResolveLockNetworkAuthFailure(); | |
| 405 return; | |
| 406 } else if (last_login_failure_.reason() == | |
| 407 LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME || | |
| 408 last_login_failure_.reason() == | |
| 409 LoginFailure::DATA_REMOVAL_FAILED) { | |
| 410 LOG(ERROR) << "Cryptohome error, forcing sign out."; | |
| 411 } else { | |
| 412 // COULD_NOT_MOUNT_TMPFS, UNLOCK_FAILED should not happen here. | |
| 413 NOTREACHED(); | |
| 414 } | |
| 415 ScreenLocker::default_screen_locker()->Signout(); | |
| 416 } | |
| 417 | |
| 418 void LoginPerformer::ResolveLockNetworkAuthFailure() { | |
| 419 DCHECK(ScreenLocker::default_screen_locker()) | |
| 420 << "ScreenLocker instance doesn't exist."; | |
| 421 DCHECK(last_login_failure_.reason() == LoginFailure::NETWORK_AUTH_FAILED); | |
| 422 | |
| 423 int msg_id = IDS_LOGIN_ERROR_AUTHENTICATING; | |
| 424 HelpAppLauncher::HelpTopic help_topic = | |
| 425 HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT; | |
| 426 bool sign_out_only = false; | |
| 427 | |
| 428 DVLOG(1) << "auth_error: " << last_login_failure_.error().state(); | |
| 429 | |
| 430 switch (last_login_failure_.error().state()) { | |
| 431 case GoogleServiceAuthError::CONNECTION_FAILED: | |
| 432 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: | |
| 433 case GoogleServiceAuthError::TWO_FACTOR: | |
| 434 case GoogleServiceAuthError::REQUEST_CANCELED: | |
| 435 // Offline auth already done. Online auth will be done next time | |
| 436 // or once user accesses web property. | |
| 437 LOG(WARNING) << "Granting user access based on offline auth only. " | |
| 438 << "Online login failed with " | |
| 439 << last_login_failure_.error().state(); | |
| 440 RequestScreenUnlock(); | |
| 441 return; | |
| 442 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: | |
| 443 // Password change detected. | |
| 444 msg_id = IDS_LOGIN_ERROR_PASSWORD_CHANGED; | |
| 445 break; | |
| 446 case GoogleServiceAuthError::USER_NOT_SIGNED_UP: | |
| 447 case GoogleServiceAuthError::ACCOUNT_DELETED: | |
| 448 case GoogleServiceAuthError::ACCOUNT_DISABLED: | |
| 449 // Access not granted. User has to sign out. | |
| 450 // Show error message using existing screen lock. | |
| 451 msg_id = IDS_LOGIN_ERROR_RESTRICTED; | |
| 452 help_topic = HelpAppLauncher::HELP_ACCOUNT_DISABLED; | |
| 453 sign_out_only = true; | |
| 454 break; | |
| 455 case GoogleServiceAuthError::CAPTCHA_REQUIRED: | |
| 456 default: | |
| 457 // Unless there's new GoogleServiceAuthError state has been added. | |
| 458 NOTREACHED(); | |
| 459 break; | |
| 460 } | |
| 461 | |
| 462 ScreenLocker::default_screen_locker()->ShowErrorMessage(msg_id, | |
| 463 help_topic, | |
| 464 sign_out_only); | |
| 465 } | |
| 466 | |
| 467 void LoginPerformer::ResolveScreenLocked() { | |
| 468 DVLOG(1) << "Screen locked"; | |
| 469 ResolveLockNetworkAuthFailure(); | |
| 470 } | |
| 471 | |
| 472 void LoginPerformer::ResolveScreenUnlocked() { | |
| 473 DVLOG(1) << "Screen unlocked"; | |
| 474 registrar_.RemoveAll(); | |
| 475 // If screen was unlocked that was for a reason, should delete itself now. | |
| 476 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | |
| 477 } | |
| 478 | |
| 479 void LoginPerformer::StartLoginCompletion() { | 267 void LoginPerformer::StartLoginCompletion() { |
| 480 DVLOG(1) << "Login completion started"; | 268 DVLOG(1) << "Login completion started"; |
| 481 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); | 269 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); |
| 482 Profile* profile = ProfileHelper::GetSigninProfile(); | 270 Profile* profile = ProfileHelper::GetSigninProfile(); |
| 483 | 271 |
| 484 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); | 272 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); |
| 485 BrowserThread::PostTask( | 273 BrowserThread::PostTask( |
| 486 BrowserThread::UI, FROM_HERE, | 274 BrowserThread::UI, FROM_HERE, |
| 487 base::Bind(&Authenticator::CompleteLogin, authenticator_.get(), | 275 base::Bind(&Authenticator::CompleteLogin, authenticator_.get(), |
| 488 profile, | 276 profile, |
| 489 user_context_)); | 277 user_context_)); |
| 490 | 278 |
| 491 user_context_.password.clear(); | 279 user_context_.password.clear(); |
| 492 user_context_.auth_code.clear(); | 280 user_context_.auth_code.clear(); |
| 493 } | 281 } |
| 494 | 282 |
| 495 void LoginPerformer::StartAuthentication() { | 283 void LoginPerformer::StartAuthentication() { |
| 496 DVLOG(1) << "Auth started"; | 284 DVLOG(1) << "Auth started"; |
| 497 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); | 285 BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false); |
| 498 Profile* profile = ProfileHelper::GetSigninProfile(); | 286 Profile* profile = ProfileHelper::GetSigninProfile(); |
| 499 if (delegate_) { | 287 if (delegate_) { |
| 500 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); | 288 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); |
| 501 BrowserThread::PostTask( | 289 BrowserThread::PostTask( |
| 502 BrowserThread::UI, FROM_HERE, | 290 BrowserThread::UI, FROM_HERE, |
| 503 base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(), | 291 base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(), |
| 504 profile, | 292 profile, |
| 505 user_context_, | 293 user_context_)); |
| 506 std::string(), | |
| 507 std::string())); | |
| 508 // Make unobtrusive online check. It helps to determine password change | 294 // Make unobtrusive online check. It helps to determine password change |
| 509 // state in the case when offline login fails. | 295 // state in the case when offline login fails. |
| 510 online_attempt_host_.Check(profile, user_context_); | 296 online_attempt_host_.Check(profile, user_context_); |
| 511 } else { | 297 } else { |
| 512 DCHECK(authenticator_.get()) | 298 NOTREACHED(); |
| 513 << "Authenticator instance doesn't exist for login attempt retry."; | |
| 514 // At this point offline auth has been successful, | |
| 515 // retry online auth, using existing Authenticator instance. | |
| 516 BrowserThread::PostTask( | |
| 517 BrowserThread::UI, FROM_HERE, | |
| 518 base::Bind(&Authenticator::RetryAuth, authenticator_.get(), | |
| 519 profile, | |
| 520 user_context_, | |
| 521 std::string(), | |
| 522 std::string())); | |
| 523 } | 299 } |
| 524 user_context_.password.clear(); | 300 user_context_.password.clear(); |
| 525 user_context_.auth_code.clear(); | 301 user_context_.auth_code.clear(); |
| 526 } | 302 } |
| 527 | 303 |
| 528 } // namespace chromeos | 304 } // namespace chromeos |
| OLD | NEW |