Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(336)

Side by Side Diff: chrome/browser/chromeos/login/oauth2_login_verifier.cc

Issue 11649055: OAuth2 sign-in flow for ChromeOS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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.
4
5 #include "chrome/browser/chromeos/login/oauth2_login_verifier.h"
6
7 #include <vector>
8
9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
11 #include "base/stringprintf.h"
12 #include "base/time.h"
13 #include "chrome/browser/chromeos/cros/cros_library.h"
14 #include "chrome/browser/chromeos/cros/network_library.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "google_apis/gaia/gaia_constants.h"
17 #include "google_apis/gaia/gaia_urls.h"
18
19 using content::BrowserThread;
20
21 namespace {
22
23 // OAuth token request max retry count.
24 const int kMaxRequestAttemptCount = 5;
25 // OAuth token request retry delay in milliseconds.
26 const int kRequestRestartDelay = 3000;
27
28 } // namespace
29
30 namespace chromeos {
31
32 OAuth2LoginVerifier::OAuth2LoginVerifier(
33 OAuth2LoginVerifier::Delegate* delegate,
34 net::URLRequestContextGetter* system_request_context,
35 net::URLRequestContextGetter* user_request_context)
36 : delegate_(delegate),
37 ALLOW_THIS_IN_INITIALIZER_LIST(token_fetcher_(
38 this, system_request_context)),
39 ALLOW_THIS_IN_INITIALIZER_LIST(gaia_fetcher_(
40 this, std::string(GaiaConstants::kChromeOSSource),
41 user_request_context)),
42 retry_count_(0) {
43 DCHECK(delegate);
44 }
45
46 OAuth2LoginVerifier::~OAuth2LoginVerifier() {
47 }
48
49 void OAuth2LoginVerifier::VerifyRefreshToken(const std::string& refresh_token) {
50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51 if (CrosLibrary::Get()->libcros_loaded()) {
52 // Delay the verification if the network is not connected or on a captive
53 // portal.
54 const Network* network =
55 CrosLibrary::Get()->GetNetworkLibrary()->active_network();
56 if (!network || !network->connected() || network->restricted_pool()) {
57 // If network is offline, defer the token fetching until online.
58 VLOG(1) << "Network is offline. Deferring OAuth2 access token fetch.";
59 BrowserThread::PostDelayedTask(
60 BrowserThread::UI, FROM_HERE,
61 base::Bind(&OAuth2LoginVerifier::VerifyRefreshToken,
62 AsWeakPtr(),
63 refresh_token),
64 base::TimeDelta::FromMilliseconds(kRequestRestartDelay));
65 return;
66 }
67 }
68
69 access_token_.clear();
70 refresh_token_ = refresh_token;
71 std::vector<std::string> scopes;
72 scopes.push_back(GaiaUrls::GetInstance()->oauth1_login_scope());
73 token_fetcher_.Start(GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
74 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
75 refresh_token,
76 scopes);
77 }
78
79 void OAuth2LoginVerifier::OnGetTokenSuccess(
80 const std::string& access_token, const base::Time& expiration_time) {
81 VLOG(1) << "Got OAuth2 access token!";
82 retry_count_ = 0;
83 access_token_ = access_token;
84 StartOAuthLogin();
85 }
86
87 void OAuth2LoginVerifier::StartOAuthLogin() {
88 gaia_fetcher_.StartOAuthLogin(access_token_,
89 GaiaConstants::kSyncService);
90 }
91
92 void OAuth2LoginVerifier::OnGetTokenFailure(
93 const GoogleServiceAuthError& error) {
94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
95 LOG(WARNING) << "Failed to get OAuth2 access token, "
96 << " error: " << error.state();
97 RetryOnError("GetToken", error,
98 base::Bind(&OAuth2LoginVerifier::VerifyRefreshToken,
99 AsWeakPtr(),
100 refresh_token_));
101 }
102
103 void OAuth2LoginVerifier::OnClientLoginSuccess(
104 const ClientLoginResult& result) {
105 LOG(WARNING) << "OAuthLogin successful!";
Nikita (slow) 2013/01/11 22:57:39 VLOG(1). You could temporarily change log level fo
zel 2013/01/12 02:07:37 Nope. I really want this in user feedback logs.
106 sid_ = result.sid;
107 lsid_ = result.lsid;
108 token_ = result.token;
109 retry_count_ = 0;
110 StartCookiesRetrieval();
111 }
112
113 void OAuth2LoginVerifier::OnClientLoginFailure(
114 const GoogleServiceAuthError& error) {
115 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
116 LOG(WARNING) << "Failed to log in with OAuth2 access tokens,"
117 << " error: " << error.state();
118 RetryOnError("OAuthLogin", error,
119 base::Bind(&OAuth2LoginVerifier::StartOAuthLogin,
120 AsWeakPtr()));
121 }
122
123 void OAuth2LoginVerifier::StartCookiesRetrieval() {
124 DCHECK(!sid_.empty());
125 DCHECK(!lsid_.empty());
126 gaia_fetcher_.StartIssueAuthToken(sid_, lsid_, GaiaConstants::kGaiaService);
127 }
128
129 void OAuth2LoginVerifier::OnIssueAuthTokenSuccess(
130 const std::string& service,
131 const std::string& token_token) {
132 LOG(WARNING) << "Got auth token!";
Nikita (slow) 2013/01/11 22:57:39 VLOG(1)
zel 2013/01/12 02:07:37 same
133 retry_count_ = 0;
134 gaia_fetcher_.StartMergeSession(token_token);
135 }
136
137 void OAuth2LoginVerifier::OnIssueAuthTokenFailure(
138 const std::string& service,
139 const GoogleServiceAuthError& error) {
140 LOG(WARNING) << "Failed IssueAuthToken request,"
141 << " error:" << error.state();
142 RetryOnError("IssueAuthToken", error,
143 base::Bind(&OAuth2LoginVerifier::StartCookiesRetrieval,
144 AsWeakPtr()));
145 }
146
147 void OAuth2LoginVerifier::OnMergeSessionSuccess(const std::string& data) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
149 LOG(WARNING) << "MergeSession successful.";
Nikita (slow) 2013/01/11 22:57:39 LOG(INFO)?
zel 2013/01/12 02:07:37 same
150 delegate_->OnOAuth2LoginVerifierSuccess(sid_, lsid_, token_);
151 }
152
153 void OAuth2LoginVerifier::OnMergeSessionFailure(
154 const GoogleServiceAuthError& error) {
155 LOG(WARNING) << "Failed MergeSession request,"
156 << " error: " << error.state();
157 RetryOnError("MergeSession", error,
158 base::Bind(&OAuth2LoginVerifier::StartCookiesRetrieval,
159 AsWeakPtr()));
160 }
161
162 void OAuth2LoginVerifier::RetryOnError(const char* operation_id,
163 const GoogleServiceAuthError& error,
164 const base::Closure& task) {
165 if ((error.state() == GoogleServiceAuthError::CONNECTION_FAILED ||
166 error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE ||
167 error.state() == GoogleServiceAuthError::REQUEST_CANCELED) &&
168 retry_count_ < kMaxRequestAttemptCount) {
169 retry_count_++;
170 UMA_HISTOGRAM_ENUMERATION(
171 base::StringPrintf("OAuth2LoginVerifier.%sWithRetry", operation_id),
172 error.state(),
173 GoogleServiceAuthError::NUM_STATES);
174 BrowserThread::PostDelayedTask(
175 BrowserThread::UI, FROM_HERE, task,
176 base::TimeDelta::FromMilliseconds(kRequestRestartDelay));
177 } else {
178 LOG(WARNING) << "Unrecoverable error or retry count max reached for "
179 << operation_id;
180 UMA_HISTOGRAM_ENUMERATION(
181 base::StringPrintf("OAuth2LoginVerifier.%sWithNoRetry", operation_id),
182 error.state(),
183 GoogleServiceAuthError::NUM_STATES);
184 delegate_->OnOAuth2LoginVerifierFailure();
185 }
186 }
187
188 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698