Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chromeos / login / auth / online_attempt.cc
blobbb9550426ed51cca15cf6629a568107914fa2b7d
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/login/auth/online_attempt.h"
8 #include "base/bind.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "chromeos/login/auth/auth_attempt_state.h"
13 #include "chromeos/login/auth/auth_attempt_state_resolver.h"
14 #include "chromeos/login/auth/key.h"
15 #include "chromeos/login/auth/user_context.h"
16 #include "components/user_manager/user_type.h"
17 #include "google_apis/gaia/gaia_auth_fetcher.h"
18 #include "google_apis/gaia/gaia_constants.h"
19 #include "net/base/load_flags.h"
20 #include "net/base/net_errors.h"
21 #include "net/url_request/url_request_status.h"
23 namespace chromeos {
25 // static
26 const int OnlineAttempt::kClientLoginTimeoutMs = 10000;
28 OnlineAttempt::OnlineAttempt(AuthAttemptState* current_attempt,
29 AuthAttemptStateResolver* callback)
30 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
31 attempt_(current_attempt),
32 resolver_(callback),
33 try_again_(true),
34 weak_factory_(this) {
35 DCHECK_EQ(user_manager::USER_TYPE_REGULAR,
36 attempt_->user_context.GetUserType());
39 OnlineAttempt::~OnlineAttempt() {
40 // Just to be sure.
41 if (client_fetcher_.get())
42 client_fetcher_->CancelRequest();
45 void OnlineAttempt::Initiate(net::URLRequestContextGetter* request_context) {
46 client_fetcher_.reset(new GaiaAuthFetcher(
47 this, GaiaConstants::kChromeOSSource, request_context));
48 task_runner_->PostTask(FROM_HERE, base::Bind(&OnlineAttempt::TryClientLogin,
49 weak_factory_.GetWeakPtr()));
52 void OnlineAttempt::OnClientLoginSuccess(
53 const GaiaAuthConsumer::ClientLoginResult& unused) {
54 VLOG(1) << "Online login successful!";
56 weak_factory_.InvalidateWeakPtrs();
58 if (attempt_->hosted_policy() == GaiaAuthFetcher::HostedAccountsAllowed &&
59 attempt_->is_first_time_user()) {
60 // First time user, and we don't know if the account is HOSTED or not.
61 // Since we don't allow HOSTED accounts to log in, we need to try
62 // again, without allowing HOSTED accounts.
64 // NOTE: we used to do this in the opposite order, so that we'd only
65 // try the HOSTED pathway if GOOGLE-only failed. This breaks CAPTCHA
66 // handling, though.
67 attempt_->DisableHosted();
68 TryClientLogin();
69 return;
71 TriggerResolve(AuthFailure::AuthFailureNone());
74 void OnlineAttempt::OnClientLoginFailure(const GoogleServiceAuthError& error) {
75 weak_factory_.InvalidateWeakPtrs();
77 if (error.state() == GoogleServiceAuthError::REQUEST_CANCELED) {
78 if (try_again_) {
79 try_again_ = false;
80 // TODO(cmasone): add UMA tracking for this to see if we can remove it.
81 LOG(ERROR) << "Login attempt canceled!?!? Trying again.";
82 TryClientLogin();
83 return;
85 LOG(ERROR) << "Login attempt canceled again? Already retried...";
88 if (error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS &&
89 attempt_->is_first_time_user() &&
90 attempt_->hosted_policy() != GaiaAuthFetcher::HostedAccountsAllowed) {
91 // This was a first-time login, we already tried allowing HOSTED accounts
92 // and succeeded. That we've failed with INVALID_GAIA_CREDENTIALS now
93 // indicates that the account is HOSTED.
94 LOG(WARNING) << "Rejecting valid HOSTED account.";
95 TriggerResolve(AuthFailure::FromNetworkAuthFailure(
96 GoogleServiceAuthError(GoogleServiceAuthError::HOSTED_NOT_ALLOWED)));
97 return;
100 if (error.state() == GoogleServiceAuthError::TWO_FACTOR) {
101 LOG(WARNING) << "Two factor authenticated. Sync will not work.";
102 TriggerResolve(AuthFailure::AuthFailureNone());
104 return;
106 VLOG(2) << "ClientLogin attempt failed with " << error.state();
107 TriggerResolve(AuthFailure::FromNetworkAuthFailure(error));
110 void OnlineAttempt::TryClientLogin() {
111 task_runner_->PostDelayedTask(
112 FROM_HERE,
113 base::Bind(&OnlineAttempt::CancelClientLogin, weak_factory_.GetWeakPtr()),
114 base::TimeDelta::FromMilliseconds(kClientLoginTimeoutMs));
116 client_fetcher_->StartClientLogin(
117 attempt_->user_context.GetUserID(),
118 attempt_->user_context.GetKey()->GetSecret(),
119 GaiaConstants::kSyncService,
120 attempt_->login_token,
121 attempt_->login_captcha,
122 attempt_->hosted_policy());
125 bool OnlineAttempt::HasPendingFetch() {
126 return client_fetcher_->HasPendingFetch();
129 void OnlineAttempt::CancelRequest() {
130 weak_factory_.InvalidateWeakPtrs();
133 void OnlineAttempt::CancelClientLogin() {
134 if (HasPendingFetch()) {
135 LOG(WARNING) << "Canceling ClientLogin attempt.";
136 CancelRequest();
138 TriggerResolve(AuthFailure(AuthFailure::LOGIN_TIMED_OUT));
142 void OnlineAttempt::TriggerResolve(const AuthFailure& outcome) {
143 attempt_->RecordOnlineLoginStatus(outcome);
144 client_fetcher_.reset(NULL);
145 resolver_->Resolve();
148 } // namespace chromeos