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 {
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Online login has succeeded.
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(!pending_requests)
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        << "Pending request w/o delegate_ should not happen!";
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // It is not guaranted, that profile creation has been finished yet. So use
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // async version here.
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    credentials_ = credentials;
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ProfileManager::CreateDefaultProfileAsync(this);
145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid LoginPerformer::OnProfileCreated(Profile* profile) {
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CHECK(profile);
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  LoginUtils::Get()->FetchCookies(profile, credentials_);
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  LoginUtils::Get()->FetchTokens(profile, credentials_);
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  credentials_ = GaiaAuthConsumer::ClientLoginResult();
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Don't unlock screen if it was locked while we're waiting
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // for initial online auth.
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (ScreenLocker::default_screen_locker() &&
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      !initial_online_auth_pending_) {
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DVLOG(1) << "Online login OK - unlocking screen.";
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    RequestScreenUnlock();
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Do not delete itself just yet, wait for unlock.
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // See ResolveScreenUnlocked().
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  initial_online_auth_pending_ = false;
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // There's nothing else that's holding LP from deleting itself -
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // no ScreenLock, no pending requests.
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::OnOffTheRecordLoginSuccess() {
17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  UserMetrics::RecordAction(
17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      UserMetricsAction("Login_GuestLoginSuccess"));
17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
175bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (delegate_)
176bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    delegate_->OnOffTheRecordLoginSuccess();
177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  else
178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    NOTREACHED();
179bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
181bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::OnPasswordChangeDetected(
182bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    const GaiaAuthConsumer::ClientLoginResult& credentials) {
183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_credentials_ = credentials;
184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (delegate_) {
185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    delegate_->OnPasswordChangeDetected(credentials);
186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    last_login_failure_ =
18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        LoginFailure::FromNetworkAuthFailure(GoogleServiceAuthError(
18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    password_changed_ = true;
19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DVLOG(1) << "Password change detected - locking screen.";
19221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    RequestScreenLock();
193bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
195bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
196bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
197bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, SignedSettingsHelper::Callback implementation:
198bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::OnCheckWhitelistCompleted(SignedSettings::ReturnCode code,
200bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                               const std::string& email) {
20121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (code == SignedSettings::SUCCESS) {
202bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // Whitelist check passed, continue with authentication.
203bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    StartAuthentication();
204bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
205bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (delegate_)
206bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      delegate_->WhiteListCheckFailed(email);
207bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    else
208bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NOTREACHED();
209bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
210bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
211bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
212bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// LoginPerformer, NotificationObserver implementation:
21421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen//
21521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
21621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::Observe(NotificationType type,
21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                             const NotificationSource& source,
21821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                             const NotificationDetails& details) {
21921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (type != NotificationType::SCREEN_LOCK_STATE_CHANGED)
22021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return;
22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool is_screen_locked = *Details<bool>(details).ptr();
22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (is_screen_locked) {
22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (screen_lock_requested_) {
22521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      screen_lock_requested_ = false;
22621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ResolveScreenLocked();
22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
22821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
22921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveScreenUnlocked();
23021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
23121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
23221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen////////////////////////////////////////////////////////////////////////////////
234bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, public:
235bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
236bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::Login(const std::string& username,
237bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                           const std::string& password) {
238bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  username_ = username;
239bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  password_ = password;
24021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Whitelist check is always performed during initial login and
24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // should not be performed when ScreenLock is active (pending online auth).
24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (!ScreenLocker::default_screen_locker()) {
24421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Must not proceed without signature verification.
24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    UserCrosSettingsProvider user_settings;
24621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    bool trusted_setting_available = user_settings.RequestTrustedAllowNewUser(
24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        method_factory_.NewRunnableMethod(&LoginPerformer::Login,
24821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                          username,
24921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                          password));
25021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!trusted_setting_available) {
25121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Value of AllowNewUser setting is still not verified.
25221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Another attempt will be invoked after verification completion.
25321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
25421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    }
25521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
25621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
25721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker() ||
25821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      UserCrosSettingsProvider::cached_allow_new_user()) {
25921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Starts authentication if guest login is allowed or online auth pending.
260bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    StartAuthentication();
261bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
262bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // Otherwise, do whitelist check first.
26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    PrefService* local_state = g_browser_process->local_state();
26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    CHECK(local_state);
26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (local_state->IsManagedPreference(kAccountsPrefUsers)) {
26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (UserCrosSettingsProvider::IsEmailInCachedWhitelist(username)) {
26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        StartAuthentication();
26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      } else {
26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        if (delegate_)
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          delegate_->WhiteListCheckFailed(username);
27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        else
27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          NOTREACHED();
27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    } else {
27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // In case of signed settings: with current implementation we do not
27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // trust whitelist returned by PrefService.  So make separate check.
27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      SignedSettingsHelper::Get()->StartCheckWhitelistOp(
27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          username, this);
27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
280bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
281bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
282bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
283bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::LoginOffTheRecord() {
284bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
287bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewRunnableMethod(authenticator_.get(),
288bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        &Authenticator::LoginOffTheRecord));
289bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
290bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
291bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
294bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewRunnableMethod(authenticator_.get(),
295bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        &Authenticator::RecoverEncryptedData,
296bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        old_password,
297bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        cached_credentials_));
298bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_credentials_ = GaiaAuthConsumer::ClientLoginResult();
299bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
300bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
301bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::ResyncEncryptedData() {
302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
304bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      NewRunnableMethod(authenticator_.get(),
305bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        &Authenticator::ResyncEncryptedData,
306bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        cached_credentials_));
307bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  cached_credentials_ = GaiaAuthConsumer::ClientLoginResult();
308bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
309bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
310bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
311bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// LoginPerformer, private:
312bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
31321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::RequestScreenLock() {
31421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen lock requested";
31521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Will receive notifications on screen unlock and delete itself.
31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  registrar_.Add(this,
31721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationType::SCREEN_LOCK_STATE_CHANGED,
31821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                 NotificationService::AllSources());
31921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker()) {
32021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DVLOG(1) << "Screen already locked";
32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ResolveScreenLocked();
32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    screen_lock_requested_ = true;
32421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    chromeos::CrosLibrary::Get()->GetScreenLockLibrary()->
32521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NotifyScreenLockRequested();
32621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
32721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
32821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
32921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::RequestScreenUnlock() {
33021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen unlock requested";
33121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (ScreenLocker::default_screen_locker()) {
33221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    chromeos::CrosLibrary::Get()->GetScreenLockLibrary()->
33321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NotifyScreenUnlockRequested();
33421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Will unsubscribe from notifications once unlock is successful.
33521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
33621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    LOG(ERROR) << "Screen is not locked";
33721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    NOTREACHED();
33821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
33921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveInitialNetworkAuthFailure() {
34221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "auth_error: " << last_login_failure_.error().state();
34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
34421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  switch (last_login_failure_.error().state()) {
34521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CONNECTION_FAILED:
34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::TWO_FACTOR:
34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::REQUEST_CANCELED:
34921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Offline auth already done. Online auth will be done next time
35021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // or once user accesses web property.
35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      VLOG(1) << "Granting user access based on offline auth only. "
35221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              << "Online login failed with "
35321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              << last_login_failure_.error().state();
35421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Resolving initial online auth failure, no ScreenLock is active.
35521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      MessageLoop::current()->DeleteSoon(FROM_HERE, this);
35621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
35721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
35821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Offline auth OK, so it might be the case of changed password.
35921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      password_changed_ = true;
36021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
36121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DELETED:
36221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DISABLED:
36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Access not granted. User has to sign out.
36421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Request screen lock & show error message there.
36521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CAPTCHA_REQUIRED:
36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // User is requested to enter CAPTCHA challenge.
36772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      captcha_token_ = last_login_failure_.error().captcha().token;
36821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      RequestScreenLock();
36921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
37021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    default:
37121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Unless there's new GoogleServiceAuthErrors state has been added.
37221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NOTREACHED();
37321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
37421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
37521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveLockLoginFailure() {
37821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (last_login_failure_.reason() == LoginFailure::LOGIN_TIMED_OUT) {
37921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     LOG(WARNING) << "Online login timed out - unlocking screen. "
38021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  << "Granting user access based on offline auth only.";
38121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     RequestScreenUnlock();
38221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     return;
38321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   } else if (last_login_failure_.reason() ==
38421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  LoginFailure::NETWORK_AUTH_FAILED) {
38521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     ResolveLockNetworkAuthFailure();
38621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     return;
38721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   } else if (last_login_failure_.reason() ==
38821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  LoginFailure::COULD_NOT_MOUNT_CRYPTOHOME ||
38921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen              last_login_failure_.reason() ==
39021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  LoginFailure::DATA_REMOVAL_FAILED) {
39121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     LOG(ERROR) << "Cryptohome error, forcing sign out.";
39221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   } else {
39321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     // COULD_NOT_MOUNT_TMPFS, UNLOCK_FAILED should not happen here.
39421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen     NOTREACHED();
39521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   }
39621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen   ScreenLocker::default_screen_locker()->Signout();
39721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
39821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
39921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveLockNetworkAuthFailure() {
40021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(ScreenLocker::default_screen_locker())
40121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      << "ScreenLocker instance doesn't exist.";
40221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DCHECK(last_login_failure_.reason() == LoginFailure::NETWORK_AUTH_FAILED);
40321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  string16 msg;
40521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool sign_out_only = false;
40621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "auth_error: " << last_login_failure_.error().state();
40821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
40921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  switch (last_login_failure_.error().state()) {
41021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CONNECTION_FAILED:
41121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
41221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::TWO_FACTOR:
41321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::REQUEST_CANCELED:
41421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Offline auth already done. Online auth will be done next time
41521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // or once user accesses web property.
41621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      LOG(WARNING) << "Granting user access based on offline auth only. "
41721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   << "Online login failed with "
41821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                   << last_login_failure_.error().state();
41921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      RequestScreenUnlock();
42021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
42121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
42221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Password change detected.
4233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      msg = l10n_util::GetStringUTF16(IDS_LOGIN_ERROR_PASSWORD_CHANGED);
42421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      break;
42521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
42621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DELETED:
42721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::ACCOUNT_DISABLED:
42821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Access not granted. User has to sign out.
42921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Show error message using existing screen lock.
4303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      msg = l10n_util::GetStringUTF16(IDS_LOGIN_ERROR_RESTRICTED);
43121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      sign_out_only = true;
43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      break;
43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    case GoogleServiceAuthError::CAPTCHA_REQUIRED:
43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // User is requested to enter CAPTCHA challenge.
43572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      captcha_token_ = last_login_failure_.error().captcha().token;
4363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      msg = l10n_util::GetStringUTF16(IDS_LOGIN_ERROR_PASSWORD_CHANGED);
43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ScreenLocker::default_screen_locker()->ShowCaptchaAndErrorMessage(
43821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          last_login_failure_.error().captcha().image_url,
4393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          UTF16ToWide(msg));
44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      return;
44121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    default:
44221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      // Unless there's new GoogleServiceAuthError state has been added.
44321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      NOTREACHED();
44421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      break;
44521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
44621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
4473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  ScreenLocker::default_screen_locker()->ShowErrorMessage(UTF16ToWide(msg),
4483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                                          sign_out_only);
44921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
45021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveScreenLocked() {
45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen locked";
45321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ResolveLockNetworkAuthFailure();
45421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
45521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
45621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid LoginPerformer::ResolveScreenUnlocked() {
45721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Screen unlocked";
45821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  registrar_.RemoveAll();
45921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // If screen was unlocked that was for a reason, should delete itself now.
46021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MessageLoop::current()->DeleteSoon(FROM_HERE, this);
46121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
46221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
463bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid LoginPerformer::StartAuthentication() {
46421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DVLOG(1) << "Auth started";
465731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
466bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile();
46721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (delegate_) {
46821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
46921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserThread::PostTask(
47021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        BrowserThread::UI, FROM_HERE,
47121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewRunnableMethod(authenticator_.get(),
47221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          &Authenticator::AuthenticateToLogin,
47321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          profile,
47421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          username_,
47521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          password_,
47621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_token_,
47721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_));
47821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  } else {
47921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    DCHECK(authenticator_.get())
48021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        << "Authenticator instance doesn't exist for login attempt retry.";
48121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // At this point offline auth has been successful,
48221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // retry online auth, using existing Authenticator instance.
48321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    BrowserThread::PostTask(
48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        BrowserThread::UI, FROM_HERE,
48521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewRunnableMethod(authenticator_.get(),
48621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          &Authenticator::RetryAuth,
48721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          profile,
48821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          username_,
48921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          password_,
49021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_token_,
49121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                          captcha_));
49221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
493bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  password_.clear();
494bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
495bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
496bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace chromeos
497