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

Side by Side Diff: chrome/common/net/gaia/oauth2_access_token_fetcher.cc

Issue 8632005: Part 1 of work to do user sign in based on OAuth2: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/json/json_reader.h"
11 #include "base/stringprintf.h"
12 #include "base/values.h"
13 #include "chrome/common/net/gaia/gaia_urls.h"
14 #include "chrome/common/net/gaia/google_service_auth_error.h"
15 #include "chrome/common/net/http_return.h"
16 #include "net/base/escape.h"
17 #include "net/base/load_flags.h"
18 #include "net/url_request/url_request_context_getter.h"
19 #include "net/url_request/url_request_status.h"
20
21 using content::URLFetcher;
22 using content::URLFetcherDelegate;
23 using net::ResponseCookies;
24 using net::URLRequestContextGetter;
25 using net::URLRequestStatus;
26
27 namespace {
28 static const char kGetAccessTokenBodyFormat[] =
29 "client_id=%s&"
30 "client_secret=%s"
31 "grant_type=refresh_token&"
32 "refresh_token=%s";
33
34 static const char kAccessTokenKey[] = "access_token";
35
36 static bool GetStringFromDictionary(const DictionaryValue* dict,
37 const std::string& key,
38 std::string* value) {
39 Value* json_value;
40 if (!dict->Get(key, &json_value))
41 return false;
42 if (json_value->GetType() != base::Value::TYPE_STRING)
43 return false;
44
45 StringValue* json_str_value = static_cast<StringValue*>(json_value);
46 json_str_value->GetAsString(value);
47 return true;
48 }
49
50 static GoogleServiceAuthError CreateAuthError(URLRequestStatus status) {
51 CHECK(!status.is_success());
52 if (status.status() == URLRequestStatus::CANCELED) {
53 return GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
54 } else {
55 DLOG(WARNING) << "Could not reach Google Accounts servers: errno "
56 << status.error();
57 return GoogleServiceAuthError::FromConnectionError(status.error());
58 }
59 }
60
61 static URLFetcher* CreateFetcher(URLRequestContextGetter* getter,
62 const GURL& url,
63 const std::string& body,
64 URLFetcherDelegate* delegate) {
65 bool empty_body = body.empty();
66 URLFetcher* result = URLFetcher::Create(
67 0, url,
68 empty_body ? URLFetcher::GET : URLFetcher::POST,
69 delegate);
70
71 result->SetRequestContext(getter);
72 result->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
73 net::LOAD_DO_NOT_SAVE_COOKIES);
74
75 if (!empty_body)
76 result->SetUploadData("application/x-www-form-urlencoded", body);
77
78 return result;
79 }
80 } // namespace
81
82 OAuth2AccessTokenFetcher::OAuth2AccessTokenFetcher(
83 OAuth2AccessTokenConsumer* consumer,
84 URLRequestContextGetter* getter,
85 const std::string& source)
86 : consumer_(consumer),
87 getter_(getter),
88 source_(source),
89 state_(INITIAL) { }
90
91 OAuth2AccessTokenFetcher::~OAuth2AccessTokenFetcher() { }
92
93 void OAuth2AccessTokenFetcher::CancelRequest() {
94 fetcher_.reset();
95 }
96
97 void OAuth2AccessTokenFetcher::Start(const std::string& refresh_token) {
98 refresh_token_ = refresh_token;
99 StartGetAccessToken();
100 }
101
102 void OAuth2AccessTokenFetcher::StartGetAccessToken() {
103 CHECK_EQ(INITIAL, state_);
104 state_ = GET_ACCESS_TOKEN_STARTED;
105 fetcher_.reset(CreateFetcher(
106 getter_,
107 MakeGetAccessTokenUrl(),
108 MakeGetAccessTokenBody(refresh_token_),
109 this));
110 fetcher_->Start(); // OnURLFetchComplete will be called.
111 }
112
113 void OAuth2AccessTokenFetcher::EndGetAccessToken(const URLFetcher* source) {
114 CHECK_EQ(GET_ACCESS_TOKEN_STARTED, state_);
115 state_ = GET_ACCESS_TOKEN_DONE;
116
117 URLRequestStatus status = source->GetStatus();
118 if (!status.is_success()) {
119 ReportFailure(CreateAuthError(status));
120 return;
121 }
122
123 if (source->GetResponseCode() != RC_REQUEST_OK) {
124 ReportFailure(GoogleServiceAuthError(
125 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
126 return;
127 }
128
129 // The request was successfully fetched and it returned OK.
130 // Parse out the access token.
131 std::string access_token;
132 if (!ParseGetAccessTokenResponse(source, &access_token)) {
133 ReportFailure(GoogleServiceAuthError(
134 GoogleServiceAuthError::UNEXPECTED_RESPONSE));
135 return;
136 }
137
138 ReportSuccess(access_token);
139 }
140
141 void OAuth2AccessTokenFetcher::ReportSuccess(const std::string& access_token) {
142 consumer_->OnGetTokenSuccess(access_token);
143 }
144
145 void OAuth2AccessTokenFetcher::ReportFailure(GoogleServiceAuthError error) {
146 state_ = ERROR_STATE;
147 consumer_->OnGetTokenFailure(error);
148 }
149
150 void OAuth2AccessTokenFetcher::OnURLFetchComplete(const URLFetcher* source) {
151 CHECK(source);
152 CHECK(state_ == GET_ACCESS_TOKEN_STARTED);
153 EndGetAccessToken(source);
154 }
155
156 // static
157 GURL OAuth2AccessTokenFetcher::MakeGetAccessTokenUrl() {
158 return GURL(GaiaUrls::GetInstance()->oauth2_token_url());
159 }
160
161 // static
162 std::string OAuth2AccessTokenFetcher::MakeGetAccessTokenBody(
163 const std::string& refresh_token) {
164 return StringPrintf(
165 kGetAccessTokenBodyFormat,
166 net::EscapeUrlEncodedData(
167 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), true).c_str(),
168 net::EscapeUrlEncodedData(
169 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
170 true).c_str(),
171 net::EscapeUrlEncodedData(refresh_token, true).c_str());
172 }
173
174 // static
175 bool OAuth2AccessTokenFetcher::ParseGetAccessTokenResponse(
176 const URLFetcher* source,
177 std::string* access_token) {
178 CHECK(source);
179 CHECK(access_token);
180 std::string data;
181 source->GetResponseAsString(&data);
182 base::JSONReader reader;
183 scoped_ptr<base::Value> value(reader.Read(data, false));
184 if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY)
185 return false;
186
187 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
188 return GetStringFromDictionary(dict, kAccessTokenKey, access_token);
189 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698