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 |