| 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/oauth2_access_token_fetcher.h" | 5 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> |
| 9 | 10 |
| 10 #include "base/json/json_reader.h" | 11 #include "base/json/json_reader.h" |
| 12 #include "base/string_util.h" |
| 11 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 12 #include "base/values.h" | 14 #include "base/values.h" |
| 13 #include "chrome/common/net/gaia/gaia_urls.h" | 15 #include "chrome/common/net/gaia/gaia_urls.h" |
| 14 #include "chrome/common/net/gaia/google_service_auth_error.h" | 16 #include "chrome/common/net/gaia/google_service_auth_error.h" |
| 15 #include "chrome/common/net/http_return.h" | 17 #include "chrome/common/net/http_return.h" |
| 16 #include "net/base/escape.h" | 18 #include "net/base/escape.h" |
| 17 #include "net/base/load_flags.h" | 19 #include "net/base/load_flags.h" |
| 18 #include "net/url_request/url_request_context_getter.h" | 20 #include "net/url_request/url_request_context_getter.h" |
| 19 #include "net/url_request/url_request_status.h" | 21 #include "net/url_request/url_request_status.h" |
| 20 | 22 |
| 21 using content::URLFetcher; | 23 using content::URLFetcher; |
| 22 using content::URLFetcherDelegate; | 24 using content::URLFetcherDelegate; |
| 23 using net::ResponseCookies; | 25 using net::ResponseCookies; |
| 24 using net::URLRequestContextGetter; | 26 using net::URLRequestContextGetter; |
| 25 using net::URLRequestStatus; | 27 using net::URLRequestStatus; |
| 26 | 28 |
| 27 namespace { | 29 namespace { |
| 28 static const char kGetAccessTokenBodyFormat[] = | 30 static const char kGetAccessTokenBodyFormat[] = |
| 29 "client_id=%s&" | 31 "client_id=%s&" |
| 30 "client_secret=%s" | 32 "client_secret=%s&" |
| 31 "grant_type=refresh_token&" | 33 "grant_type=refresh_token&" |
| 32 "refresh_token=%s"; | 34 "refresh_token=%s"; |
| 33 | 35 |
| 36 static const char kGetAccessTokenBodyWithScopeFormat[] = |
| 37 "client_id=%s&" |
| 38 "client_secret=%s&" |
| 39 "grant_type=refresh_token&" |
| 40 "refresh_token=%s&" |
| 41 "scope=%s"; |
| 42 |
| 34 static const char kAccessTokenKey[] = "access_token"; | 43 static const char kAccessTokenKey[] = "access_token"; |
| 35 | 44 |
| 36 static bool GetStringFromDictionary(const DictionaryValue* dict, | 45 static bool GetStringFromDictionary(const DictionaryValue* dict, |
| 37 const std::string& key, | 46 const std::string& key, |
| 38 std::string* value) { | 47 std::string* value) { |
| 39 Value* json_value; | 48 Value* json_value; |
| 40 if (!dict->Get(key, &json_value)) | 49 if (!dict->Get(key, &json_value)) |
| 41 return false; | 50 return false; |
| 42 if (json_value->GetType() != base::Value::TYPE_STRING) | 51 if (json_value->GetType() != base::Value::TYPE_STRING) |
| 43 return false; | 52 return false; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 74 | 83 |
| 75 if (!empty_body) | 84 if (!empty_body) |
| 76 result->SetUploadData("application/x-www-form-urlencoded", body); | 85 result->SetUploadData("application/x-www-form-urlencoded", body); |
| 77 | 86 |
| 78 return result; | 87 return result; |
| 79 } | 88 } |
| 80 } // namespace | 89 } // namespace |
| 81 | 90 |
| 82 OAuth2AccessTokenFetcher::OAuth2AccessTokenFetcher( | 91 OAuth2AccessTokenFetcher::OAuth2AccessTokenFetcher( |
| 83 OAuth2AccessTokenConsumer* consumer, | 92 OAuth2AccessTokenConsumer* consumer, |
| 84 URLRequestContextGetter* getter, | 93 URLRequestContextGetter* getter) |
| 85 const std::string& source) | |
| 86 : consumer_(consumer), | 94 : consumer_(consumer), |
| 87 getter_(getter), | 95 getter_(getter), |
| 88 source_(source), | |
| 89 state_(INITIAL) { } | 96 state_(INITIAL) { } |
| 90 | 97 |
| 91 OAuth2AccessTokenFetcher::~OAuth2AccessTokenFetcher() { } | 98 OAuth2AccessTokenFetcher::~OAuth2AccessTokenFetcher() { } |
| 92 | 99 |
| 93 void OAuth2AccessTokenFetcher::CancelRequest() { | 100 void OAuth2AccessTokenFetcher::CancelRequest() { |
| 94 fetcher_.reset(); | 101 fetcher_.reset(); |
| 95 } | 102 } |
| 96 | 103 |
| 97 void OAuth2AccessTokenFetcher::Start(const std::string& client_id, | 104 void OAuth2AccessTokenFetcher::Start(const std::string& client_id, |
| 98 const std::string& client_secret, | 105 const std::string& client_secret, |
| 99 const std::string& refresh_token) { | 106 const std::string& refresh_token, |
| 107 const std::vector<std::string>& scopes) { |
| 100 client_id_ = client_id; | 108 client_id_ = client_id; |
| 101 client_secret_ = client_secret; | 109 client_secret_ = client_secret; |
| 102 refresh_token_ = refresh_token; | 110 refresh_token_ = refresh_token; |
| 111 scopes_ = scopes; |
| 103 StartGetAccessToken(); | 112 StartGetAccessToken(); |
| 104 } | 113 } |
| 105 | 114 |
| 106 void OAuth2AccessTokenFetcher::StartGetAccessToken() { | 115 void OAuth2AccessTokenFetcher::StartGetAccessToken() { |
| 107 CHECK_EQ(INITIAL, state_); | 116 CHECK_EQ(INITIAL, state_); |
| 108 state_ = GET_ACCESS_TOKEN_STARTED; | 117 state_ = GET_ACCESS_TOKEN_STARTED; |
| 109 fetcher_.reset(CreateFetcher( | 118 fetcher_.reset(CreateFetcher( |
| 110 getter_, | 119 getter_, |
| 111 MakeGetAccessTokenUrl(), | 120 MakeGetAccessTokenUrl(), |
| 112 MakeGetAccessTokenBody(client_id_, client_secret_, refresh_token_), | 121 MakeGetAccessTokenBody( |
| 122 client_id_, client_secret_, refresh_token_, scopes_), |
| 113 this)); | 123 this)); |
| 114 fetcher_->Start(); // OnURLFetchComplete will be called. | 124 fetcher_->Start(); // OnURLFetchComplete will be called. |
| 115 } | 125 } |
| 116 | 126 |
| 117 void OAuth2AccessTokenFetcher::EndGetAccessToken(const URLFetcher* source) { | 127 void OAuth2AccessTokenFetcher::EndGetAccessToken(const URLFetcher* source) { |
| 118 CHECK_EQ(GET_ACCESS_TOKEN_STARTED, state_); | 128 CHECK_EQ(GET_ACCESS_TOKEN_STARTED, state_); |
| 119 state_ = GET_ACCESS_TOKEN_DONE; | 129 state_ = GET_ACCESS_TOKEN_DONE; |
| 120 | 130 |
| 121 URLRequestStatus status = source->GetStatus(); | 131 URLRequestStatus status = source->GetStatus(); |
| 122 if (!status.is_success()) { | 132 if (!status.is_success()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 | 165 |
| 156 // static | 166 // static |
| 157 GURL OAuth2AccessTokenFetcher::MakeGetAccessTokenUrl() { | 167 GURL OAuth2AccessTokenFetcher::MakeGetAccessTokenUrl() { |
| 158 return GURL(GaiaUrls::GetInstance()->oauth2_token_url()); | 168 return GURL(GaiaUrls::GetInstance()->oauth2_token_url()); |
| 159 } | 169 } |
| 160 | 170 |
| 161 // static | 171 // static |
| 162 std::string OAuth2AccessTokenFetcher::MakeGetAccessTokenBody( | 172 std::string OAuth2AccessTokenFetcher::MakeGetAccessTokenBody( |
| 163 const std::string& client_id, | 173 const std::string& client_id, |
| 164 const std::string& client_secret, | 174 const std::string& client_secret, |
| 165 const std::string& refresh_token) { | 175 const std::string& refresh_token, |
| 166 return StringPrintf( | 176 const std::vector<std::string>& scopes) { |
| 167 kGetAccessTokenBodyFormat, | 177 std::string enc_client_id = net::EscapeUrlEncodedData(client_id, true); |
| 168 net::EscapeUrlEncodedData(client_id, true).c_str(), | 178 std::string enc_client_secret = |
| 169 net::EscapeUrlEncodedData(client_secret, true).c_str(), | 179 net::EscapeUrlEncodedData(client_secret, true); |
| 170 net::EscapeUrlEncodedData(refresh_token, true).c_str()); | 180 std::string enc_refresh_token = |
| 181 net::EscapeUrlEncodedData(refresh_token, true); |
| 182 if (scopes.empty()) { |
| 183 return StringPrintf( |
| 184 kGetAccessTokenBodyFormat, |
| 185 enc_client_id.c_str(), |
| 186 enc_client_secret.c_str(), |
| 187 enc_refresh_token.c_str()); |
| 188 } else { |
| 189 std::string scopes_string = JoinString(scopes, ','); |
| 190 return StringPrintf( |
| 191 kGetAccessTokenBodyWithScopeFormat, |
| 192 enc_client_id.c_str(), |
| 193 enc_client_secret.c_str(), |
| 194 enc_refresh_token.c_str(), |
| 195 net::EscapeUrlEncodedData(scopes_string, true).c_str()); |
| 196 } |
| 171 } | 197 } |
| 172 | 198 |
| 173 // static | 199 // static |
| 174 bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse( | 200 bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse( |
| 175 const URLFetcher* source, | 201 const URLFetcher* source, |
| 176 std::string* access_token) { | 202 std::string* access_token) { |
| 177 CHECK(source); | 203 CHECK(source); |
| 178 CHECK(access_token); | 204 CHECK(access_token); |
| 179 std::string data; | 205 std::string data; |
| 180 source->GetResponseAsString(&data); | 206 source->GetResponseAsString(&data); |
| 181 base::JSONReader reader; | 207 base::JSONReader reader; |
| 182 scoped_ptr<base::Value> value(reader.Read(data, false)); | 208 scoped_ptr<base::Value> value(reader.Read(data, false)); |
| 183 if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY) | 209 if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY) |
| 184 return false; | 210 return false; |
| 185 | 211 |
| 186 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); | 212 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); |
| 187 return GetStringFromDictionary(dict, kAccessTokenKey, access_token); | 213 return GetStringFromDictionary(dict, kAccessTokenKey, access_token); |
| 188 } | 214 } |
| OLD | NEW |