// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/login/auth/login_performer.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"
#include "chromeos/login/auth/login_event_recorder.h"
#include "components/account_id/account_id.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_names.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "net/cookies/cookie_monster.h"
#include "net/cookies/cookie_store.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"

using base::UserMetricsAction;

namespace chromeos {

LoginPerformer::LoginPerformer(scoped_refptr<base::TaskRunner> task_runner,
                               Delegate* delegate)
    : delegate_(delegate),
      task_runner_(task_runner),
      last_login_failure_(AuthFailure::AuthFailureNone()),
      password_changed_(false),
      password_changed_callback_count_(0),
      auth_mode_(AUTH_MODE_INTERNAL),
      weak_factory_(this) {}

LoginPerformer::~LoginPerformer() {
  DVLOG(1) << "Deleting LoginPerformer";
  if (authenticator_.get())
    authenticator_->SetConsumer(NULL);
  if (extended_authenticator_.get())
    extended_authenticator_->SetConsumer(NULL);
}

////////////////////////////////////////////////////////////////////////////////
// LoginPerformer, AuthStatusConsumer implementation:

void LoginPerformer::OnAuthFailure(const AuthFailure& failure) {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  base::RecordAction(UserMetricsAction("Login_Failure"));

  UMA_HISTOGRAM_ENUMERATION("Login.FailureReason",
                            failure.reason(),
                            AuthFailure::NUM_FAILURE_REASONS);

  LOG(ERROR) << "Login failure, reason=" << failure.reason()
             << ", error.state=" << failure.error().state();

  last_login_failure_ = failure;
  if (delegate_) {
    delegate_->SetAuthFlowOffline(user_context_.GetAuthFlow() ==
                                  UserContext::AUTH_FLOW_OFFLINE);
    delegate_->OnAuthFailure(failure);
    return;
  } else {
    // COULD_NOT_MOUNT_CRYPTOHOME, COULD_NOT_MOUNT_TMPFS:
    // happens during offline auth only.
    NOTREACHED();
  }
}

void LoginPerformer::OnAuthSuccess(const UserContext& user_context) {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  base::RecordAction(UserMetricsAction("Login_Success"));

  // Do not distinguish between offline and online success.
  UMA_HISTOGRAM_ENUMERATION("Login.SuccessReason", OFFLINE_AND_ONLINE,
                            NUM_SUCCESS_REASONS);

  VLOG(1) << "LoginSuccess hash: " << user_context.GetUserIDHash();
  DCHECK(delegate_);
  // After delegate_->OnAuthSuccess(...) is called, delegate_ releases
  // LoginPerformer ownership. LP now manages it's lifetime on its own.
  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
  delegate_->OnAuthSuccess(user_context);
}

void LoginPerformer::OnOffTheRecordAuthSuccess() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  base::RecordAction(UserMetricsAction("Login_GuestLoginSuccess"));

  if (delegate_)
    delegate_->OnOffTheRecordAuthSuccess();
  else
    NOTREACHED();
}

void LoginPerformer::OnPasswordChangeDetected() {
  password_changed_ = true;
  password_changed_callback_count_++;
  if (delegate_) {
    delegate_->OnPasswordChangeDetected();
  } else {
    NOTREACHED();
  }
}

void LoginPerformer::OnOldEncryptionDetected(const UserContext& user_context,
                                             bool has_incomplete_migration) {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());

  if (delegate_)
    delegate_->OnOldEncryptionDetected(user_context, has_incomplete_migration);
  else
    NOTREACHED();
}

////////////////////////////////////////////////////////////////////////////////
// LoginPerformer, public:

void LoginPerformer::NotifyWhitelistCheckFailure() {
  if (delegate_)
    delegate_->WhiteListCheckFailed(
        user_context_.GetAccountId().GetUserEmail());
  else
    NOTREACHED();
}

void LoginPerformer::PerformLogin(const UserContext& user_context,
                                  AuthorizationMode auth_mode) {
  auth_mode_ = auth_mode;
  user_context_ = user_context;

  if (RunTrustedCheck(base::Bind(&LoginPerformer::DoPerformLogin,
                                 weak_factory_.GetWeakPtr(),
                                 user_context_,
                                 auth_mode))) {
    return;
  }
  DoPerformLogin(user_context_, auth_mode);
}

void LoginPerformer::DoPerformLogin(const UserContext& user_context,
                                    AuthorizationMode auth_mode) {
  bool wildcard_match = false;

  const AccountId& account_id = user_context.GetAccountId();
  if (!IsUserWhitelisted(account_id, &wildcard_match)) {
    NotifyWhitelistCheckFailure();
    return;
  }

  if (user_context.GetAuthFlow() == UserContext::AUTH_FLOW_EASY_UNLOCK)
    SetupEasyUnlockUserFlow(user_context.GetAccountId());

  switch (auth_mode_) {
    case AUTH_MODE_EXTENSION: {
      RunOnlineWhitelistCheck(
          account_id, wildcard_match, user_context.GetRefreshToken(),
          base::Bind(&LoginPerformer::StartLoginCompletion,
                     weak_factory_.GetWeakPtr()),
          base::Bind(&LoginPerformer::NotifyWhitelistCheckFailure,
                     weak_factory_.GetWeakPtr()));
      break;
    }
    case AUTH_MODE_INTERNAL:
      StartAuthentication();
      break;
  }
}

void LoginPerformer::LoginAsSupervisedUser(const UserContext& user_context) {
  DCHECK_EQ(
      user_manager::kSupervisedUserDomain,
      gaia::ExtractDomainName(user_context.GetAccountId().GetUserEmail()));

  user_context_ = user_context;
  if (user_context_.GetUserType() != user_manager::USER_TYPE_SUPERVISED) {
    LOG(FATAL) << "Incorrect supervised user type "
               << user_context_.GetUserType();
  }

  if (RunTrustedCheck(base::Bind(&LoginPerformer::TrustedLoginAsSupervisedUser,
                                 weak_factory_.GetWeakPtr(),
                                 user_context_))) {
    return;
  }
  TrustedLoginAsSupervisedUser(user_context_);
}

void LoginPerformer::TrustedLoginAsSupervisedUser(
    const UserContext& user_context) {
  if (!AreSupervisedUsersAllowed()) {
    LOG(ERROR) << "Login attempt of supervised user detected.";
    delegate_->WhiteListCheckFailed(user_context.GetAccountId().GetUserEmail());
    return;
  }

  SetupSupervisedUserFlow(user_context.GetAccountId());
  UserContext user_context_copy = TransformSupervisedKey(user_context);

  if (UseExtendedAuthenticatorForSupervisedUser(user_context)) {
    EnsureExtendedAuthenticator();
    // TODO(antrim) : Replace empty callback with explicit method.
    // http://crbug.com/351268
    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&ExtendedAuthenticator::AuthenticateToMount,
                       extended_authenticator_.get(), user_context_copy,
                       ExtendedAuthenticator::ResultCallback()));

  } else {
    EnsureAuthenticator();
    task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&Authenticator::LoginAsSupervisedUser,
                                  authenticator_.get(), user_context_copy));
  }
}

void LoginPerformer::LoginAsPublicSession(const UserContext& user_context) {
  if (!CheckPolicyForUser(user_context.GetAccountId())) {
    DCHECK(delegate_);
    if (delegate_)
      delegate_->PolicyLoadFailed();
    return;
  }

  EnsureAuthenticator();
  task_runner_->PostTask(FROM_HERE,
                         base::BindOnce(&Authenticator::LoginAsPublicSession,
                                        authenticator_.get(), user_context));
}

void LoginPerformer::LoginOffTheRecord() {
  EnsureAuthenticator();
  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&Authenticator::LoginOffTheRecord, authenticator_.get()));
}

void LoginPerformer::LoginAsKioskAccount(const AccountId& app_account_id,
                                         bool use_guest_mount) {
  EnsureAuthenticator();
  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&Authenticator::LoginAsKioskAccount, authenticator_.get(),
                     app_account_id, use_guest_mount));
}

void LoginPerformer::LoginAsArcKioskAccount(
    const AccountId& arc_app_account_id) {
  EnsureAuthenticator();
  task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&Authenticator::LoginAsArcKioskAccount,
                                authenticator_.get(), arc_app_account_id));
}

void LoginPerformer::RecoverEncryptedData(const std::string& old_password) {
  task_runner_->PostTask(FROM_HERE,
                         base::BindOnce(&Authenticator::RecoverEncryptedData,
                                        authenticator_.get(), old_password));
}

void LoginPerformer::ResyncEncryptedData() {
  task_runner_->PostTask(FROM_HERE,
                         base::BindOnce(&Authenticator::ResyncEncryptedData,
                                        authenticator_.get()));
}

////////////////////////////////////////////////////////////////////////////////
// LoginPerformer, private:

void LoginPerformer::EnsureExtendedAuthenticator() {
  if (extended_authenticator_.get())
    extended_authenticator_->SetConsumer(NULL);
  extended_authenticator_ = ExtendedAuthenticator::Create(this);
}

void LoginPerformer::StartLoginCompletion() {
  VLOG(1) << "Online login completion started.";
  chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker("AuthStarted", false);
  content::BrowserContext* browser_context = GetSigninContext();
  EnsureAuthenticator();
  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&chromeos::Authenticator::CompleteLogin,
                     authenticator_.get(), browser_context, user_context_));
  user_context_.ClearSecrets();
}

void LoginPerformer::StartAuthentication() {
  VLOG(1) << "Offline auth started.";
  chromeos::LoginEventRecorder::Get()->AddLoginTimeMarker("AuthStarted", false);
  if (delegate_) {
    EnsureAuthenticator();
    content::BrowserContext* browser_context = GetSigninContext();
    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&Authenticator::AuthenticateToLogin,
                       authenticator_.get(), base::Unretained(browser_context),
                       user_context_));
  } else {
    NOTREACHED();
  }
  user_context_.ClearSecrets();
}

void LoginPerformer::EnsureAuthenticator() {
  authenticator_ = CreateAuthenticator();
}
}  // namespace chromeos
