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

Side by Side Diff: google_apis/gaia/gaia_auth_fetcher.cc

Issue 14169010: Remove support for ClientOAuth from GaiaAuthFetcher. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 7 years, 7 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
« no previous file with comments | « google_apis/gaia/gaia_auth_fetcher.h ('k') | google_apis/gaia/gaia_auth_fetcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "google_apis/gaia/gaia_auth_fetcher.h" 5 #include "google_apis/gaia/gaia_auth_fetcher.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 // static 128 // static
129 const char GaiaAuthFetcher::kErrorParam[] = "Error"; 129 const char GaiaAuthFetcher::kErrorParam[] = "Error";
130 // static 130 // static
131 const char GaiaAuthFetcher::kErrorUrlParam[] = "Url"; 131 const char GaiaAuthFetcher::kErrorUrlParam[] = "Url";
132 // static 132 // static
133 const char GaiaAuthFetcher::kCaptchaUrlParam[] = "CaptchaUrl"; 133 const char GaiaAuthFetcher::kCaptchaUrlParam[] = "CaptchaUrl";
134 // static 134 // static
135 const char GaiaAuthFetcher::kCaptchaTokenParam[] = "CaptchaToken"; 135 const char GaiaAuthFetcher::kCaptchaTokenParam[] = "CaptchaToken";
136 136
137 // static 137 // static
138 const char GaiaAuthFetcher::kNeedsAdditional[] = "NeedsAdditional";
139 // static
140 const char GaiaAuthFetcher::kCaptcha[] = "Captcha";
141 // static
142 const char GaiaAuthFetcher::kTwoFactor[] = "TwoStep";
143
144 // static
145 const char GaiaAuthFetcher::kCookiePersistence[] = "true"; 138 const char GaiaAuthFetcher::kCookiePersistence[] = "true";
146 // static 139 // static
147 // TODO(johnnyg): When hosted accounts are supported by sync, 140 // TODO(johnnyg): When hosted accounts are supported by sync,
148 // we can always use "HOSTED_OR_GOOGLE" 141 // we can always use "HOSTED_OR_GOOGLE"
149 const char GaiaAuthFetcher::kAccountTypeHostedOrGoogle[] = 142 const char GaiaAuthFetcher::kAccountTypeHostedOrGoogle[] =
150 "HOSTED_OR_GOOGLE"; 143 "HOSTED_OR_GOOGLE";
151 const char GaiaAuthFetcher::kAccountTypeGoogle[] = 144 const char GaiaAuthFetcher::kAccountTypeGoogle[] =
152 "GOOGLE"; 145 "GOOGLE";
153 146
154 // static 147 // static
(...skipping 26 matching lines...) Expand all
181 getter_(getter), 174 getter_(getter),
182 source_(source), 175 source_(source),
183 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()), 176 client_login_gurl_(GaiaUrls::GetInstance()->client_login_url()),
184 issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), 177 issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()),
185 oauth2_token_gurl_(GaiaUrls::GetInstance()->oauth2_token_url()), 178 oauth2_token_gurl_(GaiaUrls::GetInstance()->oauth2_token_url()),
186 oauth2_revoke_gurl_(GaiaUrls::GetInstance()->oauth2_revoke_url()), 179 oauth2_revoke_gurl_(GaiaUrls::GetInstance()->oauth2_revoke_url()),
187 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), 180 get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()),
188 merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), 181 merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()),
189 uberauth_token_gurl_(base::StringPrintf(kUberAuthTokenURLFormat, 182 uberauth_token_gurl_(base::StringPrintf(kUberAuthTokenURLFormat,
190 GaiaUrls::GetInstance()->oauth1_login_url().c_str(), source.c_str())), 183 GaiaUrls::GetInstance()->oauth1_login_url().c_str(), source.c_str())),
191 client_oauth_gurl_(GaiaUrls::GetInstance()->client_oauth_url()),
192 oauth_login_gurl_(GaiaUrls::GetInstance()->oauth1_login_url()), 184 oauth_login_gurl_(GaiaUrls::GetInstance()->oauth1_login_url()),
193 client_login_to_oauth2_gurl_( 185 client_login_to_oauth2_gurl_(
194 GaiaUrls::GetInstance()->client_login_to_oauth2_url()), 186 GaiaUrls::GetInstance()->client_login_to_oauth2_url()),
195 fetch_pending_(false) {} 187 fetch_pending_(false) {}
196 188
197 GaiaAuthFetcher::~GaiaAuthFetcher() {} 189 GaiaAuthFetcher::~GaiaAuthFetcher() {}
198 190
199 bool GaiaAuthFetcher::HasPendingFetch() { 191 bool GaiaAuthFetcher::HasPendingFetch() {
200 return fetch_pending_; 192 return fetch_pending_;
201 } 193 }
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 token->assign(i->second); 381 token->assign(i->second);
390 } 382 }
391 } 383 }
392 // If this was a request for uberauth token, then that's all we've got in 384 // If this was a request for uberauth token, then that's all we've got in
393 // data. 385 // data.
394 if (sid->empty() && lsid->empty() && token->empty()) 386 if (sid->empty() && lsid->empty() && token->empty())
395 token->assign(data); 387 token->assign(data);
396 } 388 }
397 389
398 // static 390 // static
399 std::string GaiaAuthFetcher::MakeClientOAuthBody(
400 const std::string& username,
401 const std::string& password,
402 const std::vector<std::string>& scopes,
403 const std::string& persistent_id,
404 const std::string& friendly_name,
405 const std::string& locale) {
406 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
407 dict->SetString(GaiaConstants::kClientOAuthEmailKey, username);
408 dict->SetString(GaiaConstants::kClientOAuthPasswordKey, password);
409
410 scoped_ptr<base::ListValue> scope_list(new base::ListValue);
411 for (size_t i = 0; i < scopes.size(); ++i)
412 scope_list->Append(base::Value::CreateStringValue(scopes[i]));
413 dict->Set(GaiaConstants::kClientOAuthScopesKey, scope_list.release());
414
415 dict->SetString(GaiaConstants::kClientOAuthOAuth2ClientIdKey,
416 GaiaUrls::GetInstance()->oauth2_chrome_client_id());
417 // crbug.com/129600: use a less generic friendly name.
418 dict->SetString(GaiaConstants::kClientOAuthFriendlyDeviceNameKey,
419 friendly_name);
420
421 scoped_ptr<base::ListValue> accepts_challenge_list(new base::ListValue);
422 accepts_challenge_list->Append(base::Value::CreateStringValue(kCaptcha));
423 accepts_challenge_list->Append(base::Value::CreateStringValue(kTwoFactor));
424 dict->Set(GaiaConstants::kClientOAuthAcceptsChallengesKey,
425 accepts_challenge_list.release());
426
427 dict->SetString(GaiaConstants::kClientOAuthLocaleKey, locale);
428 // Chrome presently does not not support a web-fallback for ClientOAuth,
429 // but need to hardcode an arbitrary one here since the endpoint expects it.
430 dict->SetString(GaiaConstants::kClientOAuthFallbackNameKey, "GetOAuth2Token");
431
432 std::string json_string;
433 base::JSONWriter::Write(dict.get(), &json_string);
434 return json_string;
435 }
436
437 // static
438 std::string GaiaAuthFetcher::MakeClientOAuthChallengeResponseBody(
439 const std::string& name,
440 const std::string& token,
441 const std::string& solution) {
442 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
443 std::string field_name = name == kTwoFactor ? "otp" : "solution";
444
445 scoped_ptr<base::DictionaryValue> challenge_reply(new base::DictionaryValue);
446 challenge_reply->SetString(GaiaConstants::kClientOAuthNameKey, name);
447 challenge_reply->SetString(GaiaConstants::kClientOAuthChallengeTokenKey,
448 token);
449 challenge_reply->SetString(field_name, solution);
450 dict->Set(GaiaConstants::kClientOAuthchallengeReplyKey,
451 challenge_reply.release());
452
453 std::string json_string;
454 base::JSONWriter::Write(dict.get(), &json_string);
455 return json_string;
456 }
457
458 // static
459 std::string GaiaAuthFetcher::MakeOAuthLoginBody(const std::string& service, 391 std::string GaiaAuthFetcher::MakeOAuthLoginBody(const std::string& service,
460 const std::string& source) { 392 const std::string& source) {
461 std::string encoded_service = net::EscapeUrlEncodedData(service, true); 393 std::string encoded_service = net::EscapeUrlEncodedData(service, true);
462 std::string encoded_source = net::EscapeUrlEncodedData(source, true); 394 std::string encoded_source = net::EscapeUrlEncodedData(source, true);
463 return base::StringPrintf(kOAuthLoginFormat, 395 return base::StringPrintf(kOAuthLoginFormat,
464 encoded_service.c_str(), 396 encoded_service.c_str(),
465 encoded_source.c_str()); 397 encoded_source.c_str());
466 } 398 }
467 399
468 // static 400 // static
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 if (StartsWithASCII( 453 if (StartsWithASCII(
522 part, kClientLoginToOAuth2CookiePartCodePrefix, false)) { 454 part, kClientLoginToOAuth2CookiePartCodePrefix, false)) {
523 auth_code->assign(part.substr( 455 auth_code->assign(part.substr(
524 kClientLoginToOAuth2CookiePartCodePrefixLength)); 456 kClientLoginToOAuth2CookiePartCodePrefixLength));
525 return true; 457 return true;
526 } 458 }
527 } 459 }
528 return false; 460 return false;
529 } 461 }
530 462
531 // static
532 GoogleServiceAuthError
533 GaiaAuthFetcher::GenerateClientOAuthError(const std::string& data,
534 const net::URLRequestStatus& status) {
535 scoped_ptr<base::Value> value(base::JSONReader::Read(data));
536 if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY)
537 return GenerateAuthError(data, status);
538 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
539
540 std::string cause;
541 if (!dict->GetStringWithoutPathExpansion("cause", &cause))
542 return GoogleServiceAuthError::FromClientOAuthError(data);
543
544 if (cause != kNeedsAdditional)
545 return GoogleServiceAuthError::FromClientOAuthError(data);
546
547 DictionaryValue* challenge;
548 if (!dict->GetDictionaryWithoutPathExpansion("challenge", &challenge))
549 return GoogleServiceAuthError::FromClientOAuthError(data);
550
551 std::string name;
552 if (!challenge->GetStringWithoutPathExpansion("name", &name))
553 return GoogleServiceAuthError::FromClientOAuthError(data);
554
555 if (name == kCaptcha) {
556 std::string token;
557 std::string audio_url;
558 std::string image_url;
559 int image_width;
560 int image_height;
561 if (!challenge->GetStringWithoutPathExpansion("challenge_token", &token) ||
562 !challenge->GetStringWithoutPathExpansion("audio_url", &audio_url) ||
563 !challenge->GetStringWithoutPathExpansion("image_url", &image_url) ||
564 !challenge->GetIntegerWithoutPathExpansion("image_width",
565 &image_width) ||
566 !challenge->GetIntegerWithoutPathExpansion("image_height",
567 &image_height)) {
568 return GoogleServiceAuthError::FromClientOAuthError(data);
569 }
570 return GoogleServiceAuthError::FromCaptchaChallenge(token, GURL(audio_url),
571 GURL(image_url),
572 image_width,
573 image_height);
574 } else if (name == kTwoFactor) {
575 std::string token;
576 std::string prompt_text;
577 std::string alternate_text;
578 int field_length;
579
580 // The protocol doc says these are required, but in practice they are not
581 // returned. So only a missing challenge token will cause an error here.
582 challenge->GetStringWithoutPathExpansion("prompt_text", &prompt_text);
583 challenge->GetStringWithoutPathExpansion("alternate_text", &alternate_text);
584 challenge->GetIntegerWithoutPathExpansion("field_length", &field_length);
585 if (!challenge->GetStringWithoutPathExpansion("challenge_token", &token))
586 return GoogleServiceAuthError::FromClientOAuthError(data);
587
588 return GoogleServiceAuthError::FromSecondFactorChallenge(token, prompt_text,
589 alternate_text,
590 field_length);
591 }
592
593 return GoogleServiceAuthError::FromClientOAuthError(data);
594 }
595
596 void GaiaAuthFetcher::StartClientLogin( 463 void GaiaAuthFetcher::StartClientLogin(
597 const std::string& username, 464 const std::string& username,
598 const std::string& password, 465 const std::string& password,
599 const char* const service, 466 const char* const service,
600 const std::string& login_token, 467 const std::string& login_token,
601 const std::string& login_captcha, 468 const std::string& login_captcha,
602 HostedAccountsSetting allow_hosted_accounts) { 469 HostedAccountsSetting allow_hosted_accounts) {
603 470
604 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; 471 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
605 472
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 fetcher_.reset(CreateGaiaFetcher(getter_, 634 fetcher_.reset(CreateGaiaFetcher(getter_,
768 std::string(), 635 std::string(),
769 authentication_header, 636 authentication_header,
770 uberauth_token_gurl_, 637 uberauth_token_gurl_,
771 kLoadFlagsIgnoreCookies, 638 kLoadFlagsIgnoreCookies,
772 this)); 639 this));
773 fetch_pending_ = true; 640 fetch_pending_ = true;
774 fetcher_->Start(); 641 fetcher_->Start();
775 } 642 }
776 643
777 void GaiaAuthFetcher::StartClientOAuth(const std::string& username,
778 const std::string& password,
779 const std::vector<std::string>& scopes,
780 const std::string& persistent_id,
781 const std::string& locale) {
782 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
783
784 request_body_ = MakeClientOAuthBody(username, password, scopes, persistent_id,
785 source_, locale);
786 fetcher_.reset(CreateGaiaFetcher(getter_,
787 request_body_,
788 std::string(),
789 client_oauth_gurl_,
790 kLoadFlagsIgnoreCookies,
791 this));
792 fetch_pending_ = true;
793 fetcher_->Start();
794 }
795
796 void GaiaAuthFetcher::StartClientOAuthChallengeResponse(
797 GoogleServiceAuthError::State type,
798 const std::string& token,
799 const std::string& solution) {
800 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
801
802 std::string name;
803 switch (type) {
804 case GoogleServiceAuthError::CAPTCHA_REQUIRED:
805 name = kCaptcha;
806 break;
807 case GoogleServiceAuthError::TWO_FACTOR:
808 name = kTwoFactor;
809 break;
810 default:
811 NOTREACHED();
812 }
813
814 request_body_ = MakeClientOAuthChallengeResponseBody(name, token, solution);
815 fetcher_.reset(CreateGaiaFetcher(getter_,
816 request_body_,
817 std::string(),
818 client_oauth_gurl_,
819 kLoadFlagsIgnoreCookies,
820 this));
821 fetch_pending_ = true;
822 fetcher_->Start();
823 }
824
825 void GaiaAuthFetcher::StartOAuthLogin(const std::string& access_token, 644 void GaiaAuthFetcher::StartOAuthLogin(const std::string& access_token,
826 const std::string& service) { 645 const std::string& service) {
827 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; 646 DCHECK(!fetch_pending_) << "Tried to fetch two things at once!";
828 647
829 request_body_ = MakeOAuthLoginBody(service, source_); 648 request_body_ = MakeOAuthLoginBody(service, source_);
830 std::string authentication_header = 649 std::string authentication_header =
831 base::StringPrintf(kOAuth2BearerHeaderFormat, access_token.c_str()); 650 base::StringPrintf(kOAuth2BearerHeaderFormat, access_token.c_str());
832 fetcher_.reset(CreateGaiaFetcher(getter_, 651 fetcher_.reset(CreateGaiaFetcher(getter_,
833 request_body_, 652 request_body_,
834 authentication_header, 653 authentication_header,
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 void GaiaAuthFetcher::OnUberAuthTokenFetch(const std::string& data, 873 void GaiaAuthFetcher::OnUberAuthTokenFetch(const std::string& data,
1055 const net::URLRequestStatus& status, 874 const net::URLRequestStatus& status,
1056 int response_code) { 875 int response_code) {
1057 if (status.is_success() && response_code == net::HTTP_OK) { 876 if (status.is_success() && response_code == net::HTTP_OK) {
1058 consumer_->OnUberAuthTokenSuccess(data); 877 consumer_->OnUberAuthTokenSuccess(data);
1059 } else { 878 } else {
1060 consumer_->OnUberAuthTokenFailure(GenerateAuthError(data, status)); 879 consumer_->OnUberAuthTokenFailure(GenerateAuthError(data, status));
1061 } 880 }
1062 } 881 }
1063 882
1064 void GaiaAuthFetcher::OnClientOAuthFetched(const std::string& data,
1065 const net::URLRequestStatus& status,
1066 int response_code) {
1067 std::string refresh_token;
1068 std::string access_token;
1069 int expires_in_secs = 0;
1070
1071 bool success = false;
1072 if (status.is_success() && response_code == net::HTTP_OK) {
1073 scoped_ptr<base::Value> value(base::JSONReader::Read(data));
1074 if (value.get() && value->GetType() == base::Value::TYPE_DICTIONARY) {
1075 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
1076 DictionaryValue* dict_oauth2;
1077 if (dict->GetDictionaryWithoutPathExpansion("oauth2", &dict_oauth2)) {
1078 success = ExtractOAuth2TokenPairResponse(dict_oauth2, &refresh_token,
1079 &access_token,
1080 &expires_in_secs);
1081 }
1082 }
1083 }
1084
1085 // TODO(rogerta): for now this reuses the OnOAuthLoginTokenXXX callbacks
1086 // since the data is exactly the same. This ignores the optional
1087 // persistent_id data in the response, which we may need to handle.
1088 // If we do, we'll need to modify ExtractOAuth2TokenPairResponse() to parse
1089 // the optional data and declare new consumer callbacks to take it.
1090 if (success) {
1091 consumer_->OnClientOAuthSuccess(
1092 GaiaAuthConsumer::ClientOAuthResult(refresh_token, access_token,
1093 expires_in_secs));
1094 } else {
1095 consumer_->OnClientOAuthFailure(GenerateClientOAuthError(data, status));
1096 }
1097 }
1098
1099 void GaiaAuthFetcher::OnOAuthLoginFetched(const std::string& data, 883 void GaiaAuthFetcher::OnOAuthLoginFetched(const std::string& data,
1100 const net::URLRequestStatus& status, 884 const net::URLRequestStatus& status,
1101 int response_code) { 885 int response_code) {
1102 if (status.is_success() && response_code == net::HTTP_OK) { 886 if (status.is_success() && response_code == net::HTTP_OK) {
1103 DVLOG(1) << "ClientLogin successful!"; 887 DVLOG(1) << "ClientLogin successful!";
1104 std::string sid; 888 std::string sid;
1105 std::string lsid; 889 std::string lsid;
1106 std::string token; 890 std::string token;
1107 ParseClientLoginResponse(data, &sid, &lsid, &token); 891 ParseClientLoginResponse(data, &sid, &lsid, &token);
1108 consumer_->OnClientLoginSuccess( 892 consumer_->OnClientLoginSuccess(
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 OnClientLoginToOAuth2Fetched( 924 OnClientLoginToOAuth2Fetched(
1141 data, source->GetCookies(), status, response_code); 925 data, source->GetCookies(), status, response_code);
1142 } else if (url == oauth2_token_gurl_) { 926 } else if (url == oauth2_token_gurl_) {
1143 OnOAuth2TokenPairFetched(data, status, response_code); 927 OnOAuth2TokenPairFetched(data, status, response_code);
1144 } else if (url == get_user_info_gurl_) { 928 } else if (url == get_user_info_gurl_) {
1145 OnGetUserInfoFetched(data, status, response_code); 929 OnGetUserInfoFetched(data, status, response_code);
1146 } else if (url == merge_session_gurl_) { 930 } else if (url == merge_session_gurl_) {
1147 OnMergeSessionFetched(data, status, response_code); 931 OnMergeSessionFetched(data, status, response_code);
1148 } else if (url == uberauth_token_gurl_) { 932 } else if (url == uberauth_token_gurl_) {
1149 OnUberAuthTokenFetch(data, status, response_code); 933 OnUberAuthTokenFetch(data, status, response_code);
1150 } else if (url == client_oauth_gurl_) {
1151 OnClientOAuthFetched(data, status, response_code);
1152 } else if (url == oauth_login_gurl_) { 934 } else if (url == oauth_login_gurl_) {
1153 OnOAuthLoginFetched(data, status, response_code); 935 OnOAuthLoginFetched(data, status, response_code);
1154 } else if (url == oauth2_revoke_gurl_) { 936 } else if (url == oauth2_revoke_gurl_) {
1155 OnOAuth2RevokeTokenFetched(data, status, response_code); 937 OnOAuth2RevokeTokenFetched(data, status, response_code);
1156 } else { 938 } else {
1157 NOTREACHED(); 939 NOTREACHED();
1158 } 940 }
1159 } 941 }
1160 942
1161 // static 943 // static
1162 bool GaiaAuthFetcher::IsSecondFactorSuccess( 944 bool GaiaAuthFetcher::IsSecondFactorSuccess(
1163 const std::string& alleged_error) { 945 const std::string& alleged_error) {
1164 return alleged_error.find(kSecondFactor) != 946 return alleged_error.find(kSecondFactor) !=
1165 std::string::npos; 947 std::string::npos;
1166 } 948 }
OLDNEW
« no previous file with comments | « google_apis/gaia/gaia_auth_fetcher.h ('k') | google_apis/gaia/gaia_auth_fetcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698