Index: components/autofill/core/browser/wallet/real_pan_wallet_client.cc |
diff --git a/components/autofill/core/browser/wallet/real_pan_wallet_client.cc b/components/autofill/core/browser/wallet/real_pan_wallet_client.cc |
index ab6367457dfd78ad6ecdce9394a6ed4bfed84c00..35c6cbd78cfe04a5813bedaad5358012b28266f8 100644 |
--- a/components/autofill/core/browser/wallet/real_pan_wallet_client.cc |
+++ b/components/autofill/core/browser/wallet/real_pan_wallet_client.cc |
@@ -10,6 +10,8 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/strings/stringprintf.h" |
#include "base/values.h" |
+#include "components/autofill/core/browser/credit_card.h" |
+#include "google_apis/gaia/identity_provider.h" |
#include "net/base/escape.h" |
#include "net/http/http_status_code.h" |
#include "net/url_request/url_fetcher.h" |
@@ -28,12 +30,17 @@ const char kUnmaskCardRequestUrl[] = |
"https://wallet.google.com/payments/apis-secure/creditcardservice" |
"/GetRealPan?s7e=cvc"; |
+const char kTokenServiceConsumerId[] = "real_pan_wallet_client"; |
+const char kWalletOAuth2Scope[] = |
+ "https://www.googleapis.com/auth/wallet.chrome"; |
+ |
} // namespace |
RealPanWalletClient::RealPanWalletClient( |
net::URLRequestContextGetter* context_getter, |
Delegate* delegate) |
- : context_getter_(context_getter), |
+ : OAuth2TokenService::Consumer(kTokenServiceConsumerId), |
+ context_getter_(context_getter), |
delegate_(delegate), |
weak_ptr_factory_(this) { |
DCHECK(delegate); |
@@ -42,16 +49,23 @@ RealPanWalletClient::RealPanWalletClient( |
RealPanWalletClient::~RealPanWalletClient() { |
} |
+void RealPanWalletClient::Prepare() { |
+ if (access_token_.empty()) |
+ StartTokenFetch(); |
+} |
+ |
void RealPanWalletClient::UnmaskCard(const CreditCard& card, |
const std::string& cvc) { |
+ DCHECK_EQ(CreditCard::MASKED_SERVER_CARD, card.record_type()); |
+ |
request_.reset(net::URLFetcher::Create( |
0, GURL(kUnmaskCardRequestUrl), net::URLFetcher::POST, this)); |
request_->SetRequestContext(context_getter_.get()); |
base::DictionaryValue request_dict; |
request_dict.SetString("encrypted_cvc", "__param:cvc"); |
- // TODO(estade): get the token from |card|. |
- request_dict.SetString("credit_card_token", "deadbeefee"); |
+ // TODO(estade): is this the correct "token"? |
+ request_dict.SetString("credit_card_token", card.server_id()); |
std::string json_request; |
base::JSONWriter::Write(&request_dict, &json_request); |
std::string post_body = base::StringPrintf(kUnmaskCardRequestFormat, |
@@ -59,9 +73,10 @@ void RealPanWalletClient::UnmaskCard(const CreditCard& card, |
net::EscapeUrlEncodedData(cvc, true).c_str()); |
request_->SetUploadData("application/x-www-form-urlencoded", post_body); |
- request_->AddExtraRequestHeader( |
- "Authorization: " + delegate_->GetOAuth2Token()); |
- request_->Start(); |
+ if (access_token_.empty()) |
+ StartTokenFetch(); |
+ else |
+ SetOAuth2TokenAndStartRequest(); |
} |
void RealPanWalletClient::CancelRequest() { |
@@ -77,6 +92,9 @@ void RealPanWalletClient::OnURLFetchComplete(const net::URLFetcher* source) { |
scoped_ptr<base::DictionaryValue> response_dict; |
int response_code = source->GetResponseCode(); |
+ // TODO(estade): OAuth2 may fail due to an expired access token, in which case |
+ // we should invalidate the token and try again. How is that failure reported? |
+ |
switch (response_code) { |
// Valid response. |
case net::HTTP_OK: { |
@@ -118,5 +136,51 @@ void RealPanWalletClient::OnURLFetchComplete(const net::URLFetcher* source) { |
delegate_->OnDidGetRealPan(real_pan); |
} |
+void RealPanWalletClient::OnGetTokenSuccess( |
+ const OAuth2TokenService::Request* request, |
+ const std::string& access_token, |
+ const base::Time& expiration_time) { |
+ DCHECK_EQ(request, access_token_request_.get()); |
+ access_token_ = access_token; |
+ if (request_) |
+ SetOAuth2TokenAndStartRequest(); |
+ |
+ access_token_request_.reset(); |
+} |
+ |
+void RealPanWalletClient::OnGetTokenFailure( |
+ const OAuth2TokenService::Request* request, |
+ const GoogleServiceAuthError& error) { |
+ DCHECK_EQ(request, access_token_request_.get()); |
+ if (request_) { |
+ request_.reset(); |
+ delegate_->OnDidGetRealPan(std::string()); |
+ } |
+ // TODO(estade): what do we do in the failure case? |
+ NOTIMPLEMENTED(); |
+ |
+ access_token_request_.reset(); |
+} |
+ |
+void RealPanWalletClient::StartTokenFetch() { |
+ // Don't cancel outstanding requests. |
+ if (access_token_request_) |
+ return; |
+ |
+ // However, do clear old tokens. |
+ access_token_.clear(); |
+ |
+ OAuth2TokenService::ScopeSet wallet_scopes; |
+ wallet_scopes.insert(kWalletOAuth2Scope); |
+ IdentityProvider* identity = delegate_->GetIdentityProvider(); |
+ access_token_request_ = identity->GetTokenService()->StartRequest( |
+ identity->GetActiveAccountId(), wallet_scopes, this); |
+} |
+ |
+void RealPanWalletClient::SetOAuth2TokenAndStartRequest() { |
+ request_->AddExtraRequestHeader("Authorization: " + access_token_); |
+ request_->Start(); |
+} |
+ |
} // namespace wallet |
} // namespace autofill |