// Copyright 2013 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 "chrome/browser/ui/webui/signin/inline_login_handler_impl.h"

#include <stddef.h>

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/macros.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/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/signin/about_signin_internals_factory.h"
#include "chrome/browser/signin/account_consistency_mode_manager.h"
#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/local_auth.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_error_controller_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/signin/signin_promo.h"
#include "chrome/browser/signin/signin_util.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/tab_modal_confirm_dialog.h"
#include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/user_manager.h"
#include "chrome/browser/ui/webui/signin/login_ui_service.h"
#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
#include "chrome/browser/ui/webui/signin/signin_utils.h"
#include "chrome/browser/ui/webui/signin/signin_utils_desktop.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/chromium_strings.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/prefs/pref_service.h"
#include "components/signin/core/browser/about_signin_internals.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_error_controller.h"
#include "components/signin/core/browser/signin_header_helper.h"
#include "components/signin/core/browser/signin_investigator.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "components/signin/core/browser/signin_pref_names.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_ui.h"
#include "google_apis/gaia/gaia_auth_fetcher.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/base/url_util.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

void LogHistogramValue(signin_metrics::AccessPointAction action) {
  UMA_HISTOGRAM_ENUMERATION("Signin.AllAccessPointActions", action,
                            signin_metrics::HISTOGRAM_MAX);
}

// Returns true if |profile| is a system profile or created from one.
bool IsSystemProfile(Profile* profile) {
  return profile->GetOriginalProfile()->IsSystemProfile();
}

void RedirectToNtpOrAppsPage(content::WebContents* contents,
                             signin_metrics::AccessPoint access_point) {
  // Do nothing if a navigation is pending, since this call can be triggered
  // from DidStartLoading. This avoids deleting the pending entry while we are
  // still navigating to it. See crbug/346632.
  if (contents->GetController().GetPendingEntry())
    return;

  VLOG(1) << "RedirectToNtpOrAppsPage";
  // Redirect to NTP/Apps page and display a confirmation bubble
  GURL url(access_point ==
                   signin_metrics::AccessPoint::ACCESS_POINT_APPS_PAGE_LINK
               ? chrome::kChromeUIAppsURL
               : chrome::kChromeUINewTabURL);
  content::OpenURLParams params(url, content::Referrer(),
                                WindowOpenDisposition::CURRENT_TAB,
                                ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false);
  contents->OpenURL(params);
}

void RedirectToNtpOrAppsPageIfNecessary(
    content::WebContents* contents,
    signin_metrics::AccessPoint access_point) {
  if (access_point != signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS)
    RedirectToNtpOrAppsPage(contents, access_point);
}

void CloseModalSigninIfNeeded(InlineLoginHandlerImpl* handler) {
  if (handler) {
    Browser* browser = handler->GetDesktopBrowser();
    if (browser)
      browser->signin_view_controller()->CloseModalSignin();
  }
}

void UnlockProfileAndHideLoginUI(const base::FilePath profile_path,
                                 InlineLoginHandlerImpl* handler) {
  if (!profile_path.empty()) {
    ProfileManager* profile_manager = g_browser_process->profile_manager();
    if (profile_manager) {
      ProfileAttributesEntry* entry;
      if (profile_manager->GetProfileAttributesStorage()
              .GetProfileAttributesWithPath(profile_path, &entry)) {
        entry->SetIsSigninRequired(false);
      }
    }
  }
  if (handler)
    handler->CloseDialogFromJavascript();

  UserManager::Hide();
}

// Returns true if the showAccountManagement parameter in the given url is set
// to true.
bool ShouldShowAccountManagement(const GURL& url, bool is_mirror_enabled) {
  if (!is_mirror_enabled)
    return false;

  std::string value;
  if (net::GetValueForKeyInQuery(url, kSignInPromoQueryKeyShowAccountManagement,
                                 &value)) {
    int enabled = 0;
    if (base::StringToInt(value, &enabled) && enabled == 1)
      return true;
  }
  return false;
}

}  // namespace

InlineSigninHelper::InlineSigninHelper(
    base::WeakPtr<InlineLoginHandlerImpl> handler,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    Profile* profile,
    Profile::CreateStatus create_status,
    const GURL& current_url,
    const std::string& email,
    const std::string& gaia_id,
    const std::string& password,
    const std::string& session_index,
    const std::string& auth_code,
    const std::string& signin_scoped_device_id,
    bool choose_what_to_sync,
    bool confirm_untrusted_signin,
    bool is_force_sign_in_with_usermanager)
    : gaia_auth_fetcher_(this,
                         GaiaConstants::kChromeSource,
                         url_loader_factory),
      handler_(handler),
      profile_(profile),
      create_status_(create_status),
      current_url_(current_url),
      email_(email),
      gaia_id_(gaia_id),
      password_(password),
      session_index_(session_index),
      auth_code_(auth_code),
      choose_what_to_sync_(choose_what_to_sync),
      confirm_untrusted_signin_(confirm_untrusted_signin),
      is_force_sign_in_with_usermanager_(is_force_sign_in_with_usermanager) {
  DCHECK(profile_);
  DCHECK(!email_.empty());
  if (!auth_code_.empty()) {
    gaia_auth_fetcher_.StartAuthCodeForOAuth2TokenExchangeWithDeviceId(
        auth_code, signin_scoped_device_id);
  } else {
    DCHECK(!session_index_.empty());
    gaia_auth_fetcher_
        .DeprecatedStartCookieForOAuthLoginTokenExchangeWithDeviceId(
            session_index_, signin_scoped_device_id);
  }
}

InlineSigninHelper::~InlineSigninHelper() {}

void InlineSigninHelper::OnClientOAuthSuccess(const ClientOAuthResult& result) {
  if (is_force_sign_in_with_usermanager_) {
    // If user sign in in UserManager with force sign in enabled, the browser
    // window won't be opened until now.
    profiles::OpenBrowserWindowForProfile(
        base::Bind(&InlineSigninHelper::OnClientOAuthSuccessAndBrowserOpened,
                   base::Unretained(this), result),
        true, false, profile_, create_status_);
  } else {
    OnClientOAuthSuccessAndBrowserOpened(result, profile_, create_status_);
  }
}

void InlineSigninHelper::OnClientOAuthSuccessAndBrowserOpened(
    const ClientOAuthResult& result,
    Profile* profile,
    Profile::CreateStatus status) {
  if (is_force_sign_in_with_usermanager_)
    UnlockProfileAndHideLoginUI(profile_->GetPath(), handler_.get());
  Browser* browser = NULL;
  if (handler_) {
    browser = handler_->GetDesktopBrowser();
  }

  AboutSigninInternals* about_signin_internals =
      AboutSigninInternalsFactory::GetForProfile(profile_);
  about_signin_internals->OnRefreshTokenReceived("Successful");

  // Prime the account tracker with this combination of gaia id/display email.
  std::string account_id =
      AccountTrackerServiceFactory::GetForProfile(profile_)
          ->SeedAccountInfo(gaia_id_, email_);

  signin_metrics::AccessPoint access_point =
      signin::GetAccessPointForPromoURL(current_url_);
  signin_metrics::Reason reason =
      signin::GetSigninReasonForPromoURL(current_url_);

  SigninManager* signin_manager = SigninManagerFactory::GetForProfile(profile_);
  std::string primary_email =
      signin_manager->GetAuthenticatedAccountInfo().email;
  if (gaia::AreEmailsSame(email_, primary_email) &&
      (reason == signin_metrics::Reason::REASON_REAUTHENTICATION ||
       reason == signin_metrics::Reason::REASON_UNLOCK) &&
      !password_.empty() && profiles::IsLockAvailable(profile_)) {
    LocalAuth::SetLocalAuthCredentials(profile_, password_);
  }

#if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED)
  if (!password_.empty()) {
    scoped_refptr<password_manager::PasswordStore> password_store =
        PasswordStoreFactory::GetForProfile(profile_,
                                            ServiceAccessType::EXPLICIT_ACCESS);
    if (password_store && !primary_email.empty()) {
      password_store->SaveGaiaPasswordHash(
          primary_email, base::UTF8ToUTF16(password_),
          password_manager::metrics_util::SyncPasswordHashChange::
              SAVED_ON_CHROME_SIGNIN);
    }
  }
#endif

  if (reason == signin_metrics::Reason::REASON_REAUTHENTICATION ||
      reason == signin_metrics::Reason::REASON_UNLOCK ||
      reason == signin_metrics::Reason::REASON_ADD_SECONDARY_ACCOUNT) {
    ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->
        UpdateCredentials(account_id, result.refresh_token);

    if (signin::IsAutoCloseEnabledInURL(current_url_)) {
      // Close the gaia sign in tab via a task to make sure we aren't in the
      // middle of any webui handler code.
      bool show_account_management = ShouldShowAccountManagement(
          current_url_,
          AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile_));
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&InlineLoginHandlerImpl::CloseTab, handler_,
                                    show_account_management));
    }

    if (reason == signin_metrics::Reason::REASON_REAUTHENTICATION ||
        reason == signin_metrics::Reason::REASON_UNLOCK) {
      signin_manager->MergeSigninCredentialIntoCookieJar();
    }
    LogSigninReason(reason);
  } else {
    browser_sync::ProfileSyncService* sync_service =
        ProfileSyncServiceFactory::GetForProfile(profile_);
    SigninErrorController* error_controller =
        SigninErrorControllerFactory::GetForProfile(profile_);

    OneClickSigninSyncStarter::StartSyncMode start_mode =
        OneClickSigninSyncStarter::CONFIRM_SYNC_SETTINGS_FIRST;
    if (access_point == signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS ||
        choose_what_to_sync_) {
      bool show_settings_without_configure =
          error_controller->HasError() && sync_service &&
          sync_service->IsFirstSetupComplete();
      if (!show_settings_without_configure)
        start_mode = OneClickSigninSyncStarter::CONFIGURE_SYNC_FIRST;
    }

    OneClickSigninSyncStarter::ConfirmationRequired confirmation_required =
        confirm_untrusted_signin_ ?
            OneClickSigninSyncStarter::CONFIRM_UNTRUSTED_SIGNIN :
            OneClickSigninSyncStarter::CONFIRM_AFTER_SIGNIN;

    bool start_signin = !HandleCrossAccountError(
        result.refresh_token, confirmation_required, start_mode);
    if (start_signin) {
      CreateSyncStarter(browser, current_url_, result.refresh_token,
                        OneClickSigninSyncStarter::CURRENT_PROFILE, start_mode,
                        confirmation_required);
      base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
    }
  }
}

void InlineSigninHelper::CreateSyncStarter(
    Browser* browser,
    const GURL& current_url,
    const std::string& refresh_token,
    OneClickSigninSyncStarter::ProfileMode profile_mode,
    OneClickSigninSyncStarter::StartSyncMode start_mode,
    OneClickSigninSyncStarter::ConfirmationRequired confirmation_required) {
  // OneClickSigninSyncStarter will delete itself once the job is done.
  new OneClickSigninSyncStarter(
      profile_, browser, gaia_id_, email_, password_, refresh_token,
      signin::GetAccessPointForPromoURL(current_url),
      signin::GetSigninReasonForPromoURL(current_url), profile_mode, start_mode,
      confirmation_required,
      base::Bind(&InlineLoginHandlerImpl::SyncStarterCallback, handler_));
}

bool InlineSigninHelper::HandleCrossAccountError(
    const std::string& refresh_token,
    OneClickSigninSyncStarter::ConfirmationRequired confirmation_required,
    OneClickSigninSyncStarter::StartSyncMode start_mode) {
  // With force sign in enabled, cross account
  // sign in will be rejected in the early stage so there is no need to show the
  // warning page here.
  if (signin_util::IsForceSigninEnabled())
    return false;

  std::string last_email =
      profile_->GetPrefs()->GetString(prefs::kGoogleServicesLastUsername);

  // TODO(skym): Warn for high risk upgrade scenario, crbug.com/572754.
  if (!IsCrossAccountError(profile_, email_, gaia_id_))
    return false;

  Browser* browser = chrome::FindLastActiveWithProfile(profile_);
  content::WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();

  SigninEmailConfirmationDialog::AskForConfirmation(
      web_contents, profile_, last_email, email_,
      base::Bind(&InlineSigninHelper::ConfirmEmailAction,
                 base::Unretained(this), web_contents, refresh_token,
                 confirmation_required, start_mode));
  return true;
}

void InlineSigninHelper::ConfirmEmailAction(
    content::WebContents* web_contents,
    const std::string& refresh_token,
    OneClickSigninSyncStarter::ConfirmationRequired confirmation_required,
    OneClickSigninSyncStarter::StartSyncMode start_mode,
    SigninEmailConfirmationDialog::Action action) {
  Browser* browser = chrome::FindLastActiveWithProfile(profile_);
  switch (action) {
    case SigninEmailConfirmationDialog::CREATE_NEW_USER:
      base::RecordAction(
          base::UserMetricsAction("Signin_ImportDataPrompt_DontImport"));
      CreateSyncStarter(browser, current_url_, refresh_token,
                        OneClickSigninSyncStarter::NEW_PROFILE, start_mode,
                        confirmation_required);
      break;
    case SigninEmailConfirmationDialog::START_SYNC:
      base::RecordAction(
          base::UserMetricsAction("Signin_ImportDataPrompt_ImportData"));
      CreateSyncStarter(browser, current_url_, refresh_token,
                        OneClickSigninSyncStarter::CURRENT_PROFILE, start_mode,
                        confirmation_required);
      break;
    case SigninEmailConfirmationDialog::CLOSE:
      base::RecordAction(
          base::UserMetricsAction("Signin_ImportDataPrompt_Cancel"));
      if (handler_) {
        handler_->SyncStarterCallback(
            OneClickSigninSyncStarter::SYNC_SETUP_FAILURE);
      }
      break;
    default:
      DCHECK(false) << "Invalid action";
  }
  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}

void InlineSigninHelper::OnClientOAuthFailure(
  const GoogleServiceAuthError& error) {
  if (handler_)
    handler_->HandleLoginError(error.ToString(), base::string16());

  AboutSigninInternals* about_signin_internals =
    AboutSigninInternalsFactory::GetForProfile(profile_);
  about_signin_internals->OnRefreshTokenReceived("Failure");

  base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this);
}

InlineLoginHandlerImpl::InlineLoginHandlerImpl()
      : confirm_untrusted_signin_(false),
        weak_factory_(this) {
}

InlineLoginHandlerImpl::~InlineLoginHandlerImpl() {}

// This method is not called with webview sign in enabled.
void InlineLoginHandlerImpl::DidFinishNavigation(
    content::NavigationHandle* navigation_handle) {
  if (!web_contents() ||
      !navigation_handle->HasCommitted() ||
      navigation_handle->IsErrorPage()) {
    return;
  }

  // Returns early if this is not a gaia webview navigation.
  content::RenderFrameHost* gaia_frame =
      signin::GetAuthFrame(web_contents(), "signin-frame");
  if (navigation_handle->GetRenderFrameHost() != gaia_frame)
    return;

  // Loading any untrusted (e.g., HTTP) URLs in the privileged sign-in process
  // will require confirmation before the sign in takes effect.
  const GURL kGaiaExtOrigin(
      GaiaUrls::GetInstance()->signin_completed_continue_url().GetOrigin());
  if (!navigation_handle->GetURL().is_empty()) {
    GURL origin(navigation_handle->GetURL().GetOrigin());
    if (navigation_handle->GetURL().spec() != url::kAboutBlankURL &&
        origin != kGaiaExtOrigin &&
        !gaia::IsGaiaSignonRealm(origin)) {
      confirm_untrusted_signin_ = true;
    }
  }
}

// static
void InlineLoginHandlerImpl::SetExtraInitParams(base::DictionaryValue& params) {
  params.SetString("service", "chromiumsync");

  // If this was called from the user manager to reauthenticate the profile,
  // make sure the webui is aware.
  Profile* profile = Profile::FromWebUI(web_ui());
  if (IsSystemProfile(profile))
    params.SetBoolean("dontResizeNonEmbeddedPages", true);

  content::WebContents* contents = web_ui()->GetWebContents();
  const GURL& current_url = contents->GetURL();
  signin_metrics::Reason reason =
      signin::GetSigninReasonForPromoURL(current_url);

  std::string is_constrained;
  net::GetValueForKeyInQuery(current_url, "constrained", &is_constrained);

  // Use new embedded flow if in constrained window.
  if (is_constrained == "1") {
    const GURL& url = GaiaUrls::GetInstance()->embedded_signin_url();
    params.SetBoolean("isNewGaiaFlow", true);
    params.SetString("clientId",
                     GaiaUrls::GetInstance()->oauth2_chrome_client_id());
    params.SetString("gaiaPath", url.path().substr(1));

    std::string flow;
    switch (reason) {
      case signin_metrics::Reason::REASON_ADD_SECONDARY_ACCOUNT:
        flow = "addaccount";
        break;
      case signin_metrics::Reason::REASON_REAUTHENTICATION:
      case signin_metrics::Reason::REASON_UNLOCK:
        flow = "reauth";
        break;
      case signin_metrics::Reason::REASON_FORCED_SIGNIN_PRIMARY_ACCOUNT:
        flow = "enterprisefsi";
        break;
      default:
        flow = "signin";
        break;
    }
    params.SetString("flow", flow);
  }

  content::WebContentsObserver::Observe(contents);
  LogHistogramValue(signin_metrics::HISTOGRAM_SHOWN);
  UMA_HISTOGRAM_BOOLEAN("Signin.UseDeprecatedGaiaSigninEndpoint",
                        is_constrained == "1");
}

void InlineLoginHandlerImpl::CompleteLogin(const base::ListValue* args) {
  content::WebContents* contents = web_ui()->GetWebContents();
  const GURL& current_url = contents->GetURL();

  const base::DictionaryValue* dict = NULL;
  args->GetDictionary(0, &dict);

  bool skip_for_now = false;
  dict->GetBoolean("skipForNow", &skip_for_now);
  if (skip_for_now) {
    signin::SetUserSkippedPromo(Profile::FromWebUI(web_ui()));
    SyncStarterCallback(OneClickSigninSyncStarter::SYNC_SETUP_FAILURE);
    return;
  }

  // This value exists only for webview sign in.
  bool trusted = false;
  if (dict->GetBoolean("trusted", &trusted))
    confirm_untrusted_signin_ = !trusted;

  base::string16 email_string16;
  dict->GetString("email", &email_string16);
  DCHECK(!email_string16.empty());
  std::string email(base::UTF16ToASCII(email_string16));

  base::string16 password_string16;
  dict->GetString("password", &password_string16);
  std::string password(base::UTF16ToASCII(password_string16));

  base::string16 gaia_id_string16;
  dict->GetString("gaiaId", &gaia_id_string16);
  DCHECK(!gaia_id_string16.empty());
  std::string gaia_id = base::UTF16ToASCII(gaia_id_string16);

  std::string is_constrained;
  net::GetValueForKeyInQuery(current_url, "constrained", &is_constrained);
  const bool is_password_separated_signin_flow = is_constrained == "1";

  base::string16 session_index_string16;
  dict->GetString("sessionIndex", &session_index_string16);
  std::string session_index = base::UTF16ToASCII(session_index_string16);
  DCHECK(is_password_separated_signin_flow || !session_index.empty());

  base::string16 auth_code_string16;
  dict->GetString("authCode", &auth_code_string16);
  std::string auth_code = base::UTF16ToASCII(auth_code_string16);
  DCHECK(!is_password_separated_signin_flow || !auth_code.empty());

  bool choose_what_to_sync = false;
  dict->GetBoolean("chooseWhatToSync", &choose_what_to_sync);

  content::StoragePartition* partition =
      content::BrowserContext::GetStoragePartitionForSite(
          contents->GetBrowserContext(), signin::GetSigninPartitionURL());

  // If this was called from the user manager to reauthenticate the profile,
  // the current profile is the system profile.  In this case, use the email to
  // find the right profile to reauthenticate.  Otherwise the profile can be
  // taken from web_ui().
  Profile* profile = Profile::FromWebUI(web_ui());
  if (IsSystemProfile(profile)) {
    ProfileManager* manager = g_browser_process->profile_manager();
    base::FilePath path = profiles::GetPathOfProfileWithEmail(manager, email);
    if (path.empty()) {
      path = UserManager::GetSigninProfilePath();
    }
    if (!path.empty()) {
      signin_metrics::Reason reason =
          signin::GetSigninReasonForPromoURL(current_url);
      // If we are only reauthenticating a profile in the user manager (and not
      // unlocking it), load the profile and finish the login.
      if (reason == signin_metrics::Reason::REASON_REAUTHENTICATION) {
        FinishCompleteLoginParams params(
            this, partition, current_url, base::FilePath(),
            confirm_untrusted_signin_, email, gaia_id, password, session_index,
            auth_code, choose_what_to_sync, false);
        ProfileManager::CreateCallback callback =
            base::Bind(&InlineLoginHandlerImpl::FinishCompleteLogin, params);
        profiles::LoadProfileAsync(path, callback);
      } else {
        // Otherwise, switch to the profile and finish the login. Pass the
        // profile path so it can be marked as unlocked. Don't pass a handler
        // pointer since it will be destroyed before the callback runs.
        bool is_force_signin_enabled = signin_util::IsForceSigninEnabled();
        InlineLoginHandlerImpl* handler = nullptr;
        if (is_force_signin_enabled)
          handler = this;
        FinishCompleteLoginParams params(
            handler, partition, current_url, path, confirm_untrusted_signin_,
            email, gaia_id, password, session_index, auth_code,
            choose_what_to_sync, is_force_signin_enabled);
        ProfileManager::CreateCallback callback =
            base::Bind(&InlineLoginHandlerImpl::FinishCompleteLogin, params);
        if (is_force_signin_enabled) {
          // Browser window will be opened after ClientOAuthSuccess.
          profiles::LoadProfileAsync(path, callback);
        } else {
          profiles::SwitchToProfile(path, true, callback,
                                    ProfileMetrics::SWITCH_PROFILE_UNLOCK);
        }
      }
    }
  } else {
    FinishCompleteLogin(
        FinishCompleteLoginParams(this, partition, current_url,
                                  base::FilePath(), confirm_untrusted_signin_,
                                  email, gaia_id, password, session_index,
                                  auth_code, choose_what_to_sync, false),
        profile, Profile::CREATE_STATUS_CREATED);
  }
}

InlineLoginHandlerImpl::FinishCompleteLoginParams::FinishCompleteLoginParams(
    InlineLoginHandlerImpl* handler,
    content::StoragePartition* partition,
    const GURL& url,
    const base::FilePath& profile_path,
    bool confirm_untrusted_signin,
    const std::string& email,
    const std::string& gaia_id,
    const std::string& password,
    const std::string& session_index,
    const std::string& auth_code,
    bool choose_what_to_sync,
    bool is_force_sign_in_with_usermanager)
    : handler(handler),
      partition(partition),
      url(url),
      profile_path(profile_path),
      confirm_untrusted_signin(confirm_untrusted_signin),
      email(email),
      gaia_id(gaia_id),
      password(password),
      session_index(session_index),
      auth_code(auth_code),
      choose_what_to_sync(choose_what_to_sync),
      is_force_sign_in_with_usermanager(is_force_sign_in_with_usermanager) {}

InlineLoginHandlerImpl::FinishCompleteLoginParams::FinishCompleteLoginParams(
    const FinishCompleteLoginParams& other) = default;

InlineLoginHandlerImpl::
    FinishCompleteLoginParams::~FinishCompleteLoginParams() {}

// static
void InlineLoginHandlerImpl::FinishCompleteLogin(
    const FinishCompleteLoginParams& params,
    Profile* profile,
    Profile::CreateStatus status) {
  // When doing a SAML sign in, this email check may result in a false
  // positive.  This happens when the user types one email address in the
  // gaia sign in page, but signs in to a different account in the SAML sign in
  // page.
  std::string default_email;
  std::string validate_email;
  if (net::GetValueForKeyInQuery(params.url, "email", &default_email) &&
      net::GetValueForKeyInQuery(params.url, "validateEmail",
                                 &validate_email) &&
      validate_email == "1" && !default_email.empty()) {
    if (!gaia::AreEmailsSame(params.email, default_email)) {
      if (params.handler) {
        params.handler->HandleLoginError(
            l10n_util::GetStringFUTF8(IDS_SYNC_WRONG_EMAIL,
                                      base::UTF8ToUTF16(default_email)),
            base::UTF8ToUTF16(params.email));
      }
      return;
    }
  }

  signin_metrics::AccessPoint access_point =
      signin::GetAccessPointForPromoURL(params.url);
  signin_metrics::Reason reason =
      signin::GetSigninReasonForPromoURL(params.url);
  LogHistogramValue(signin_metrics::HISTOGRAM_ACCEPTED);
  bool switch_to_advanced =
      params.choose_what_to_sync &&
      (access_point != signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS);
  LogHistogramValue(
      switch_to_advanced ? signin_metrics::HISTOGRAM_WITH_ADVANCED :
                           signin_metrics::HISTOGRAM_WITH_DEFAULTS);

  CanOfferSigninType can_offer_for = CAN_OFFER_SIGNIN_FOR_ALL_ACCOUNTS;
  switch (reason) {
    case signin_metrics::Reason::REASON_ADD_SECONDARY_ACCOUNT:
      can_offer_for = CAN_OFFER_SIGNIN_FOR_SECONDARY_ACCOUNT;
      break;
    case signin_metrics::Reason::REASON_REAUTHENTICATION:
    case signin_metrics::Reason::REASON_UNLOCK: {
      std::string primary_username =
          SigninManagerFactory::GetForProfile(profile)
              ->GetAuthenticatedAccountInfo()
              .email;
      if (!gaia::AreEmailsSame(default_email, primary_username))
        can_offer_for = CAN_OFFER_SIGNIN_FOR_SECONDARY_ACCOUNT;
      break;
    }
    default:
      // No need to change |can_offer_for|.
      break;
  }

  std::string error_msg;
  bool can_offer = CanOfferSignin(profile, can_offer_for, params.gaia_id,
                                  params.email, &error_msg);
  if (!can_offer) {
    if (params.handler) {
      params.handler->HandleLoginError(error_msg,
                                       base::UTF8ToUTF16(params.email));
    }
    return;
  }

  AboutSigninInternals* about_signin_internals =
      AboutSigninInternalsFactory::GetForProfile(profile);
  about_signin_internals->OnAuthenticationResultReceived("Successful");

  SigninClient* signin_client =
      ChromeSigninClientFactory::GetForProfile(profile);
  std::string signin_scoped_device_id =
      signin_client->GetSigninScopedDeviceId();
  base::WeakPtr<InlineLoginHandlerImpl> handler_weak_ptr;
  if (params.handler)
    handler_weak_ptr = params.handler->GetWeakPtr();

  // InlineSigninHelper will delete itself.
  new InlineSigninHelper(
      handler_weak_ptr,
      params.partition->GetURLLoaderFactoryForBrowserProcess(), profile, status,
      params.url, params.email, params.gaia_id, params.password,
      params.session_index, params.auth_code, signin_scoped_device_id,
      params.choose_what_to_sync, params.confirm_untrusted_signin,
      params.is_force_sign_in_with_usermanager);

  // If opened from user manager to unlock a profile, make sure the user manager
  // is closed and that the profile is marked as unlocked.
  if (!params.is_force_sign_in_with_usermanager) {
    UnlockProfileAndHideLoginUI(params.profile_path, params.handler);
  }
}

void InlineLoginHandlerImpl::HandleLoginError(const std::string& error_msg,
                                              const base::string16& email) {
  SyncStarterCallback(OneClickSigninSyncStarter::SYNC_SETUP_FAILURE);
  Browser* browser = GetDesktopBrowser();
  Profile* profile = Profile::FromWebUI(web_ui());

  if (IsSystemProfile(profile))
    profile = g_browser_process->profile_manager()->GetProfileByPath(
        UserManager::GetSigninProfilePath());
  CloseModalSigninIfNeeded(this);
  if (!error_msg.empty()) {
    LoginUIServiceFactory::GetForProfile(profile)->DisplayLoginResult(
        browser, base::UTF8ToUTF16(error_msg), email);
  }
}

Browser* InlineLoginHandlerImpl::GetDesktopBrowser() {
  Browser* browser = chrome::FindBrowserWithWebContents(
      web_ui()->GetWebContents());
  if (!browser)
    browser = chrome::FindLastActiveWithProfile(Profile::FromWebUI(web_ui()));
  return browser;
}

void InlineLoginHandlerImpl::SyncStarterCallback(
    OneClickSigninSyncStarter::SyncSetupResult result) {
  content::WebContents* contents = web_ui()->GetWebContents();

  if (contents->GetController().GetPendingEntry()) {
    // Do nothing if a navigation is pending, since this call can be triggered
    // from DidStartLoading. This avoids deleting the pending entry while we are
    // still navigating to it. See crbug/346632.
    return;
  }

  const GURL& current_url = contents->GetLastCommittedURL();
  signin_metrics::AccessPoint access_point =
      signin::GetAccessPointForPromoURL(current_url);
  bool auto_close = signin::IsAutoCloseEnabledInURL(current_url);

  if (result == OneClickSigninSyncStarter::SYNC_SETUP_FAILURE) {
    RedirectToNtpOrAppsPage(contents, access_point);
  } else if (auto_close) {
    bool show_account_management = ShouldShowAccountManagement(
        current_url,
        AccountConsistencyModeManager::IsMirrorEnabledForProfile(
            Profile::FromBrowserContext(contents->GetBrowserContext())));
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::BindOnce(&InlineLoginHandlerImpl::CloseTab,
                       weak_factory_.GetWeakPtr(), show_account_management));
  } else {
    RedirectToNtpOrAppsPageIfNecessary(contents, access_point);
  }
}

void InlineLoginHandlerImpl::CloseTab(bool show_account_management) {
  content::WebContents* tab = web_ui()->GetWebContents();
  Browser* browser = chrome::FindBrowserWithWebContents(tab);
  if (browser) {
    TabStripModel* tab_strip_model = browser->tab_strip_model();
    if (tab_strip_model) {
      int index = tab_strip_model->GetIndexOfWebContents(tab);
      if (index != TabStripModel::kNoTab) {
        tab_strip_model->ExecuteContextMenuCommand(
            index, TabStripModel::CommandCloseTab);
      }
    }

    if (show_account_management) {
      browser->window()->ShowAvatarBubbleFromAvatarButton(
          BrowserWindow::AVATAR_BUBBLE_MODE_ACCOUNT_MANAGEMENT,
          signin::ManageAccountsParams(),
          signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN,
          false);
    }
  }
}
