Index: chrome/common/net/gaia/oauth2_api_call_flow.cc |
=================================================================== |
--- chrome/common/net/gaia/oauth2_api_call_flow.cc (revision 0) |
+++ chrome/common/net/gaia/oauth2_api_call_flow.cc (revision 0) |
@@ -0,0 +1,152 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/common/net/gaia/oauth2_api_call_flow.h" |
+ |
+#include <string> |
+#include <vector> |
+ |
+#include "base/basictypes.h" |
+#include "chrome/common/net/gaia/gaia_urls.h" |
+#include "net/base/escape.h" |
+#include "net/base/load_flags.h" |
+#include "net/http/http_status_code.h" |
+#include "net/url_request/url_request_context_getter.h" |
+#include "net/url_request/url_request_status.h" |
+ |
+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
|
+using content::URLFetcherDelegate; |
+using net::ResponseCookies; |
+using net::URLRequestContextGetter; |
+using net::URLRequestStatus; |
+ |
+OAuth2ApiCallFlow::OAuth2ApiCallFlow( |
+ net::URLRequestContextGetter* context, |
+ const std::string& refresh_token, |
+ const std::string& access_token, |
+ const std::vector<std::string>& scopes) |
+ : context_(context), |
+ refresh_token_(refresh_token), |
+ access_token_(access_token), |
+ scopes_(scopes), |
+ state_(INITIAL), |
+ tried_mint_access_token_(false) { |
+} |
+ |
+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.
|
+ |
+void OAuth2ApiCallFlow::Start() { |
+ BeginApiCall(); |
+} |
+ |
+void OAuth2ApiCallFlow::BeginApiCall() { |
+ CHECK(state_ == INITIAL || state_ == MINT_ACCESS_TOKEN_DONE); |
+ |
+ // If the access token is empty then directly try to mint one. |
+ if (access_token_.empty()) { |
+ BeginMintAccessToken(); |
+ 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.
|
+ } else { |
+ state_ = API_CALL_STARTED; |
+ |
+ url_fetcher_.reset(CreateURLFetcher()); |
+ url_fetcher_->Start(); // OnURLFetchComplete will be called. |
+ } |
+} |
+ |
+void OAuth2ApiCallFlow::EndApiCall(const URLFetcher* source) { |
+ CHECK_EQ(API_CALL_STARTED, state_); |
+ state_ = API_CALL_DONE; |
+ |
+ URLRequestStatus status = source->GetStatus(); |
+ if (!status.is_success()) { |
+ ProcessApiCallFailure(source); |
msw
2012/03/30 23:56:32
Should you set "state_ = ERROR_STATE;"?
Munjal (Google)
2012/04/04 19:24:38
Done.
|
+ return; |
+ } |
+ |
+ // If the response code is 401 Unauthorized then access token may have |
+ // expired. So try generating a new access token. |
+ if (source->GetResponseCode() == net::HTTP_UNAUTHORIZED) { |
+ // If we already tried minting a new access token, don't do it again. |
+ if (tried_mint_access_token_) |
+ ProcessApiCallFailure(source); |
msw
2012/03/30 23:56:32
Should you set "state_ = ERROR_STATE;"?
Munjal (Google)
2012/04/04 19:24:38
Done.
|
+ else |
+ BeginMintAccessToken(); |
+ |
+ return; |
+ } |
+ |
+ if (source->GetResponseCode() != net::HTTP_OK) { |
+ ProcessApiCallFailure(source); |
msw
2012/03/30 23:56:32
Should you set "state_ = ERROR_STATE;"?
Munjal (Google)
2012/04/04 19:24:38
Done.
|
+ return; |
+ } |
+ |
+ ProcessApiCallSuccess(source); |
+} |
+ |
+void OAuth2ApiCallFlow::BeginMintAccessToken() { |
+ CHECK(state_ == INITIAL || state_ == API_CALL_DONE); |
+ CHECK(!tried_mint_access_token_); |
+ state_ = MINT_ACCESS_TOKEN_STARTED; |
+ tried_mint_access_token_ = true; |
+ |
+ oauth2_access_token_fetcher_.reset(CreateAccessTokenFetcher()); |
+ oauth2_access_token_fetcher_->Start( |
+ GaiaUrls::GetInstance()->oauth2_chrome_client_id(), |
+ GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), |
+ refresh_token_, |
+ scopes_); |
+} |
+ |
+void OAuth2ApiCallFlow::EndMintAccessToken( |
+ const GoogleServiceAuthError* error) { |
+ CHECK_EQ(MINT_ACCESS_TOKEN_STARTED, state_); |
+ |
+ if (!error) { |
+ state_ = MINT_ACCESS_TOKEN_DONE; |
+ BeginApiCall(); |
+ } else { |
+ state_ = ERROR_STATE; |
+ ProcessMintAccessTokenFailure(*error); |
+ } |
+} |
+ |
+OAuth2AccessTokenFetcher* OAuth2ApiCallFlow::CreateAccessTokenFetcher() { |
+ return new OAuth2AccessTokenFetcher(this, context_); |
+} |
+ |
+void OAuth2ApiCallFlow::OnURLFetchComplete(const URLFetcher* source) { |
+ CHECK(source); |
+ CHECK_EQ(API_CALL_STARTED, state_); |
+ EndApiCall(source); |
+} |
+ |
+void OAuth2ApiCallFlow::OnGetTokenSuccess(const std::string& access_token) { |
+ access_token_ = access_token; |
+ EndMintAccessToken(NULL); |
+} |
+ |
+void OAuth2ApiCallFlow::OnGetTokenFailure( |
+ const GoogleServiceAuthError& error) { |
+ EndMintAccessToken(&error); |
+} |
+ |
+URLFetcher* OAuth2ApiCallFlow::CreateURLFetcher() { |
+ std::string body = CreateApiCallBody(); |
+ bool empty_body = body.empty(); |
+ URLFetcher* result = URLFetcher::Create( |
+ 0, |
+ CreateApiCallUrl(), |
+ empty_body ? URLFetcher::GET : URLFetcher::POST, |
+ this); |
+ |
+ result->SetRequestContext(context_); |
+ result->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
+ net::LOAD_DO_NOT_SAVE_COOKIES); |
+ |
+ if (!empty_body) |
+ result->SetUploadData("application/x-www-form-urlencoded", body); |
+ |
+ return result; |
+} |