| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/net/gaia/gaia_auth_fetcher.h" | 5 #include "chrome/common/net/gaia/gaia_auth_fetcher.h" |
| 6 | 6 |
| 7 #include <algorithm> |
| 7 #include <string> | 8 #include <string> |
| 8 #include <utility> | 9 #include <utility> |
| 9 #include <vector> | 10 #include <vector> |
| 10 | 11 |
| 12 #include "base/json/json_reader.h" |
| 11 #include "base/string_split.h" | 13 #include "base/string_split.h" |
| 12 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 13 #include "base/stringprintf.h" | 15 #include "base/stringprintf.h" |
| 16 #include "base/values.h" |
| 14 #include "chrome/common/net/gaia/gaia_auth_consumer.h" | 17 #include "chrome/common/net/gaia/gaia_auth_consumer.h" |
| 15 #include "chrome/common/net/gaia/gaia_constants.h" | 18 #include "chrome/common/net/gaia/gaia_constants.h" |
| 16 #include "chrome/common/net/gaia/gaia_urls.h" | 19 #include "chrome/common/net/gaia/gaia_urls.h" |
| 17 #include "chrome/common/net/gaia/google_service_auth_error.h" | 20 #include "chrome/common/net/gaia/google_service_auth_error.h" |
| 18 #include "chrome/common/net/http_return.h" | 21 #include "chrome/common/net/http_return.h" |
| 19 #include "content/public/common/url_fetcher.h" | 22 #include "content/public/common/url_fetcher.h" |
| 20 #include "net/base/escape.h" | 23 #include "net/base/escape.h" |
| 21 #include "net/base/load_flags.h" | 24 #include "net/base/load_flags.h" |
| 22 #include "net/url_request/url_request_context_getter.h" | 25 #include "net/url_request/url_request_context_getter.h" |
| 23 #include "net/url_request/url_request_status.h" | 26 #include "net/url_request/url_request_status.h" |
| 24 | 27 |
| 28 namespace { |
| 29 static bool CookiePartsContains(const std::vector<std::string>& parts, |
| 30 const char* part) { |
| 31 return std::find(parts.begin(), parts.end(), part) != parts.end(); |
| 32 } |
| 33 } // namespace |
| 34 |
| 25 // TODO(chron): Add sourceless version of this formatter. | 35 // TODO(chron): Add sourceless version of this formatter. |
| 26 // static | 36 // static |
| 27 const char GaiaAuthFetcher::kClientLoginFormat[] = | 37 const char GaiaAuthFetcher::kClientLoginFormat[] = |
| 28 "Email=%s&" | 38 "Email=%s&" |
| 29 "Passwd=%s&" | 39 "Passwd=%s&" |
| 30 "PersistentCookie=%s&" | 40 "PersistentCookie=%s&" |
| 31 "accountType=%s&" | 41 "accountType=%s&" |
| 32 "source=%s&" | 42 "source=%s&" |
| 33 "service=%s"; | 43 "service=%s"; |
| 34 // static | 44 // static |
| 35 const char GaiaAuthFetcher::kClientLoginCaptchaFormat[] = | 45 const char GaiaAuthFetcher::kClientLoginCaptchaFormat[] = |
| 36 "Email=%s&" | 46 "Email=%s&" |
| 37 "Passwd=%s&" | 47 "Passwd=%s&" |
| 38 "PersistentCookie=%s&" | 48 "PersistentCookie=%s&" |
| 39 "accountType=%s&" | 49 "accountType=%s&" |
| 40 "source=%s&" | 50 "source=%s&" |
| 41 "service=%s&" | 51 "service=%s&" |
| 42 "logintoken=%s&" | 52 "logintoken=%s&" |
| 43 "logincaptcha=%s"; | 53 "logincaptcha=%s"; |
| 44 // static | 54 // static |
| 45 const char GaiaAuthFetcher::kIssueAuthTokenFormat[] = | 55 const char GaiaAuthFetcher::kIssueAuthTokenFormat[] = |
| 46 "SID=%s&" | 56 "SID=%s&" |
| 47 "LSID=%s&" | 57 "LSID=%s&" |
| 48 "service=%s&" | 58 "service=%s&" |
| 49 "Session=%s"; | 59 "Session=%s"; |
| 50 // static | 60 // static |
| 61 const char GaiaAuthFetcher::kGetAuthCodeBodyFormat[] = |
| 62 "scope=%s&client_id=%s"; |
| 63 // static |
| 64 const char GaiaAuthFetcher::kGetTokenPairBodyFormat[] = |
| 65 "scope=%s&" |
| 66 "grant_type=authorization_code&" |
| 67 "client_id=%s&" |
| 68 "client_secret=%s&" |
| 69 "code=%s"; |
| 70 // static |
| 51 const char GaiaAuthFetcher::kGetUserInfoFormat[] = | 71 const char GaiaAuthFetcher::kGetUserInfoFormat[] = |
| 52 "LSID=%s"; | 72 "LSID=%s"; |
| 53 // static | 73 // static |
| 54 const char GaiaAuthFetcher::kTokenAuthFormat[] = | 74 const char GaiaAuthFetcher::kTokenAuthFormat[] = |
| 55 "auth=%s&" | 75 "auth=%s&" |
| 56 "continue=%s&" | 76 "continue=%s&" |
| 57 "source=%s"; | 77 "source=%s"; |
| 58 // static | 78 // static |
| 59 const char GaiaAuthFetcher::kMergeSessionFormat[] = | 79 const char GaiaAuthFetcher::kMergeSessionFormat[] = |
| 60 "uberauth=%s&" | 80 "uberauth=%s&" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 // TODO(johnnyg): When hosted accounts are supported by sync, | 113 // TODO(johnnyg): When hosted accounts are supported by sync, |
| 94 // we can always use "HOSTED_OR_GOOGLE" | 114 // we can always use "HOSTED_OR_GOOGLE" |
| 95 const char GaiaAuthFetcher::kAccountTypeHostedOrGoogle[] = | 115 const char GaiaAuthFetcher::kAccountTypeHostedOrGoogle[] = |
| 96 "HOSTED_OR_GOOGLE"; | 116 "HOSTED_OR_GOOGLE"; |
| 97 const char GaiaAuthFetcher::kAccountTypeGoogle[] = | 117 const char GaiaAuthFetcher::kAccountTypeGoogle[] = |
| 98 "GOOGLE"; | 118 "GOOGLE"; |
| 99 | 119 |
| 100 // static | 120 // static |
| 101 const char GaiaAuthFetcher::kSecondFactor[] = "Info=InvalidSecondFactor"; | 121 const char GaiaAuthFetcher::kSecondFactor[] = "Info=InvalidSecondFactor"; |
| 102 | 122 |
| 123 // static |
| 124 const char GaiaAuthFetcher::kAuthHeaderFormat[] = |
| 125 "Authorization: GoogleLogin auth=%s"; |
| 126 // static |
| 127 const char GaiaAuthFetcher::kAuthCodeCookiePartSecure[] = "Secure"; |
| 128 // static |
| 129 const char GaiaAuthFetcher::kAuthCodeCookiePartHttpOnly[] = "HttpOnly"; |
| 130 // static |
| 131 const char GaiaAuthFetcher::kAuthCodeCookiePartCodePrefix[] = "oauth_code="; |
| 132 // static |
| 133 const int GaiaAuthFetcher::kAuthCodeCookiePartCodePrefixLength = |
| 134 arraysize(GaiaAuthFetcher::kAuthCodeCookiePartCodePrefix) - 1; |
| 135 // static |
| 136 const char GaiaAuthFetcher::kRefreshTokenKey[] = "refresh_token"; |
| 137 // static |
| 138 const char GaiaAuthFetcher::kAccessTokenKey[] = "access_token"; |
| 139 // static |
| 140 const char GaiaAuthFetcher::kExpiresInKey[] = "expires_in"; |
| 141 |
| 103 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, | 142 GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, |
| 104 const std::string& source, | 143 const std::string& source, |
| 105 net::URLRequestContextGetter* getter) | 144 net::URLRequestContextGetter* getter) |
| 106 : consumer_(consumer), | 145 : consumer_(consumer), |
| 107 getter_(getter), | 146 getter_(getter), |
| 108 source_(source), | 147 source_(source), |
| 109 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), | 148 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), |
| 110 issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), | 149 issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), |
| 150 get_auth_code_gurl_( |
| 151 GaiaUrls::GetInstance()->client_login_to_oauth2_url()), |
| 152 get_token_pair_gurl_(GaiaUrls::GetInstance()->oauth2_token_url()), |
| 111 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), | 153 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), |
| 112 token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), | 154 token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), |
| 113 merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), | 155 merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), |
| 114 fetch_pending_(false) {} | 156 fetch_pending_(false) {} |
| 115 | 157 |
| 116 GaiaAuthFetcher::~GaiaAuthFetcher() {} | 158 GaiaAuthFetcher::~GaiaAuthFetcher() {} |
| 117 | 159 |
| 118 bool GaiaAuthFetcher::HasPendingFetch() { | 160 bool GaiaAuthFetcher::HasPendingFetch() { |
| 119 return fetch_pending_; | 161 return fetch_pending_; |
| 120 } | 162 } |
| 121 | 163 |
| 122 void GaiaAuthFetcher::CancelRequest() { | 164 void GaiaAuthFetcher::CancelRequest() { |
| 123 fetcher_.reset(); | 165 fetcher_.reset(); |
| 124 fetch_pending_ = false; | 166 fetch_pending_ = false; |
| 125 } | 167 } |
| 126 | 168 |
| 127 // static | 169 // static |
| 128 content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( | 170 content::URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( |
| 129 net::URLRequestContextGetter* getter, | 171 net::URLRequestContextGetter* getter, |
| 130 const std::string& body, | 172 const std::string& body, |
| 173 const std::string& headers, |
| 131 const GURL& gaia_gurl, | 174 const GURL& gaia_gurl, |
| 132 bool send_cookies, | 175 bool send_cookies, |
| 133 content::URLFetcherDelegate* delegate) { | 176 content::URLFetcherDelegate* delegate) { |
| 134 content::URLFetcher* to_return = content::URLFetcher::Create( | 177 content::URLFetcher* to_return = content::URLFetcher::Create( |
| 135 0, gaia_gurl, content::URLFetcher::POST, delegate); | 178 0, gaia_gurl, content::URLFetcher::POST, delegate); |
| 136 to_return->SetRequestContext(getter); | 179 to_return->SetRequestContext(getter); |
| 137 to_return->SetUploadData("application/x-www-form-urlencoded", body); | 180 to_return->SetUploadData("application/x-www-form-urlencoded", body); |
| 138 | 181 |
| 139 // The Gaia token exchange requests do not require any cookie-based | 182 // The Gaia token exchange requests do not require any cookie-based |
| 140 // identification as part of requests. We suppress sending any cookies to | 183 // identification as part of requests. We suppress sending any cookies to |
| 141 // maintain a separation between the user's browsing and Chrome's internal | 184 // maintain a separation between the user's browsing and Chrome's internal |
| 142 // services. Where such mixing is desired (MergeSession), it will be done | 185 // services. Where such mixing is desired (MergeSession), it will be done |
| 143 // explicitly. | 186 // explicitly. |
| 144 if (!send_cookies) | 187 if (!send_cookies) { |
| 145 to_return->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES); | 188 to_return->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
| 189 net::LOAD_DO_NOT_SAVE_COOKIES); |
| 190 } |
| 191 if (!headers.empty()) |
| 192 to_return->SetExtraRequestHeaders(headers); |
| 146 | 193 |
| 147 return to_return; | 194 return to_return; |
| 148 } | 195 } |
| 149 | 196 |
| 150 // static | 197 // static |
| 151 std::string GaiaAuthFetcher::MakeClientLoginBody( | 198 std::string GaiaAuthFetcher::MakeClientLoginBody( |
| 152 const std::string& username, | 199 const std::string& username, |
| 153 const std::string& password, | 200 const std::string& password, |
| 154 const std::string& source, | 201 const std::string& source, |
| 155 const char* service, | 202 const char* service, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 session = false; | 249 session = false; |
| 203 | 250 |
| 204 return base::StringPrintf(kIssueAuthTokenFormat, | 251 return base::StringPrintf(kIssueAuthTokenFormat, |
| 205 encoded_sid.c_str(), | 252 encoded_sid.c_str(), |
| 206 encoded_lsid.c_str(), | 253 encoded_lsid.c_str(), |
| 207 service, | 254 service, |
| 208 session ? "true" : "false"); | 255 session ? "true" : "false"); |
| 209 } | 256 } |
| 210 | 257 |
| 211 // static | 258 // static |
| 259 std::string GaiaAuthFetcher::MakeGetAuthCodeBody() { |
| 260 std::string encoded_scope = net::EscapeUrlEncodedData( |
| 261 GaiaUrls::GetInstance()->oauth1_login_scope(), true); |
| 262 std::string encoded_client_id = net::EscapeUrlEncodedData( |
| 263 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), true); |
| 264 return StringPrintf(kGetAuthCodeBodyFormat, |
| 265 encoded_scope.c_str(), |
| 266 encoded_client_id.c_str()); |
| 267 } |
| 268 |
| 269 // static |
| 270 std::string GaiaAuthFetcher::MakeGetTokenPairBody( |
| 271 const std::string& auth_code) { |
| 272 std::string encoded_scope = net::EscapeUrlEncodedData( |
| 273 GaiaUrls::GetInstance()->oauth1_login_scope(), true); |
| 274 std::string encoded_client_id = net::EscapeUrlEncodedData( |
| 275 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), true); |
| 276 std::string encoded_client_secret = net::EscapeUrlEncodedData( |
| 277 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), true); |
| 278 std::string encoded_auth_code = net::EscapeUrlEncodedData(auth_code, true); |
| 279 return StringPrintf(kGetTokenPairBodyFormat, |
| 280 encoded_scope.c_str(), |
| 281 encoded_client_id.c_str(), |
| 282 encoded_client_secret.c_str(), |
| 283 encoded_auth_code.c_str()); |
| 284 } |
| 285 |
| 286 // static |
| 212 std::string GaiaAuthFetcher::MakeGetUserInfoBody(const std::string& lsid) { | 287 std::string GaiaAuthFetcher::MakeGetUserInfoBody(const std::string& lsid) { |
| 213 std::string encoded_lsid = net::EscapeUrlEncodedData(lsid, true); | 288 std::string encoded_lsid = net::EscapeUrlEncodedData(lsid, true); |
| 214 return base::StringPrintf(kGetUserInfoFormat, encoded_lsid.c_str()); | 289 return base::StringPrintf(kGetUserInfoFormat, encoded_lsid.c_str()); |
| 215 } | 290 } |
| 216 | 291 |
| 217 // static | 292 // static |
| 218 std::string GaiaAuthFetcher::MakeTokenAuthBody(const std::string& auth_token, | 293 std::string GaiaAuthFetcher::MakeTokenAuthBody(const std::string& auth_token, |
| 219 const std::string& continue_url, | 294 const std::string& continue_url, |
| 220 const std::string& source) { | 295 const std::string& source) { |
| 221 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); | 296 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 236 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); | 311 std::string encoded_auth_token = net::EscapeUrlEncodedData(auth_token, true); |
| 237 std::string encoded_continue_url = net::EscapeUrlEncodedData(continue_url, | 312 std::string encoded_continue_url = net::EscapeUrlEncodedData(continue_url, |
| 238 true); | 313 true); |
| 239 std::string encoded_source = net::EscapeUrlEncodedData(source, true); | 314 std::string encoded_source = net::EscapeUrlEncodedData(source, true); |
| 240 return base::StringPrintf(kMergeSessionFormat, | 315 return base::StringPrintf(kMergeSessionFormat, |
| 241 encoded_auth_token.c_str(), | 316 encoded_auth_token.c_str(), |
| 242 encoded_continue_url.c_str(), | 317 encoded_continue_url.c_str(), |
| 243 encoded_source.c_str()); | 318 encoded_source.c_str()); |
| 244 } | 319 } |
| 245 | 320 |
| 321 // static |
| 322 std::string GaiaAuthFetcher::MakeGetAuthCodeHeader( |
| 323 const std::string& auth_token) { |
| 324 return StringPrintf(kAuthHeaderFormat, auth_token.c_str()); |
| 325 } |
| 326 |
| 246 // Helper method that extracts tokens from a successful reply. | 327 // Helper method that extracts tokens from a successful reply. |
| 247 // static | 328 // static |
| 248 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, | 329 void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, |
| 249 std::string* sid, | 330 std::string* sid, |
| 250 std::string* lsid, | 331 std::string* lsid, |
| 251 std::string* token) { | 332 std::string* token) { |
| 252 using std::vector; | 333 using std::vector; |
| 253 using std::pair; | 334 using std::pair; |
| 254 using std::string; | 335 using std::string; |
| 255 | 336 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 286 } else if (i->first == kErrorUrlParam) { | 367 } else if (i->first == kErrorUrlParam) { |
| 287 error_url->assign(i->second); | 368 error_url->assign(i->second); |
| 288 } else if (i->first == kCaptchaUrlParam) { | 369 } else if (i->first == kCaptchaUrlParam) { |
| 289 captcha_url->assign(i->second); | 370 captcha_url->assign(i->second); |
| 290 } else if (i->first == kCaptchaTokenParam) { | 371 } else if (i->first == kCaptchaTokenParam) { |
| 291 captcha_token->assign(i->second); | 372 captcha_token->assign(i->second); |
| 292 } | 373 } |
| 293 } | 374 } |
| 294 } | 375 } |
| 295 | 376 |
| 377 // static |
| 378 bool GaiaAuthFetcher::ParseGetAuthCodeResponse( |
| 379 const net::ResponseCookies& cookies, |
| 380 std::string* auth_code) { |
| 381 DCHECK(auth_code); |
| 382 net::ResponseCookies::const_iterator iter; |
| 383 for (iter = cookies.begin(); iter != cookies.end(); ++iter) { |
| 384 if (ParseCookieToAuthCode(*iter, auth_code)) |
| 385 return true; |
| 386 } |
| 387 return false; |
| 388 } |
| 389 |
| 390 // static |
| 391 bool GaiaAuthFetcher::ParseGetTokenPairResponse(const std::string& data, |
| 392 std::string* refresh_token, |
| 393 std::string* access_token, |
| 394 int* expires_in_secs) { |
| 395 DCHECK(refresh_token); |
| 396 DCHECK(access_token); |
| 397 base::JSONReader reader; |
| 398 scoped_ptr<base::Value> value(reader.Read(data, false)); |
| 399 if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY) |
| 400 return false; |
| 401 |
| 402 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); |
| 403 std::string rt; |
| 404 std::string at; |
| 405 int exp; |
| 406 |
| 407 if (!dict->GetStringWithoutPathExpansion(kRefreshTokenKey, &rt) || |
| 408 !dict->GetStringWithoutPathExpansion(kAccessTokenKey, &at) || |
| 409 !dict->GetIntegerWithoutPathExpansion(kExpiresInKey, &exp)) { |
| 410 return false; |
| 411 } |
| 412 |
| 413 refresh_token->assign(rt); |
| 414 access_token->assign(at); |
| 415 *expires_in_secs = exp; |
| 416 return true; |
| 417 } |
| 418 |
| 419 // static |
| 420 bool GaiaAuthFetcher::ParseCookieToAuthCode(const std::string& cookie, |
| 421 std::string* auth_code) { |
| 422 std::vector<std::string> parts; |
| 423 base::SplitString(cookie, ';', &parts); |
| 424 // Per documentation, the cookie should have Secure and HttpOnly. |
| 425 if (!CookiePartsContains(parts, kAuthCodeCookiePartSecure) || |
| 426 !CookiePartsContains(parts, kAuthCodeCookiePartHttpOnly)) { |
| 427 return false; |
| 428 } |
| 429 |
| 430 std::vector<std::string>::const_iterator iter; |
| 431 for (iter = parts.begin(); iter != parts.end(); ++iter) { |
| 432 const std::string& part = *iter; |
| 433 if (StartsWithASCII(part, kAuthCodeCookiePartCodePrefix, false)) { |
| 434 auth_code->assign(part.substr(kAuthCodeCookiePartCodePrefixLength)); |
| 435 return true; |
| 436 } |
| 437 } |
| 438 return false; |
| 439 } |
| 440 |
| 296 void GaiaAuthFetcher::StartClientLogin( | 441 void GaiaAuthFetcher::StartClientLogin( |
| 297 const std::string& username, | 442 const std::string& username, |
| 298 const std::string& password, | 443 const std::string& password, |
| 299 const char* const service, | 444 const char* const service, |
| 300 const std::string& login_token, | 445 const std::string& login_token, |
| 301 const std::string& login_captcha, | 446 const std::string& login_captcha, |
| 302 HostedAccountsSetting allow_hosted_accounts) { | 447 HostedAccountsSetting allow_hosted_accounts) { |
| 303 | 448 |
| 304 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 449 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 305 | 450 |
| 306 // This class is thread agnostic, so be sure to call this only on the | 451 // This class is thread agnostic, so be sure to call this only on the |
| 307 // same thread each time. | 452 // same thread each time. |
| 308 DVLOG(1) << "Starting new ClientLogin fetch for:" << username; | 453 DVLOG(1) << "Starting new ClientLogin fetch for:" << username; |
| 309 | 454 |
| 310 // Must outlive fetcher_. | 455 // Must outlive fetcher_. |
| 311 request_body_ = MakeClientLoginBody(username, | 456 request_body_ = MakeClientLoginBody(username, |
| 312 password, | 457 password, |
| 313 source_, | 458 source_, |
| 314 service, | 459 service, |
| 315 login_token, | 460 login_token, |
| 316 login_captcha, | 461 login_captcha, |
| 317 allow_hosted_accounts); | 462 allow_hosted_accounts); |
| 318 fetcher_.reset(CreateGaiaFetcher(getter_, | 463 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 319 request_body_, | 464 request_body_, |
| 465 "", |
| 320 client_login_gurl_, | 466 client_login_gurl_, |
| 321 false, | 467 false, |
| 322 this)); | 468 this)); |
| 323 fetch_pending_ = true; | 469 fetch_pending_ = true; |
| 324 fetcher_->Start(); | 470 fetcher_->Start(); |
| 325 } | 471 } |
| 326 | 472 |
| 327 void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, | 473 void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, |
| 328 const std::string& lsid, | 474 const std::string& lsid, |
| 329 const char* const service) { | 475 const char* const service) { |
| 330 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 476 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 331 | 477 |
| 332 DVLOG(1) << "Starting IssueAuthToken for: " << service; | 478 DVLOG(1) << "Starting IssueAuthToken for: " << service; |
| 333 requested_service_ = service; | 479 requested_service_ = service; |
| 334 request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); | 480 request_body_ = MakeIssueAuthTokenBody(sid, lsid, service); |
| 335 fetcher_.reset(CreateGaiaFetcher(getter_, | 481 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 336 request_body_, | 482 request_body_, |
| 483 "", |
| 337 issue_auth_token_gurl_, | 484 issue_auth_token_gurl_, |
| 338 false, | 485 false, |
| 339 this)); | 486 this)); |
| 340 fetch_pending_ = true; | 487 fetch_pending_ = true; |
| 341 fetcher_->Start(); | 488 fetcher_->Start(); |
| 342 } | 489 } |
| 343 | 490 |
| 491 void GaiaAuthFetcher::StartOAuthLoginTokenFetch( |
| 492 const std::string& auth_token) { |
| 493 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 494 |
| 495 DVLOG(1) << "Starting OAuth login token fetch"; |
| 496 request_body_ = MakeGetAuthCodeBody(); |
| 497 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 498 request_body_, |
| 499 MakeGetAuthCodeHeader(auth_token), |
| 500 get_auth_code_gurl_, |
| 501 false, |
| 502 this)); |
| 503 fetch_pending_ = true; |
| 504 fetcher_->Start(); |
| 505 } |
| 506 |
| 344 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, | 507 void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, |
| 345 const std::string& info_key) { | 508 const std::string& info_key) { |
| 346 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 509 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 347 | 510 |
| 348 DVLOG(1) << "Starting GetUserInfo for lsid=" << lsid; | 511 DVLOG(1) << "Starting GetUserInfo for lsid=" << lsid; |
| 349 request_body_ = MakeGetUserInfoBody(lsid); | 512 request_body_ = MakeGetUserInfoBody(lsid); |
| 350 fetcher_.reset(CreateGaiaFetcher(getter_, | 513 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 351 request_body_, | 514 request_body_, |
| 515 "", |
| 352 get_user_info_gurl_, | 516 get_user_info_gurl_, |
| 353 false, | 517 false, |
| 354 this)); | 518 this)); |
| 355 fetch_pending_ = true; | 519 fetch_pending_ = true; |
| 356 requested_info_key_ = info_key; | 520 requested_info_key_ = info_key; |
| 357 fetcher_->Start(); | 521 fetcher_->Start(); |
| 358 } | 522 } |
| 359 | 523 |
| 360 void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { | 524 void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { |
| 361 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 525 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 362 | 526 |
| 363 DVLOG(1) << "Starting TokenAuth with auth_token=" << auth_token; | 527 DVLOG(1) << "Starting TokenAuth with auth_token=" << auth_token; |
| 364 | 528 |
| 365 // The continue URL is a required parameter of the TokenAuth API, but in this | 529 // The continue URL is a required parameter of the TokenAuth API, but in this |
| 366 // case we don't actually need or want to navigate to it. Setting it to | 530 // case we don't actually need or want to navigate to it. Setting it to |
| 367 // an arbitrary Google URL. | 531 // an arbitrary Google URL. |
| 368 std::string continue_url("http://www.google.com"); | 532 std::string continue_url("http://www.google.com"); |
| 369 request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_); | 533 request_body_ = MakeTokenAuthBody(auth_token, continue_url, source_); |
| 370 fetcher_.reset(CreateGaiaFetcher(getter_, | 534 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 371 request_body_, | 535 request_body_, |
| 536 "", |
| 372 token_auth_gurl_, | 537 token_auth_gurl_, |
| 373 false, | 538 false, |
| 374 this)); | 539 this)); |
| 375 fetch_pending_ = true; | 540 fetch_pending_ = true; |
| 376 fetcher_->Start(); | 541 fetcher_->Start(); |
| 377 } | 542 } |
| 378 | 543 |
| 379 void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { | 544 void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { |
| 380 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; | 545 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 381 | 546 |
| 382 DVLOG(1) << "Starting MergeSession with auth_token=" << auth_token; | 547 DVLOG(1) << "Starting MergeSession with auth_token=" << auth_token; |
| 383 | 548 |
| 384 // The continue URL is a required parameter of the MergeSession API, but in | 549 // The continue URL is a required parameter of the MergeSession API, but in |
| 385 // this case we don't actually need or want to navigate to it. Setting it to | 550 // this case we don't actually need or want to navigate to it. Setting it to |
| 386 // an arbitrary Google URL. | 551 // an arbitrary Google URL. |
| 387 // | 552 // |
| 388 // In order for the new session to be merged correctly, the server needs to | 553 // In order for the new session to be merged correctly, the server needs to |
| 389 // know what sessions already exist in the browser. The fetcher needs to be | 554 // know what sessions already exist in the browser. The fetcher needs to be |
| 390 // created such that it sends the cookies with the request, which is | 555 // created such that it sends the cookies with the request, which is |
| 391 // different from all other requests the fetcher can make. | 556 // different from all other requests the fetcher can make. |
| 392 std::string continue_url("http://www.google.com"); | 557 std::string continue_url("http://www.google.com"); |
| 393 request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_); | 558 request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_); |
| 394 fetcher_.reset(CreateGaiaFetcher(getter_, | 559 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 395 request_body_, | 560 request_body_, |
| 561 "", |
| 396 merge_session_gurl_, | 562 merge_session_gurl_, |
| 397 true, | 563 true, |
| 398 this)); | 564 this)); |
| 399 fetch_pending_ = true; | 565 fetch_pending_ = true; |
| 400 fetcher_->Start(); | 566 fetcher_->Start(); |
| 401 } | 567 } |
| 402 | 568 |
| 403 // static | 569 // static |
| 404 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( | 570 GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError( |
| 405 const std::string& data, | 571 const std::string& data, |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 if (status.is_success() && response_code == RC_REQUEST_OK) { | 695 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 530 // Only the bare token is returned in the body of this Gaia call | 696 // Only the bare token is returned in the body of this Gaia call |
| 531 // without any padding. | 697 // without any padding. |
| 532 consumer_->OnIssueAuthTokenSuccess(requested_service_, data); | 698 consumer_->OnIssueAuthTokenSuccess(requested_service_, data); |
| 533 } else { | 699 } else { |
| 534 consumer_->OnIssueAuthTokenFailure(requested_service_, | 700 consumer_->OnIssueAuthTokenFailure(requested_service_, |
| 535 GenerateAuthError(data, status)); | 701 GenerateAuthError(data, status)); |
| 536 } | 702 } |
| 537 } | 703 } |
| 538 | 704 |
| 705 void GaiaAuthFetcher::OnGetAuthCodeFetched( |
| 706 const std::string& data, |
| 707 const net::ResponseCookies& cookies, |
| 708 const net::URLRequestStatus& status, |
| 709 int response_code) { |
| 710 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 711 std::string auth_code; |
| 712 if (!ParseGetAuthCodeResponse(cookies, &auth_code)) { |
| 713 consumer_->OnOAuthLoginTokenFailure(GoogleServiceAuthError( |
| 714 GoogleServiceAuthError::UNEXPECTED_RESPONSE)); |
| 715 } else { |
| 716 // Start GetTokenPair. |
| 717 StartGetTokenPair(auth_code); |
| 718 } |
| 719 } else { |
| 720 consumer_->OnOAuthLoginTokenFailure(GenerateAuthError(data, status)); |
| 721 } |
| 722 } |
| 723 |
| 724 void GaiaAuthFetcher::StartGetTokenPair(const std::string& auth_code) { |
| 725 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; |
| 726 |
| 727 DVLOG(1) << "Starting OAuth token pair fetch"; |
| 728 request_body_ = MakeGetTokenPairBody(auth_code); |
| 729 fetcher_.reset(CreateGaiaFetcher(getter_, |
| 730 request_body_, |
| 731 "", |
| 732 get_token_pair_gurl_, |
| 733 false, |
| 734 this)); |
| 735 fetch_pending_ = true; |
| 736 fetcher_->Start(); |
| 737 } |
| 738 |
| 739 void GaiaAuthFetcher::OnGetTokenPairFetched( |
| 740 const std::string& data, |
| 741 const net::URLRequestStatus& status, |
| 742 int response_code) { |
| 743 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 744 std::string refresh_token; |
| 745 std::string access_token; |
| 746 int expires_in_secs; |
| 747 if (ParseGetTokenPairResponse( |
| 748 data, &refresh_token, &access_token, &expires_in_secs)) { |
| 749 consumer_->OnOAuthLoginTokenSuccess( |
| 750 refresh_token, access_token, expires_in_secs); |
| 751 } else { |
| 752 consumer_->OnOAuthLoginTokenFailure(GoogleServiceAuthError( |
| 753 GoogleServiceAuthError::UNEXPECTED_RESPONSE)); |
| 754 } |
| 755 } else { |
| 756 consumer_->OnOAuthLoginTokenFailure(GenerateAuthError(data, status)); |
| 757 } |
| 758 } |
| 759 |
| 539 void GaiaAuthFetcher::OnGetUserInfoFetched( | 760 void GaiaAuthFetcher::OnGetUserInfoFetched( |
| 540 const std::string& data, | 761 const std::string& data, |
| 541 const net::URLRequestStatus& status, | 762 const net::URLRequestStatus& status, |
| 542 int response_code) { | 763 int response_code) { |
| 543 using std::vector; | 764 using std::vector; |
| 544 using std::string; | 765 using std::string; |
| 545 using std::pair; | 766 using std::pair; |
| 546 | 767 |
| 547 if (status.is_success() && response_code == RC_REQUEST_OK) { | 768 if (status.is_success() && response_code == RC_REQUEST_OK) { |
| 548 vector<pair<string, string> > tokens; | 769 vector<pair<string, string> > tokens; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 fetch_pending_ = false; | 805 fetch_pending_ = false; |
| 585 const GURL& url = source->GetURL(); | 806 const GURL& url = source->GetURL(); |
| 586 const net::URLRequestStatus& status = source->GetStatus(); | 807 const net::URLRequestStatus& status = source->GetStatus(); |
| 587 int response_code = source->GetResponseCode(); | 808 int response_code = source->GetResponseCode(); |
| 588 std::string data; | 809 std::string data; |
| 589 source->GetResponseAsString(&data); | 810 source->GetResponseAsString(&data); |
| 590 if (url == client_login_gurl_) { | 811 if (url == client_login_gurl_) { |
| 591 OnClientLoginFetched(data, status, response_code); | 812 OnClientLoginFetched(data, status, response_code); |
| 592 } else if (url == issue_auth_token_gurl_) { | 813 } else if (url == issue_auth_token_gurl_) { |
| 593 OnIssueAuthTokenFetched(data, status, response_code); | 814 OnIssueAuthTokenFetched(data, status, response_code); |
| 815 } else if (url == get_auth_code_gurl_) { |
| 816 OnGetAuthCodeFetched(data, source->GetCookies(), status, response_code); |
| 817 } else if (url == get_token_pair_gurl_) { |
| 818 OnGetTokenPairFetched(data, status, response_code); |
| 594 } else if (url == get_user_info_gurl_) { | 819 } else if (url == get_user_info_gurl_) { |
| 595 OnGetUserInfoFetched(data, status, response_code); | 820 OnGetUserInfoFetched(data, status, response_code); |
| 596 } else if (url == token_auth_gurl_) { | 821 } else if (url == token_auth_gurl_) { |
| 597 OnTokenAuthFetched(data, status, response_code); | 822 OnTokenAuthFetched(data, status, response_code); |
| 598 } else if (url == merge_session_gurl_ || | 823 } else if (url == merge_session_gurl_ || |
| 599 (source && source->GetOriginalURL() == merge_session_gurl_)) { | 824 (source && source->GetOriginalURL() == merge_session_gurl_)) { |
| 600 // MergeSession may redirect, so check the original URL of the fetcher. | 825 // MergeSession may redirect, so check the original URL of the fetcher. |
| 601 OnMergeSessionFetched(data, status, response_code); | 826 OnMergeSessionFetched(data, status, response_code); |
| 602 } else { | 827 } else { |
| 603 NOTREACHED(); | 828 NOTREACHED(); |
| 604 } | 829 } |
| 605 } | 830 } |
| 606 | 831 |
| 607 // static | 832 // static |
| 608 bool GaiaAuthFetcher::IsSecondFactorSuccess( | 833 bool GaiaAuthFetcher::IsSecondFactorSuccess( |
| 609 const std::string& alleged_error) { | 834 const std::string& alleged_error) { |
| 610 return alleged_error.find(kSecondFactor) != | 835 return alleged_error.find(kSecondFactor) != |
| 611 std::string::npos; | 836 std::string::npos; |
| 612 } | 837 } |
| OLD | NEW |