| 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
|
|
|