login_performer.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 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
9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/logging.h"
10bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/message_loop.h"
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/metrics/histogram.h"
123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/utf_string_conversions.h"
13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/browser_process.h"
14731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/chromeos/boot_times_loader.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/chromeos/cros/cros_library.h"
1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/chromeos/cros/screen_lock_library.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/chromeos/cros_settings_names.h"
18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/login/login_utils.h"
1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/chromeos/login/screen_locker.h"
204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/chromeos/user_cros_settings_provider.h"
2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/metrics/user_metrics.h"
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/prefs/pref_service.h"
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile_manager.h"
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/common/pref_names.h"
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_service.h"
28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/common/notification_type.h"
2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "grit/generated_resources.h"
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace chromeos {
34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Initialize default LoginPerformer.
3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenLoginPerformer* LoginPerformer::default_performer_ = NULL;
38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenLoginPerformer::LoginPerformer(Delegate* delegate)
40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    : last_login_failure_(LoginFailure::None()),
4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      delegate_(delegate),
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      password_changed_(false),
4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      screen_lock_requested_(false),
4421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      initial_online_auth_pending_(false),
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      method_factory_(this) {
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(default_performer_ == NULL)
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      << "LoginPerformer should have only one instance.";
4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  default_performer_ = this;
4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenLoginPerformer::~LoginPerformer() {
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Deleting LoginPerformer";
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(default_performer_ != NULL) << "Default instance should exist.";
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  default_performer_ = NULL;
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, LoginStatusConsumer implementation:
59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::OnLoginFailure(const LoginFailure& failure) {
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserMetrics::RecordAction(UserMetricsAction("Login_Failure"));
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UMA_HISTOGRAM_ENUMERATION("Login.FailureReason", failure.reason(),
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                            LoginFailure::NUM_FAILURE_REASONS);
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "failure.reason " << failure.reason();
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "failure.error.state " << failure.error().state();
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  last_login_failure_ = failure;
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (delegate_) {
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    captcha_.clear();
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    captcha_token_.clear();
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (failure.reason() == LoginFailure::NETWORK_AUTH_FAILED &&
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        failure.error().state() == GoogleServiceAuthError::CAPTCHA_REQUIRED) {
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      captcha_token_ = failure.error().captcha().token;
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    delegate_->OnLoginFailure(failure);
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Consequent online login failure with blocking UI on.
8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // No difference between cases whether screen was locked by the user or
8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // by LoginPerformer except for the very first screen lock while waiting
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // for online auth. Otherwise it will be SL active > timeout > screen unlock.
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Display recoverable error message using ScreenLocker,
8521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // force sign out otherwise.
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker() && !initial_online_auth_pending_) {
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveLockLoginFailure();
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  initial_online_auth_pending_ = false;
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Offline auth - OK, online auth - failed.
9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (failure.reason() == LoginFailure::NETWORK_AUTH_FAILED) {
9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveInitialNetworkAuthFailure();
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else if (failure.reason() == LoginFailure::LOGIN_TIMED_OUT) {
9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    VLOG(1) << "Online login timed out. "
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            << "Granting user access based on offline auth only.";
9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // ScreenLock is not active, it's ok to delete itself.
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // happens during offline auth only.
10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // UNLOCK_FAILED is used during normal screen lock case.
10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // TODO(nkostylev) DATA_REMOVAL_FAILED - ?
10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    NOTREACHED();
10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid LoginPerformer::OnLoginSuccess(
110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const std::string& username,
111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const std::string& password,
112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const GaiaAuthConsumer::ClientLoginResult& credentials,
113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool pending_requests) {
11421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserMetrics::RecordAction(UserMetricsAction("Login_Success"));
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // 0 - Login success offline and online. It's a new user. or it's an
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  //     existing user and offline auth took longer than online auth.
11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // 1 - Login success offline only. It's an existing user login.
11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UMA_HISTOGRAM_ENUMERATION("Login.SuccessReason", pending_requests, 2);
11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VLOG(1) << "LoginSuccess, pending_requests " << pending_requests;
121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (delegate_) {
12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // After delegate_->OnLoginSuccess(...) is called, delegate_ releases
12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // LoginPerformer ownership. LP now manages it's lifetime on its own.
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // 2 things could make it exist longer:
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // 1. ScreenLock active (pending correct new password input)
12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // 2. Pending online auth request.
12721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!pending_requests)
12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      MessageLoop::current()->DeleteSoon(FROM_HERE, this);
12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    else
13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      initial_online_auth_pending_ = true;
13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
132513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    delegate_->OnLoginSuccess(username,
133513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                              password,
134513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                              credentials,
135513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                              pending_requests);
13621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
13821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(!pending_requests)
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        << "Pending request w/o delegate_ should not happen!";
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Online login has succeeded.
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    Profile* profile =
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        g_browser_process->profile_manager()->GetDefaultProfile();
14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    LoginUtils::Get()->FetchCookies(profile, credentials);
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    LoginUtils::Get()->FetchTokens(profile, credentials);
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Don't unlock screen if it was locked while we're waiting
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // for initial online auth.
14821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (ScreenLocker::default_screen_locker() &&
14921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        !initial_online_auth_pending_) {
15021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      DVLOG(1) << "Online login OK - unlocking screen.";
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      RequestScreenUnlock();
15221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Do not delete itself just yet, wait for unlock.
15321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // See ResolveScreenUnlocked().
15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
15521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
15621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    initial_online_auth_pending_ = false;
15721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // There's nothing else that's holding LP from deleting itself -
15821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // no ScreenLock, no pending requests.
159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    MessageLoop::current()->DeleteSoon(FROM_HERE, this);
160bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
161bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
162bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::OnOffTheRecordLoginSuccess() {
16421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserMetrics::RecordAction(
16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      UserMetricsAction("Login_GuestLoginSuccess"));
16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (delegate_)
168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    delegate_->OnOffTheRecordLoginSuccess();
169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  else
170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    NOTREACHED();
171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
172bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
173bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::OnPasswordChangeDetected(
174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const GaiaAuthConsumer::ClientLoginResult& credentials) {
175bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_credentials_ = credentials;
176bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (delegate_) {
177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    delegate_->OnPasswordChangeDetected(credentials);
178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    last_login_failure_ =
18021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError(
18121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    password_changed_ = true;
18321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DVLOG(1) << "Password change detected - locking screen.";
18421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    RequestScreenLock();
185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
187bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
189bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, SignedSettingsHelper::Callback implementation:
190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::OnCheckWhitelistCompleted(SignedSettings::ReturnCode code,
192bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                               const std::string& email) {
19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (code == SignedSettings::SUCCESS) {
194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // Whitelist check passed, continue with authentication.
195bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    StartAuthentication();
196bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
197bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (delegate_)
198bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      delegate_->WhiteListCheckFailed(email);
199bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    else
200bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NOTREACHED();
201bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
202bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
203bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
204bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
20521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// LoginPerformer, NotificationObserver implementation:
20621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen//
20721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
20821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::Observe(NotificationType type,
20921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                             const NotificationSource& source,
21021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                             const NotificationDetails& details) {
21121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (type != NotificationType::SCREEN_LOCK_STATE_CHANGED)
21221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
21421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool is_screen_locked = *Details<bool>(details).ptr();
21521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (is_screen_locked) {
21621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (screen_lock_requested_) {
21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      screen_lock_requested_ = false;
21821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ResolveScreenLocked();
21921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
22021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveScreenUnlocked();
22221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen////////////////////////////////////////////////////////////////////////////////
226bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, public:
227bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
228bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::Login(const std::string& username,
229bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                           const std::string& password) {
230bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  username_ = username;
231bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  password_ = password;
23221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Whitelist check is always performed during initial login and
23421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // should not be performed when ScreenLock is active (pending online auth).
23521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!ScreenLocker::default_screen_locker()) {
23621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Must not proceed without signature verification.
23721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    UserCrosSettingsProvider user_settings;
23821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    bool trusted_setting_available = user_settings.RequestTrustedAllowNewUser(
23921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        method_factory_.NewRunnableMethod(&LoginPerformer::Login,
24021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                          username,
24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                          password));
24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!trusted_setting_available) {
24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Value of AllowNewUser setting is still not verified.
24421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Another attempt will be invoked after verification completion.
24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
24621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
24821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
24921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker() ||
25021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      UserCrosSettingsProvider::cached_allow_new_user()) {
25121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Starts authentication if guest login is allowed or online auth pending.
252bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    StartAuthentication();
253bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
254bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // Otherwise, do whitelist check first.
25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PrefService* local_state = g_browser_process->local_state();
25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    CHECK(local_state);
25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (local_state->IsManagedPreference(kAccountsPrefUsers)) {
25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (UserCrosSettingsProvider::IsEmailInCachedWhitelist(username)) {
25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        StartAuthentication();
26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      } else {
26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        if (delegate_)
26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          delegate_->WhiteListCheckFailed(username);
26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        else
26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          NOTREACHED();
26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    } else {
26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // In case of signed settings: with current implementation we do not
26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // trust whitelist returned by PrefService.  So make separate check.
26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      SignedSettingsHelper::Get()->StartCheckWhitelistOp(
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          username, this);
27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
272bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
273bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
274bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
275bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::LoginOffTheRecord() {
276bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
279bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewRunnableMethod(authenticator_.get(),
280bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        &Authenticator::LoginOffTheRecord));
281bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
282bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
283bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
286bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewRunnableMethod(authenticator_.get(),
287bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        &Authenticator::RecoverEncryptedData,
288bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        old_password,
289bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        cached_credentials_));
290bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_credentials_ = GaiaAuthConsumer::ClientLoginResult();
291bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
292bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
293bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::ResyncEncryptedData() {
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
296bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewRunnableMethod(authenticator_.get(),
297bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        &Authenticator::ResyncEncryptedData,
298bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        cached_credentials_));
299bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_credentials_ = GaiaAuthConsumer::ClientLoginResult();
300bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
301bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
302bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
303bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, private:
304bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
30521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::RequestScreenLock() {
30621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen lock requested";
30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Will receive notifications on screen unlock and delete itself.
30821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  registrar_.Add(this,
30921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationType::SCREEN_LOCK_STATE_CHANGED,
31021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationService::AllSources());
31121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker()) {
31221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DVLOG(1) << "Screen already locked";
31321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveScreenLocked();
31421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
31521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    screen_lock_requested_ = true;
31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    chromeos::CrosLibrary::Get()->GetScreenLockLibrary()->
31721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NotifyScreenLockRequested();
31821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
31921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
32021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::RequestScreenUnlock() {
32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen unlock requested";
32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker()) {
32421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    chromeos::CrosLibrary::Get()->GetScreenLockLibrary()->
32521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NotifyScreenUnlockRequested();
32621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Will unsubscribe from notifications once unlock is successful.
32721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
32821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    LOG(ERROR) << "Screen is not locked";
32921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    NOTREACHED();
33021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
33121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
33221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
33321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveInitialNetworkAuthFailure() {
33421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "auth_error: " << last_login_failure_.error().state();
33521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
33621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  switch (last_login_failure_.error().state()) {
33721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CONNECTION_FAILED:
33821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
33921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::TWO_FACTOR:
34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::REQUEST_CANCELED:
34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Offline auth already done. Online auth will be done next time
34221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // or once user accesses web property.
34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      VLOG(1) << "Granting user access based on offline auth only. "
34421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              << "Online login failed with "
34521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              << last_login_failure_.error().state();
34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Resolving initial online auth failure, no ScreenLock is active.
34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      MessageLoop::current()->DeleteSoon(FROM_HERE, this);
34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
34921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
35021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Offline auth OK, so it might be the case of changed password.
35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      password_changed_ = true;
35221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
35321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DELETED:
35421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DISABLED:
35521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Access not granted. User has to sign out.
35621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Request screen lock & show error message there.
35721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CAPTCHA_REQUIRED:
35821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // User is requested to enter CAPTCHA challenge.
35972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      captcha_token_ = last_login_failure_.error().captcha().token;
36021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      RequestScreenLock();
36121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
36221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    default:
36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Unless there's new GoogleServiceAuthErrors state has been added.
36421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NOTREACHED();
36521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
36721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
36821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
36921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveLockLoginFailure() {
37021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (last_login_failure_.reason() == LoginFailure::LOGIN_TIMED_OUT) {
37121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     LOG(WARNING) << "Online login timed out - unlocking screen. "
37221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  << "Granting user access based on offline auth only.";
37321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     RequestScreenUnlock();
37421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     return;
37521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   } else if (last_login_failure_.reason() ==
37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  LoginFailure::NETWORK_AUTH_FAILED) {
37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     ResolveLockNetworkAuthFailure();
37821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     return;
37921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   } else if (last_login_failure_.reason() ==
38021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME ||
38121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              last_login_failure_.reason() ==
38221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  LoginFailure::DATA_REMOVAL_FAILED) {
38321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     LOG(ERROR) << "Cryptohome error, forcing sign out.";
38421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   } else {
38521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     // COULD_NOT_MOUNT_TMPFS, UNLOCK_FAILED should not happen here.
38621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     NOTREACHED();
38721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   }
38821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   ScreenLocker::default_screen_locker()->Signout();
38921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
39021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
39121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveLockNetworkAuthFailure() {
39221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(ScreenLocker::default_screen_locker())
39321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      << "ScreenLocker instance doesn't exist.";
39421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(last_login_failure_.reason() == LoginFailure::NETWORK_AUTH_FAILED);
39521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  string16 msg;
39721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool sign_out_only = false;
39821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
39921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "auth_error: " << last_login_failure_.error().state();
40021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
40121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  switch (last_login_failure_.error().state()) {
40221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CONNECTION_FAILED:
40321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
40421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::TWO_FACTOR:
40521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::REQUEST_CANCELED:
40621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Offline auth already done. Online auth will be done next time
40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // or once user accesses web property.
40821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      LOG(WARNING) << "Granting user access based on offline auth only. "
40921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   << "Online login failed with "
41021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   << last_login_failure_.error().state();
41121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      RequestScreenUnlock();
41221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
41321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
41421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Password change detected.
4153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      msg = l10n_util::GetStringUTF16(IDS_LOGIN_ERROR_PASSWORD_CHANGED);
41621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      break;
41721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
41821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DELETED:
41921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DISABLED:
42021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Access not granted. User has to sign out.
42121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Show error message using existing screen lock.
4223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      msg = l10n_util::GetStringUTF16(IDS_LOGIN_ERROR_RESTRICTED);
42321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      sign_out_only = true;
42421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      break;
42521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CAPTCHA_REQUIRED:
42621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // User is requested to enter CAPTCHA challenge.
42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      captcha_token_ = last_login_failure_.error().captcha().token;
4283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      msg = l10n_util::GetStringUTF16(IDS_LOGIN_ERROR_PASSWORD_CHANGED);
42921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ScreenLocker::default_screen_locker()->ShowCaptchaAndErrorMessage(
43021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          last_login_failure_.error().captcha().image_url,
4313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          UTF16ToWide(msg));
43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    default:
43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Unless there's new GoogleServiceAuthError state has been added.
43521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NOTREACHED();
43621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      break;
43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
43821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ScreenLocker::default_screen_locker()->ShowErrorMessage(UTF16ToWide(msg),
4403f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                          sign_out_only);
44121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
44221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
44321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveScreenLocked() {
44421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen locked";
44521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ResolveLockNetworkAuthFailure();
44621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
44721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
44821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveScreenUnlocked() {
44921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen unlocked";
45021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  registrar_.RemoveAll();
45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // If screen was unlocked that was for a reason, should delete itself now.
45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
45321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
45421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
455bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::StartAuthentication() {
45621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Auth started";
457731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
458bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile();
45921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (delegate_) {
46021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
46121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserThread::PostTask(
46221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        BrowserThread::UI, FROM_HERE,
46321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewRunnableMethod(authenticator_.get(),
46421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          &Authenticator::AuthenticateToLogin,
46521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          profile,
46621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          username_,
46721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          password_,
46821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_token_,
46921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_));
47021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
47121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(authenticator_.get())
47221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        << "Authenticator instance doesn't exist for login attempt retry.";
47321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // At this point offline auth has been successful,
47421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // retry online auth, using existing Authenticator instance.
47521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserThread::PostTask(
47621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        BrowserThread::UI, FROM_HERE,
47721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewRunnableMethod(authenticator_.get(),
47821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          &Authenticator::RetryAuth,
47921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          profile,
48021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          username_,
48121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          password_,
48221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_token_,
48321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_));
48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
485bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  password_.clear();
486bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
487bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
488bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace chromeos
489