Chromium Code Reviews| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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) | 94 const std::string& source) |
| 86 : consumer_(consumer), | 95 : consumer_(consumer), |
| 87 getter_(getter), | 96 getter_(getter), |
| 88 source_(source), | 97 source_(source), |
|
sail
2011/11/29 20:43:11
What should I pass for source? This doesn't seem t
Munjal (Google)
2011/11/29 21:58:09
Done. Good catch. I removed it.
| |
| 89 state_(INITIAL) { } | 98 state_(INITIAL) { } |
| 90 | 99 |
| 91 OAuth2AccessTokenFetcher::~OAuth2AccessTokenFetcher() { } | 100 OAuth2AccessTokenFetcher::~OAuth2AccessTokenFetcher() { } |
| 92 | 101 |
| 93 void OAuth2AccessTokenFetcher::CancelRequest() { | 102 void OAuth2AccessTokenFetcher::CancelRequest() { |
| 94 fetcher_.reset(); | 103 fetcher_.reset(); |
| 95 } | 104 } |
| 96 | 105 |
| 97 void OAuth2AccessTokenFetcher::Start(const std::string& client_id, | 106 void OAuth2AccessTokenFetcher::Start(const std::string& client_id, |
| 98 const std::string& client_secret, | 107 const std::string& client_secret, |
| 99 const std::string& refresh_token) { | 108 const std::string& refresh_token, |
| 109 const std::vector<std::string>& scopes) { | |
| 100 client_id_ = client_id; | 110 client_id_ = client_id; |
| 101 client_secret_ = client_secret; | 111 client_secret_ = client_secret; |
| 102 refresh_token_ = refresh_token; | 112 refresh_token_ = refresh_token; |
| 113 scopes_ = scopes; | |
| 103 StartGetAccessToken(); | 114 StartGetAccessToken(); |
| 104 } | 115 } |
| 105 | 116 |
| 106 void OAuth2AccessTokenFetcher::StartGetAccessToken() { | 117 void OAuth2AccessTokenFetcher::StartGetAccessToken() { |
| 107 CHECK_EQ(INITIAL, state_); | 118 CHECK_EQ(INITIAL, state_); |
| 108 state_ = GET_ACCESS_TOKEN_STARTED; | 119 state_ = GET_ACCESS_TOKEN_STARTED; |
| 109 fetcher_.reset(CreateFetcher( | 120 fetcher_.reset(CreateFetcher( |
| 110 getter_, | 121 getter_, |
| 111 MakeGetAccessTokenUrl(), | 122 MakeGetAccessTokenUrl(), |
| 112 MakeGetAccessTokenBody(client_id_, client_secret_, refresh_token_), | 123 MakeGetAccessTokenBody( |
| 124 client_id_, client_secret_, refresh_token_, scopes_), | |
| 113 this)); | 125 this)); |
| 114 fetcher_->Start(); // OnURLFetchComplete will be called. | 126 fetcher_->Start(); // OnURLFetchComplete will be called. |
| 115 } | 127 } |
| 116 | 128 |
| 117 void OAuth2AccessTokenFetcher::EndGetAccessToken(const URLFetcher* source) { | 129 void OAuth2AccessTokenFetcher::EndGetAccessToken(const URLFetcher* source) { |
| 118 CHECK_EQ(GET_ACCESS_TOKEN_STARTED, state_); | 130 CHECK_EQ(GET_ACCESS_TOKEN_STARTED, state_); |
| 119 state_ = GET_ACCESS_TOKEN_DONE; | 131 state_ = GET_ACCESS_TOKEN_DONE; |
| 120 | 132 |
| 121 URLRequestStatus status = source->GetStatus(); | 133 URLRequestStatus status = source->GetStatus(); |
| 122 if (!status.is_success()) { | 134 if (!status.is_success()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 | 167 |
| 156 // static | 168 // static |
| 157 GURL OAuth2AccessTokenFetcher::MakeGetAccessTokenUrl() { | 169 GURL OAuth2AccessTokenFetcher::MakeGetAccessTokenUrl() { |
| 158 return GURL(GaiaUrls::GetInstance()->oauth2_token_url()); | 170 return GURL(GaiaUrls::GetInstance()->oauth2_token_url()); |
| 159 } | 171 } |
| 160 | 172 |
| 161 // static | 173 // static |
| 162 std::string OAuth2AccessTokenFetcher::MakeGetAccessTokenBody( | 174 std::string OAuth2AccessTokenFetcher::MakeGetAccessTokenBody( |
| 163 const std::string& client_id, | 175 const std::string& client_id, |
| 164 const std::string& client_secret, | 176 const std::string& client_secret, |
| 165 const std::string& refresh_token) { | 177 const std::string& refresh_token, |
| 166 return StringPrintf( | 178 const std::vector<std::string>& scopes) { |
| 167 kGetAccessTokenBodyFormat, | 179 std::string enc_client_id = net::EscapeUrlEncodedData(client_id, true); |
| 168 net::EscapeUrlEncodedData(client_id, true).c_str(), | 180 std::string enc_client_secret = |
| 169 net::EscapeUrlEncodedData(client_secret, true).c_str(), | 181 net::EscapeUrlEncodedData(client_secret, true); |
| 170 net::EscapeUrlEncodedData(refresh_token, true).c_str()); | 182 std::string enc_refresh_token = |
| 183 net::EscapeUrlEncodedData(refresh_token, true); | |
| 184 if (scopes.empty()) { | |
| 185 return StringPrintf( | |
| 186 kGetAccessTokenBodyFormat, | |
| 187 enc_client_id.c_str(), | |
| 188 enc_client_secret.c_str(), | |
| 189 enc_refresh_token.c_str()); | |
| 190 } else { | |
| 191 std::string scopes_string = JoinString(scopes, ','); | |
| 192 return StringPrintf( | |
| 193 kGetAccessTokenBodyWithScopeFormat, | |
| 194 enc_client_id.c_str(), | |
| 195 enc_client_secret.c_str(), | |
| 196 enc_refresh_token.c_str(), | |
| 197 net::EscapeUrlEncodedData(scopes_string, true).c_str()); | |
| 198 } | |
| 171 } | 199 } |
| 172 | 200 |
| 173 // static | 201 // static |
| 174 bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse( | 202 bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse( |
| 175 const URLFetcher* source, | 203 const URLFetcher* source, |
| 176 std::string* access_token) { | 204 std::string* access_token) { |
| 177 CHECK(source); | 205 CHECK(source); |
| 178 CHECK(access_token); | 206 CHECK(access_token); |
| 179 std::string data; | 207 std::string data; |
| 180 source->GetResponseAsString(&data); | 208 source->GetResponseAsString(&data); |
| 181 base::JSONReader reader; | 209 base::JSONReader reader; |
| 182 scoped_ptr<base::Value> value(reader.Read(data, false)); | 210 scoped_ptr<base::Value> value(reader.Read(data, false)); |
| 183 if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY) | 211 if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY) |
| 184 return false; | 212 return false; |
| 185 | 213 |
| 186 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); | 214 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); |
| 187 return GetStringFromDictionary(dict, kAccessTokenKey, access_token); | 215 return GetStringFromDictionary(dict, kAccessTokenKey, access_token); |
| 188 } | 216 } |
| OLD | NEW |