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

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

Issue 9937004: Create an abstract flow class that abstracts the following logical steps of calling an OAuth2 enabl… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 8 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_api_call_flow.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/basictypes.h"
11 #include "chrome/common/net/gaia/gaia_urls.h"
12 #include "net/base/escape.h"
13 #include "net/base/load_flags.h"
14 #include "net/http/http_status_code.h"
15 #include "net/url_request/url_request_context_getter.h"
16 #include "net/url_request/url_request_status.h"
17
18 using content::URLFetcher;
msw 2012/03/30 23:56:32 The Google C++ style guide discourages use of 'usi
Munjal (Google) 2012/04/04 19:24:38 I thought that using is fine in .cc files. Not in
19 using content::URLFetcherDelegate;
20 using net::ResponseCookies;
21 using net::URLRequestContextGetter;
22 using net::URLRequestStatus;
23
24 OAuth2ApiCallFlow::OAuth2ApiCallFlow(
25 net::URLRequestContextGetter* context,
26 const std::string& refresh_token,
27 const std::string& access_token,
28 const std::vector<std::string>& scopes)
29 : context_(context),
30 refresh_token_(refresh_token),
31 access_token_(access_token),
32 scopes_(scopes),
33 state_(INITIAL),
34 tried_mint_access_token_(false) {
35 }
36
37 OAuth2ApiCallFlow::~OAuth2ApiCallFlow() { }
msw 2012/03/30 23:56:32 The Google C++ style guide says "No spaces inside
Munjal (Google) 2012/04/04 19:24:38 Done.
38
39 void OAuth2ApiCallFlow::Start() {
40 BeginApiCall();
41 }
42
43 void OAuth2ApiCallFlow::BeginApiCall() {
44 CHECK(state_ == INITIAL || state_ == MINT_ACCESS_TOKEN_DONE);
45
46 // If the access token is empty then directly try to mint one.
47 if (access_token_.empty()) {
48 BeginMintAccessToken();
49 return;
msw 2012/03/30 23:56:32 nit: either return here and move the else-case to
Munjal (Google) 2012/04/04 19:24:38 Done.
50 } else {
51 state_ = API_CALL_STARTED;
52
53 url_fetcher_.reset(CreateURLFetcher());
54 url_fetcher_->Start(); // OnURLFetchComplete will be called.
55 }
56 }
57
58 void OAuth2ApiCallFlow::EndApiCall(const URLFetcher* source) {
59 CHECK_EQ(API_CALL_STARTED, state_);
60 state_ = API_CALL_DONE;
61
62 URLRequestStatus status = source->GetStatus();
63 if (!status.is_success()) {
64 ProcessApiCallFailure(source);
msw 2012/03/30 23:56:32 Should you set "state_ = ERROR_STATE;"?
Munjal (Google) 2012/04/04 19:24:38 Done.
65 return;
66 }
67
68 // If the response code is 401 Unauthorized then access token may have
69 // expired. So try generating a new access token.
70 if (source->GetResponseCode() == net::HTTP_UNAUTHORIZED) {
71 // If we already tried minting a new access token, don't do it again.
72 if (tried_mint_access_token_)
73 ProcessApiCallFailure(source);
msw 2012/03/30 23:56:32 Should you set "state_ = ERROR_STATE;"?
Munjal (Google) 2012/04/04 19:24:38 Done.
74 else
75 BeginMintAccessToken();
76
77 return;
78 }
79
80 if (source->GetResponseCode() != net::HTTP_OK) {
81 ProcessApiCallFailure(source);
msw 2012/03/30 23:56:32 Should you set "state_ = ERROR_STATE;"?
Munjal (Google) 2012/04/04 19:24:38 Done.
82 return;
83 }
84
85 ProcessApiCallSuccess(source);
86 }
87
88 void OAuth2ApiCallFlow::BeginMintAccessToken() {
89 CHECK(state_ == INITIAL || state_ == API_CALL_DONE);
90 CHECK(!tried_mint_access_token_);
91 state_ = MINT_ACCESS_TOKEN_STARTED;
92 tried_mint_access_token_ = true;
93
94 oauth2_access_token_fetcher_.reset(CreateAccessTokenFetcher());
95 oauth2_access_token_fetcher_->Start(
96 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
97 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
98 refresh_token_,
99 scopes_);
100 }
101
102 void OAuth2ApiCallFlow::EndMintAccessToken(
103 const GoogleServiceAuthError* error) {
104 CHECK_EQ(MINT_ACCESS_TOKEN_STARTED, state_);
105
106 if (!error) {
107 state_ = MINT_ACCESS_TOKEN_DONE;
108 BeginApiCall();
109 } else {
110 state_ = ERROR_STATE;
111 ProcessMintAccessTokenFailure(*error);
112 }
113 }
114
115 OAuth2AccessTokenFetcher* OAuth2ApiCallFlow::CreateAccessTokenFetcher() {
116 return new OAuth2AccessTokenFetcher(this, context_);
117 }
118
119 void OAuth2ApiCallFlow::OnURLFetchComplete(const URLFetcher* source) {
120 CHECK(source);
121 CHECK_EQ(API_CALL_STARTED, state_);
122 EndApiCall(source);
123 }
124
125 void OAuth2ApiCallFlow::OnGetTokenSuccess(const std::string& access_token) {
126 access_token_ = access_token;
127 EndMintAccessToken(NULL);
128 }
129
130 void OAuth2ApiCallFlow::OnGetTokenFailure(
131 const GoogleServiceAuthError& error) {
132 EndMintAccessToken(&error);
133 }
134
135 URLFetcher* OAuth2ApiCallFlow::CreateURLFetcher() {
136 std::string body = CreateApiCallBody();
137 bool empty_body = body.empty();
138 URLFetcher* result = URLFetcher::Create(
139 0,
140 CreateApiCallUrl(),
141 empty_body ? URLFetcher::GET : URLFetcher::POST,
142 this);
143
144 result->SetRequestContext(context_);
145 result->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
146 net::LOAD_DO_NOT_SAVE_COOKIES);
147
148 if (!empty_body)
149 result->SetUploadData("application/x-www-form-urlencoded", body);
150
151 return result;
152 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698