login_performer.cc revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
1bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/login/login_performer.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <string>
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "app/l10n_util.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "app/resource_bundle.h"
11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/logging.h"
12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/message_loop.h"
1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/metrics/histogram.h"
14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/browser_process.h"
15731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/browser_thread.h"
16731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/boot_times_loader.h"
1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/chromeos/cros/cros_library.h"
1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/chromeos/cros/screen_lock_library.h"
19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/login/login_utils.h"
2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/chromeos/login/screen_locker.h"
214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/chromeos/user_cros_settings_provider.h"
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/metrics/user_metrics.h"
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile_manager.h"
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/common/notification_service.h"
2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/common/notification_type.h"
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "grit/generated_resources.h"
28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace chromeos {
30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Initialize default LoginPerformer.
3221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static
3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenLoginPerformer* LoginPerformer::default_performer_ = NULL;
34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenLoginPerformer::LoginPerformer(Delegate* delegate)
36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    : last_login_failure_(LoginFailure::None()),
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      delegate_(delegate),
3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      password_changed_(false),
3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      screen_lock_requested_(false),
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      initial_online_auth_pending_(false),
4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      method_factory_(this) {
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(default_performer_ == NULL)
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      << "LoginPerformer should have only one instance.";
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  default_performer_ = this;
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenLoginPerformer::~LoginPerformer() {
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Deleting LoginPerformer";
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(default_performer_ != NULL) << "Default instance should exist.";
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  default_performer_ = NULL;
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, LoginStatusConsumer implementation:
55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::OnLoginFailure(const LoginFailure& failure) {
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserMetrics::RecordAction(UserMetricsAction("Login_Failure"));
5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UMA_HISTOGRAM_ENUMERATION("Login.FailureReason", failure.reason(),
5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                            LoginFailure::NUM_FAILURE_REASONS);
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "failure.reason " << failure.reason();
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "failure.error.state " << failure.error().state();
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  last_login_failure_ = failure;
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (delegate_) {
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    captcha_.clear();
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    captcha_token_.clear();
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (failure.reason() == LoginFailure::NETWORK_AUTH_FAILED &&
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        failure.error().state() == GoogleServiceAuthError::CAPTCHA_REQUIRED) {
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      captcha_token_ = failure.error().captcha().token;
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    delegate_->OnLoginFailure(failure);
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Consequent online login failure with blocking UI on.
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // No difference between cases whether screen was locked by the user or
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // by LoginPerformer except for the very first screen lock while waiting
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // for online auth. Otherwise it will be SL active > timeout > screen unlock.
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Display recoverable error message using ScreenLocker,
8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // force sign out otherwise.
8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker() && !initial_online_auth_pending_) {
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveLockLoginFailure();
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  initial_online_auth_pending_ = false;
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Offline auth - OK, online auth - failed.
8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (failure.reason() == LoginFailure::NETWORK_AUTH_FAILED) {
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveInitialNetworkAuthFailure();
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else if (failure.reason() == LoginFailure::LOGIN_TIMED_OUT) {
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    VLOG(1) << "Online login timed out. "
9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            << "Granting user access based on offline auth only.";
9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // ScreenLock is not active, it's ok to delete itself.
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // happens during offline auth only.
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // UNLOCK_FAILED is used during normal screen lock case.
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // TODO(nkostylev) DATA_REMOVAL_FAILED - ?
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    NOTREACHED();
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid LoginPerformer::OnLoginSuccess(
106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const std::string& username,
107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const std::string& password,
108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const GaiaAuthConsumer::ClientLoginResult& credentials,
109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool pending_requests) {
11021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserMetrics::RecordAction(UserMetricsAction("Login_Success"));
11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // 0 - Login success offline and online. It's a new user. or it's an
11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  //     existing user and offline auth took longer than online auth.
11321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // 1 - Login success offline only. It's an existing user login.
11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UMA_HISTOGRAM_ENUMERATION("Login.SuccessReason", pending_requests, 2);
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VLOG(1) << "LoginSuccess, pending_requests " << pending_requests;
117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (delegate_) {
11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // After delegate_->OnLoginSuccess(...) is called, delegate_ releases
11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // LoginPerformer ownership. LP now manages it's lifetime on its own.
12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // 2 things could make it exist longer:
12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // 1. ScreenLock active (pending correct new password input)
12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // 2. Pending online auth request.
12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!pending_requests)
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      MessageLoop::current()->DeleteSoon(FROM_HERE, this);
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    else
12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      initial_online_auth_pending_ = true;
12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
128513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    delegate_->OnLoginSuccess(username,
129513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                              password,
130513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                              credentials,
131513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                              pending_requests);
13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
13421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(!pending_requests)
13521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        << "Pending request w/o delegate_ should not happen!";
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Online login has succeeded.
13721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    Profile* profile =
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        g_browser_process->profile_manager()->GetDefaultProfile();
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    LoginUtils::Get()->FetchCookies(profile, credentials);
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    LoginUtils::Get()->FetchTokens(profile, credentials);
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Don't unlock screen if it was locked while we're waiting
14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // for initial online auth.
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (ScreenLocker::default_screen_locker() &&
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        !initial_online_auth_pending_) {
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      DVLOG(1) << "Online login OK - unlocking screen.";
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      RequestScreenUnlock();
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Do not delete itself just yet, wait for unlock.
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // See ResolveScreenUnlocked().
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    initial_online_auth_pending_ = false;
15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // There's nothing else that's holding LP from deleting itself -
15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // no ScreenLock, no pending requests.
155bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
156bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
157bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
158bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::OnOffTheRecordLoginSuccess() {
16021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserMetrics::RecordAction(
16121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      UserMetricsAction("Login_GuestLoginSuccess"));
16221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (delegate_)
164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    delegate_->OnOffTheRecordLoginSuccess();
165bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  else
166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    NOTREACHED();
167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::OnPasswordChangeDetected(
170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const GaiaAuthConsumer::ClientLoginResult& credentials) {
171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_credentials_ = credentials;
172bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (delegate_) {
173bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    delegate_->OnPasswordChangeDetected(credentials);
174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    last_login_failure_ =
17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError(
17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    password_changed_ = true;
17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DVLOG(1) << "Password change detected - locking screen.";
18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    RequestScreenLock();
181bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
182bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, SignedSettingsHelper::Callback implementation:
186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::OnCheckWhitelistCompleted(SignedSettings::ReturnCode code,
188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                               const std::string& email) {
18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (code == SignedSettings::SUCCESS) {
190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // Whitelist check passed, continue with authentication.
191bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    StartAuthentication();
192bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
193bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (delegate_)
194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      delegate_->WhiteListCheckFailed(email);
195bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    else
196bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NOTREACHED();
197bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
198bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
199bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
200bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
20121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// LoginPerformer, NotificationObserver implementation:
20221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen//
20321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
20421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::Observe(NotificationType type,
20521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                             const NotificationSource& source,
20621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                             const NotificationDetails& details) {
20721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (type != NotificationType::SCREEN_LOCK_STATE_CHANGED)
20821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
20921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
21021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool is_screen_locked = *Details<bool>(details).ptr();
21121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (is_screen_locked) {
21221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (screen_lock_requested_) {
21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      screen_lock_requested_ = false;
21421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ResolveScreenLocked();
21521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
21621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveScreenUnlocked();
21821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
21921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
22021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen////////////////////////////////////////////////////////////////////////////////
222bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, public:
223bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
224bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::Login(const std::string& username,
225bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                           const std::string& password) {
226bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  username_ = username;
227bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  password_ = password;
22821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Whitelist check is always performed during initial login and
23021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // should not be performed when ScreenLock is active (pending online auth).
23121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!ScreenLocker::default_screen_locker()) {
23221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Must not proceed without signature verification.
23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    UserCrosSettingsProvider user_settings;
23421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    bool trusted_setting_available = user_settings.RequestTrustedAllowNewUser(
23521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        method_factory_.NewRunnableMethod(&LoginPerformer::Login,
23621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                          username,
23721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                          password));
23821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!trusted_setting_available) {
23921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Value of AllowNewUser setting is still not verified.
24021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Another attempt will be invoked after verification completion.
24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
24421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker() ||
24621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      UserCrosSettingsProvider::cached_allow_new_user()) {
24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Starts authentication if guest login is allowed or online auth pending.
248bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    StartAuthentication();
249bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
250bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // Otherwise, do whitelist check first.
251bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    SignedSettingsHelper::Get()->StartCheckWhitelistOp(
252bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen        username, this);
253bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
254bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
255bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
256bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::LoginOffTheRecord() {
257bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
258731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
260bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewRunnableMethod(authenticator_.get(),
261bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        &Authenticator::LoginOffTheRecord));
262bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
263bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
264bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
267bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewRunnableMethod(authenticator_.get(),
268bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        &Authenticator::RecoverEncryptedData,
269bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        old_password,
270bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        cached_credentials_));
271bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_credentials_ = GaiaAuthConsumer::ClientLoginResult();
272bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
273bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
274bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::ResyncEncryptedData() {
275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
277bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewRunnableMethod(authenticator_.get(),
278bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        &Authenticator::ResyncEncryptedData,
279bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        cached_credentials_));
280bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_credentials_ = GaiaAuthConsumer::ClientLoginResult();
281bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
282bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
283bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
284bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, private:
285bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
28621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::RequestScreenLock() {
28721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen lock requested";
28821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Will receive notifications on screen unlock and delete itself.
28921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  registrar_.Add(this,
29021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationType::SCREEN_LOCK_STATE_CHANGED,
29121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationService::AllSources());
29221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker()) {
29321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DVLOG(1) << "Screen already locked";
29421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveScreenLocked();
29521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
29621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    screen_lock_requested_ = true;
29721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    chromeos::CrosLibrary::Get()->GetScreenLockLibrary()->
29821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NotifyScreenLockRequested();
29921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
30021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
30121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
30221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::RequestScreenUnlock() {
30321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen unlock requested";
30421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker()) {
30521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    chromeos::CrosLibrary::Get()->GetScreenLockLibrary()->
30621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NotifyScreenUnlockRequested();
30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Will unsubscribe from notifications once unlock is successful.
30821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
30921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    LOG(ERROR) << "Screen is not locked";
31021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    NOTREACHED();
31121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
31221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
31321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
31421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveInitialNetworkAuthFailure() {
31521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "auth_error: " << last_login_failure_.error().state();
31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
31721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  switch (last_login_failure_.error().state()) {
31821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CONNECTION_FAILED:
31921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
32021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::TWO_FACTOR:
32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::REQUEST_CANCELED:
32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Offline auth already done. Online auth will be done next time
32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // or once user accesses web property.
32421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      VLOG(1) << "Granting user access based on offline auth only. "
32521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              << "Online login failed with "
32621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              << last_login_failure_.error().state();
32721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Resolving initial online auth failure, no ScreenLock is active.
32821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      MessageLoop::current()->DeleteSoon(FROM_HERE, this);
32921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
33021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
33121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Offline auth OK, so it might be the case of changed password.
33221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      password_changed_ = true;
33321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
33421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DELETED:
33521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DISABLED:
33621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Access not granted. User has to sign out.
33721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Request screen lock & show error message there.
33821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CAPTCHA_REQUIRED:
33921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // User is requested to enter CAPTCHA challenge.
34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      RequestScreenLock();
34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
34221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    default:
34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Unless there's new GoogleServiceAuthErrors state has been added.
34421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NOTREACHED();
34521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
34921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveLockLoginFailure() {
35021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (last_login_failure_.reason() == LoginFailure::LOGIN_TIMED_OUT) {
35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     LOG(WARNING) << "Online login timed out - unlocking screen. "
35221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  << "Granting user access based on offline auth only.";
35321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     RequestScreenUnlock();
35421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     return;
35521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   } else if (last_login_failure_.reason() ==
35621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  LoginFailure::NETWORK_AUTH_FAILED) {
35721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     ResolveLockNetworkAuthFailure();
35821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     return;
35921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   } else if (last_login_failure_.reason() ==
36021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME ||
36121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              last_login_failure_.reason() ==
36221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  LoginFailure::DATA_REMOVAL_FAILED) {
36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     LOG(ERROR) << "Cryptohome error, forcing sign out.";
36421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   } else {
36521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     // COULD_NOT_MOUNT_TMPFS, UNLOCK_FAILED should not happen here.
36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     NOTREACHED();
36721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   }
36821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   ScreenLocker::default_screen_locker()->Signout();
36921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
37021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
37121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveLockNetworkAuthFailure() {
37221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(ScreenLocker::default_screen_locker())
37321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      << "ScreenLocker instance doesn't exist.";
37421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(last_login_failure_.reason() == LoginFailure::NETWORK_AUTH_FAILED);
37521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  std::wstring msg;
37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool sign_out_only = false;
37821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
37921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "auth_error: " << last_login_failure_.error().state();
38021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
38121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  switch (last_login_failure_.error().state()) {
38221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CONNECTION_FAILED:
38321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
38421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::TWO_FACTOR:
38521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::REQUEST_CANCELED:
38621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Offline auth already done. Online auth will be done next time
38721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // or once user accesses web property.
38821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      LOG(WARNING) << "Granting user access based on offline auth only. "
38921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   << "Online login failed with "
39021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   << last_login_failure_.error().state();
39121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      RequestScreenUnlock();
39221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
39321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
39421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Password change detected.
39521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      msg = l10n_util::GetString(IDS_LOGIN_ERROR_PASSWORD_CHANGED);
39621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      break;
39721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
39821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DELETED:
39921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DISABLED:
40021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Access not granted. User has to sign out.
40121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Show error message using existing screen lock.
40221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      msg = l10n_util::GetString(IDS_LOGIN_ERROR_RESTRICTED);
40321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      sign_out_only = true;
40421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      break;
40521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CAPTCHA_REQUIRED:
40621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // User is requested to enter CAPTCHA challenge.
40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      msg = l10n_util::GetString(IDS_LOGIN_ERROR_PASSWORD_CHANGED);
40821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ScreenLocker::default_screen_locker()->ShowCaptchaAndErrorMessage(
40921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          last_login_failure_.error().captcha().image_url,
41021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          msg);
41121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
41221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    default:
41321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Unless there's new GoogleServiceAuthError state has been added.
41421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NOTREACHED();
41521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      break;
41621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
41721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
41821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ScreenLocker::default_screen_locker()->ShowErrorMessage(msg, sign_out_only);
41921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
42021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
42121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveScreenLocked() {
42221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen locked";
42321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ResolveLockNetworkAuthFailure();
42421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
42521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
42621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveScreenUnlocked() {
42721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen unlocked";
42821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  registrar_.RemoveAll();
42921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // If screen was unlocked that was for a reason, should delete itself now.
43021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
43121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
433bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::StartAuthentication() {
43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Auth started";
435731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
436bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile();
43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (delegate_) {
43821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
43921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserThread::PostTask(
44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        BrowserThread::UI, FROM_HERE,
44121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewRunnableMethod(authenticator_.get(),
44221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          &Authenticator::AuthenticateToLogin,
44321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          profile,
44421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          username_,
44521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          password_,
44621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_token_,
44721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_));
44821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
44921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(authenticator_.get())
45021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        << "Authenticator instance doesn't exist for login attempt retry.";
45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // At this point offline auth has been successful,
45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // retry online auth, using existing Authenticator instance.
45321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserThread::PostTask(
45421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        BrowserThread::UI, FROM_HERE,
45521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewRunnableMethod(authenticator_.get(),
45621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          &Authenticator::RetryAuth,
45721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          profile,
45821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          username_,
45921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          password_,
46021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_token_,
46121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_));
46221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
463bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  password_.clear();
464bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
465bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
466bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace chromeos
467