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

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

Issue 9549013: Add code to mint OAuth tokens from login-scoped OAuth token. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 9 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/common/net/gaia/oauth2_mint_token_fetcher.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/json/json_reader.h"
11 #include "base/string_util.h"
12 #include "base/stringprintf.h"
13 #include "base/values.h"
14 #include "chrome/common/net/gaia/gaia_urls.h"
15 #include "chrome/common/net/gaia/google_service_auth_error.h"
16 #include "net/base/escape.h"
17 #include "net/base/load_flags.h"
18 #include "net/http/http_status_code.h"
19 #include "net/url_request/url_request_context_getter.h"
20 #include "net/url_request/url_request_status.h"
21
22 using content::URLFetcher;
23 using content::URLFetcherDelegate;
24 using net::ResponseCookies;
25 using net::URLRequestContextGetter;
26 using net::URLRequestStatus;
27
28 namespace {
29 static const char kAuthorizationHeaderFormat[] =
30 "Authorization: Bearer %s";
31 static const char kOAuth2IssueTokenBodyFormat[] =
32 "force=true"
33 "&response_type=token"
34 "&scope=%s"
35 "&client_id=%s"
36 "&origin=%s";
37 static const char kAccessTokenKey[] = "token";
38
39 static GoogleServiceAuthError CreateAuthError(URLRequestStatus status) {
40 CHECK(!status.is_success());
41 if (status.status() == URLRequestStatus::CANCELED) {
42 return GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
43 } else {
44 DLOG(WARNING) << "Could not reach Google Accounts servers: errno "
45 << status.error();
46 return GoogleServiceAuthError::FromConnectionError(status.error());
47 }
48 }
49
50 static URLFetcher* CreateFetcher(URLRequestContextGetter* getter,
51 const GURL& url,
52 const std::string& headers,
53 const std::string& body,
54 URLFetcherDelegate* delegate) {
55 bool empty_body = body.empty();
56 URLFetcher* result = URLFetcher::Create(
57 0, url,
58 empty_body ? URLFetcher::GET : URLFetcher::POST,
59 delegate);
60
61 result->SetRequestContext(getter);
62 result->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
63 net::LOAD_DO_NOT_SAVE_COOKIES);
64
65 if (!empty_body)
66 result->SetUploadData("application/x-www-form-urlencoded", body);
67 if (!headers.empty())
68 result->SetExtraRequestHeaders(headers);
69
70 return result;
71 }
72 } // namespace
73
74 OAuth2MintTokenFetcher::OAuth2MintTokenFetcher(
75 OAuth2MintTokenConsumer* consumer,
76 URLRequestContextGetter* getter,
77 const std::string& source)
78 : consumer_(consumer),
79 getter_(getter),
80 source_(source),
81 state_(INITIAL) { }
82
83 OAuth2MintTokenFetcher::~OAuth2MintTokenFetcher() { }
84
85 void OAuth2MintTokenFetcher::CancelRequest() {
86 fetcher_.reset();
87 }
88
89 void OAuth2MintTokenFetcher::Start(const std::string& oauth_login_access_token,
90 const std::string& client_id,
91 const std::vector<std::string>& scopes,
92 const std::string& origin) {
93 oauth_login_access_token_ = oauth_login_access_token;
94 client_id_ = client_id;
95 scopes_ = scopes;
96 origin_ = origin;
97 StartMintToken();
98 }
99
100 void OAuth2MintTokenFetcher::StartMintToken() {
101 CHECK_EQ(INITIAL, state_);
102 state_ = MINT_TOKEN_STARTED;
103 fetcher_.reset(CreateFetcher(
104 getter_,
105 MakeMintTokenUrl(),
106 MakeMintTokenHeader(oauth_login_access_token_),
107 MakeMintTokenBody(client_id_, scopes_, origin_),
108 this));
109 fetcher_->Start(); // OnURLFetchComplete will be called.
110 }
111
112 void OAuth2MintTokenFetcher::EndMintToken(const URLFetcher* source) {
113 CHECK_EQ(MINT_TOKEN_STARTED, state_);
114 state_ = MINT_TOKEN_DONE;
115
116 URLRequestStatus status = source->GetStatus();
117 if (!status.is_success()) {
118 OnMintTokenFailure(CreateAuthError(status));
119 return;
120 }
121
122 if (source->GetResponseCode() != net::HTTP_OK) {
123 OnMintTokenFailure(GoogleServiceAuthError(
124 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
125 return;
126 }
127
128 // The request was successfully fetched and it returned OK.
129 // Parse out the access token.
130 std::string access_token;
131 ParseMintTokenResponse(source, &access_token);
132 OnMintTokenSuccess(access_token);
133 }
134
135 void OAuth2MintTokenFetcher::OnMintTokenSuccess(
136 const std::string& access_token) {
137 consumer_->OnMintTokenSuccess(access_token);
138 }
139
140 void OAuth2MintTokenFetcher::OnMintTokenFailure(GoogleServiceAuthError error) {
141 state_ = ERROR_STATE;
142 consumer_->OnMintTokenFailure(error);
143 }
144
145 void OAuth2MintTokenFetcher::OnURLFetchComplete(const URLFetcher* source) {
146 CHECK(source);
147 CHECK_EQ(MINT_TOKEN_STARTED, state_);
148 EndMintToken(source);
149 }
150
151 // static
152 GURL OAuth2MintTokenFetcher::MakeMintTokenUrl() {
153 return GURL(GaiaUrls::GetInstance()->oauth2_issue_token_url());
154 }
155
156 // static
157 std::string OAuth2MintTokenFetcher::MakeMintTokenHeader(
158 const std::string& access_token) {
159 return StringPrintf(kAuthorizationHeaderFormat, access_token.c_str());
160 }
161
162 // static
163 std::string OAuth2MintTokenFetcher::MakeMintTokenBody(
164 const std::string& client_id,
165 const std::vector<std::string>& scopes,
166 const std::string& origin) {
167 return StringPrintf(
168 kOAuth2IssueTokenBodyFormat,
169 net::EscapeUrlEncodedData(JoinString(scopes, ','), true).c_str(),
170 net::EscapeUrlEncodedData(client_id, true).c_str(),
171 net::EscapeUrlEncodedData(origin, true).c_str());
172 }
173
174 // static
175 bool OAuth2MintTokenFetcher::ParseMintTokenResponse(
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 dict->GetString(kAccessTokenKey, access_token);
189 }
OLDNEW
« no previous file with comments | « chrome/common/net/gaia/oauth2_mint_token_fetcher.h ('k') | chrome/common/net/gaia/oauth2_mint_token_fetcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698