login_performer.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_performer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/boot_times_loader.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/login_utils.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/managed/locally_managed_user_login_flow.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/profiles/profile_helper.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings_names.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/policy/browser_policy_connector.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/session_manager_client.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_monster.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/cookie_store.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::UserMetricsAction;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoginPerformer::LoginPerformer(Delegate* delegate)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : online_attempt_host_(this),
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      last_login_failure_(LoginFailure::LoginFailureNone()),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delegate_(delegate),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      password_changed_(false),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      password_changed_callback_count_(0),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_mode_(AUTH_MODE_INTERNAL),
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      weak_factory_(this) {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoginPerformer::~LoginPerformer() {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Deleting LoginPerformer";
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (authenticator_.get())
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_->SetConsumer(NULL);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoginPerformer, LoginStatusConsumer implementation:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnLoginFailure(const LoginFailure& failure) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Login_Failure"));
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Login.FailureReason", failure.reason(),
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            LoginFailure::NUM_FAILURE_REASONS);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "failure.reason " << failure.reason();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "failure.error.state " << failure.error().state();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_login_failure_ = failure;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnLoginFailure(failure);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // happens during offline auth only.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void LoginPerformer::OnRetailModeLoginSuccess(
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UserContext& user_context) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UserMetricsAction("Login_DemoUserLoginSuccess"));
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  LoginStatusConsumer::OnRetailModeLoginSuccess(user_context);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnLoginSuccess(
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UserContext& user_context,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool pending_requests,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool using_oauth) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(UserMetricsAction("Login_Success"));
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The value of |pending_requests| indicates:
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 0 - New regular user, login success offline and online.
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //     - or -
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //     Existing regular user, login success offline and online, offline
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //     authentication took longer than online authentication.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //     - or -
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //     Public account user, login successful.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // 1 - Existing regular user, login success offline only.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Login.SuccessReason", pending_requests, 2);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  VLOG(1) << "LoginSuccess hash: " << user_context.username_hash
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          << ", pending_requests " << pending_requests;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(delegate_);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // After delegate_->OnLoginSuccess(...) is called, delegate_ releases
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // LoginPerformer ownership. LP now manages it's lifetime on its own.
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK(!pending_requests);
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  delegate_->OnLoginSuccess(user_context,
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            pending_requests,
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            using_oauth);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnOffTheRecordLoginSuccess() {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RecordAction(
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UserMetricsAction("Login_GuestLoginSuccess"));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnOffTheRecordLoginSuccess();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnPasswordChangeDetected() {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  password_changed_ = true;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  password_changed_callback_count_++;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnPasswordChangeDetected();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NOTREACHED();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::OnChecked(const std::string& username, bool success) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!delegate_) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Delegate is reset in case of successful offline login.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // See ExistingUserConstoller::OnLoginSuccess().
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Case when user has changed password and enters old password
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // does not block user from sign in yet.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_->OnOnlineChecked(username, success);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoginPerformer, public:
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void LoginPerformer::PerformLogin(const UserContext& user_context,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  AuthorizationMode auth_mode) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_mode_ = auth_mode;
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_ = user_context;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CrosSettings* cros_settings = CrosSettings::Get();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Whitelist check is always performed during initial login.
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  CrosSettingsProvider::TrustedStatus status =
1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      cros_settings->PrepareTrustedValues(
1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          base::Bind(&LoginPerformer::PerformLogin,
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     weak_factory_.GetWeakPtr(),
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                     user_context_, auth_mode));
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Must not proceed without signature verification.
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (delegate_)
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      delegate_->PolicyLoadFailed();
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    else
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NOTREACHED();
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else if (status != CrosSettingsProvider::TRUSTED) {
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Value of AllowNewUser setting is still not verified.
1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // Another attempt will be invoked after verification completion.
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_whitelisted = LoginUtils::IsWhitelisted(
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      gaia::CanonicalizeEmail(user_context.username));
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (is_whitelisted) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (auth_mode_) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case AUTH_MODE_EXTENSION:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        StartLoginCompletion();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case AUTH_MODE_INTERNAL:
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        StartAuthentication();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (delegate_)
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      delegate_->WhiteListCheckFailed(user_context.username);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginPerformer::LoginAsLocallyManagedUser(
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const UserContext& user_context) {
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(UserManager::kLocallyManagedUserDomain,
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            gaia::ExtractDomainName(user_context.username));
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(nkostylev): Check that policy allows locally managed user login.
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UserFlow* new_flow = new LocallyManagedUserLoginFlow(user_context.username);
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  new_flow->set_host(
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      UserManager::Get()->GetUserFlow(user_context.username)->host());
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UserManager::Get()->SetUserFlow(user_context.username, new_flow);
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&Authenticator::LoginAsLocallyManagedUser,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 authenticator_.get(),
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 user_context));
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginPerformer::LoginRetailMode() {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&Authenticator::LoginRetailMode, authenticator_.get()));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::LoginOffTheRecord() {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::LoginOffTheRecord, authenticator_.get()));
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LoginPerformer::LoginAsPublicAccount(const std::string& username) {
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Login is not allowed if policy could not be loaded for the account.
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  policy::DeviceLocalAccountPolicyService* policy_service =
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      g_browser_process->browser_policy_connector()->
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetDeviceLocalAccountPolicyService();
23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!policy_service || !policy_service->IsPolicyAvailableForUser(username)) {
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(delegate_);
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (delegate_)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delegate_->PolicyLoadFailed();
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BrowserThread::PostTask(
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&Authenticator::LoginAsPublicAccount, authenticator_.get(),
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 username));
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::RecoverEncryptedData, authenticator_.get(),
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 old_password));
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::ResyncEncryptedData() {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::ResyncEncryptedData, authenticator_.get()));
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoginPerformer, private:
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::StartLoginCompletion() {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Login completion started";
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Profile* profile = ProfileHelper::GetSigninProfile();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserThread::PostTask(
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserThread::UI, FROM_HERE,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&Authenticator::CompleteLogin, authenticator_.get(),
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 profile,
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                 user_context_));
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.password.clear();
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.auth_code.clear();
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginPerformer::StartAuthentication() {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Auth started";
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BootTimesLoader::Get()->AddLoginTimeMarker("AuthStarted", false);
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Profile* profile = ProfileHelper::GetSigninProfile();
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (delegate_) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::UI, FROM_HERE,
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&Authenticator::AuthenticateToLogin, authenticator_.get(),
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   profile,
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   user_context_));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make unobtrusive online check. It helps to determine password change
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // state in the case when offline login fails.
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    online_attempt_host_.Check(profile, user_context_);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NOTREACHED();
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.password.clear();
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  user_context_.auth_code.clear();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
305