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

Side by Side Diff: chrome/browser/autofill/wallet/wallet_client.cc

Issue 11293078: Integrating Online Wallet into Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing HexStringToInt Created 8 years 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/browser/autofill/wallet/wallet_client.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/string_number_conversions.h"
12 #include "base/string_split.h"
13 #include "base/stringprintf.h"
14 #include "base/values.h"
15 #include "chrome/browser/autofill/wallet/cart.h"
16 #include "chrome/browser/autofill/wallet/full_wallet.h"
17 #include "chrome/browser/autofill/wallet/wallet_address.h"
18 #include "chrome/browser/autofill/wallet/wallet_items.h"
19 #include "chrome/browser/autofill/wallet/wallet_service_url.h"
20 #include "googleurl/src/gurl.h"
21 #include "net/http/http_status_code.h"
22 #include "net/url_request/url_fetcher.h"
23 #include "net/url_request/url_request_context_getter.h"
24
25 namespace {
26
27 const char kEncryptOtpBodyFormat[] = "cvv=%s:%s";
28 const char kJsonMimeType[] = "application/json";
29 const char kApplicationMimeType[] = "application/x-www-form-urlencoded";
30 const size_t kMaxBits = 63;
31
32 } // anonymous namespace
33
34 namespace wallet {
35
36 void WalletClient::AcceptLegalDocuments(
37 const std::vector<std::string>& document_ids,
38 const std::string& google_transaction_id,
39 WalletClient::WalletClientObserver* observer) {
40 DCHECK_EQ(request_type_, NO_PENDING_REQUEST);
41
42 request_type_ = ACCEPT_LEGAL_DOCUMENTS;
43
44 DictionaryValue request_dict;
45 request_dict.SetString("api_key", wallet::kApiKey);
46 request_dict.SetString("google_transaction_id", google_transaction_id);
47 ListValue* docs_list = new ListValue();
48 for (std::vector<std::string>::const_iterator it = document_ids.begin();
49 it != document_ids.end();
50 ++it) {
51 docs_list->AppendString(*it);
52 }
53 request_dict.Set("accepted_legal_document", docs_list);
54
55 std::string post_body;
56 base::JSONWriter::Write(&request_dict, &post_body);
57
58 MakeWalletRequest(GetAcceptLegalDocumentsUrl(),
59 post_body,
60 observer,
61 kJsonMimeType);
62 }
63
64 void WalletClient::EncryptOtp(
65 const void* otp,
66 size_t length,
67 WalletClient::WalletClientObserver* observer) {
68 DCHECK_EQ(request_type_, NO_PENDING_REQUEST);
69 size_t num_bits = length * 8;
70 DCHECK_LT(num_bits, kMaxBits);
71
72 request_type_ = ENCRYPT_OTP;
73
74 std::string post_body = StringPrintf(kEncryptOtpBodyFormat,
75 base::HexEncode(&num_bits, 1).c_str(),
76 base::HexEncode(otp, length).c_str());
77
78 MakeWalletRequest(GetSecureUrl(), post_body, observer, kApplicationMimeType);
79 }
80
81 void WalletClient::GetFullWallet(
82 const std::string& instrument_id,
83 const std::string& address_id,
84 const std::string& merchant_domain,
85 const Cart& cart,
86 const std::string& google_transaction_id,
87 const std::string& encrypted_otp,
88 const std::string& session_material,
89 WalletClient::WalletClientObserver* observer) {
90 DCHECK_EQ(request_type_, NO_PENDING_REQUEST);
91
92 request_type_ = GET_FULL_WALLET;
93
94 DictionaryValue request_dict;
95 request_dict.SetString("api_key", wallet::kApiKey);
96 request_dict.SetString("risk_params", GetRiskParams());
97 request_dict.SetString("selected_instrument_id", instrument_id);
98 request_dict.SetString("selected_address_id", address_id);
99 request_dict.SetString("merchant_domain", merchant_domain);
100 request_dict.SetString("google_transaction_id", google_transaction_id);
101 request_dict.Set("cart", cart.ToDictionary().release());
102 request_dict.SetString("encrypted_otp", encrypted_otp);
103 request_dict.SetString("session_material", session_material);
104
105 std::string post_body;
106 base::JSONWriter::Write(&request_dict, &post_body);
107
108 MakeWalletRequest(GetGetFullWalletUrl(), post_body, observer, kJsonMimeType);
109 }
110
111 void WalletClient::GetWalletItems(
112 WalletClient::WalletClientObserver* observer) {
113 DCHECK_EQ(request_type_, NO_PENDING_REQUEST);
114
115 request_type_ = GET_WALLET_ITEMS;
116
117 DictionaryValue request_dict;
118 request_dict.SetString("api_key", wallet::kApiKey);
119 request_dict.SetString("risk_params", GetRiskParams());
120
121 std::string post_body;
122 base::JSONWriter::Write(&request_dict, &post_body);
123
124 MakeWalletRequest(GetGetWalletItemsUrl(), post_body, observer, kJsonMimeType);
125 }
126
127 void WalletClient::SendExtendedAutofillStatus(
128 bool success,
129 const std::string& merchant_domain,
130 const std::string& reason,
131 const std::string& google_transaction_id,
132 WalletClient::WalletClientObserver* observer) {
133 DCHECK_EQ(request_type_, NO_PENDING_REQUEST);
134
135 request_type_ = SEND_STATUS;
136
137 DictionaryValue request_dict;
138 request_dict.SetString("api_key", wallet::kApiKey);
139 request_dict.SetBoolean("success", success);
140 request_dict.SetString("hostname", merchant_domain);
141 if (!success) {
142 // TODO(ahutter): Probably want to do some checks on reason.
143 request_dict.SetString("reason", reason);
144 }
145 request_dict.SetString("google_transaction_id", google_transaction_id);
146
147 std::string post_body;
148 base::JSONWriter::Write(&request_dict, &post_body);
149
150 MakeWalletRequest(GetSendStatusUrl(), post_body, observer, kJsonMimeType);
151 }
152
153 void WalletClient::MakeWalletRequest(
154 const GURL& url,
155 const std::string& post_body,
156 WalletClient::WalletClientObserver* observer,
157 const std::string& content_type) {
158 DCHECK(!request_.get()) << "Tried to fetch two things at once!";
159 DCHECK(observer);
160
161 observer_ = observer;
162
163 request_.reset(net::URLFetcher::Create(
164 0, url, net::URLFetcher::POST, this));
165 request_->SetRequestContext(context_getter_);
166 DVLOG(1) << "Request body: " << post_body;
167 request_->SetUploadData(content_type, post_body);
168 request_->Start();
169 }
170
171 // TODO(ahutter): Add manual retry logic if it's necessary.
172 void WalletClient::OnURLFetchComplete(
173 const net::URLFetcher* source) {
174 scoped_ptr<net::URLFetcher> old_request = request_.Pass();
175 DCHECK_EQ(source, old_request.get());
176
177 DVLOG(1) << "Got response from " << source->GetOriginalURL();
178
179 std::string data;
180 scoped_ptr<DictionaryValue> response_dict;
181 int response_code = source->GetResponseCode();
182 switch (response_code) {
183 // HTTP_BAD_REQUEST means the arguments are invalid. No point retrying.
184 case net::HTTP_BAD_REQUEST: {
185 request_type_ = NO_PENDING_REQUEST;
186 observer_->OnWalletError();
187 return;
188 }
189 // HTTP_OK holds a valid response and HTTP_INTERNAL_SERVER_ERROR holds an
190 // error code and message for the user.
191 case net::HTTP_OK:
192 case net::HTTP_INTERNAL_SERVER_ERROR: {
193 source->GetResponseAsString(&data);
194 DVLOG(1) << "Response body: " << data;
195 scoped_ptr<Value> message_value(base::JSONReader::Read(data));
196 if (message_value.get() &&
197 message_value->IsType(Value::TYPE_DICTIONARY)) {
198 response_dict.reset(
199 static_cast<DictionaryValue*>(message_value.release()));
200 }
201 if (response_code == net::HTTP_INTERNAL_SERVER_ERROR) {
202 request_type_ = NO_PENDING_REQUEST;
203 // TODO(ahutter): Do something with the response. See
204 // http://crbug.com/164410.
205 observer_->OnWalletError();
206 return;
207 }
208 break;
209 }
210 // Anything else is an error.
211 default: {
212 request_type_ = NO_PENDING_REQUEST;
213 observer_->OnNetworkError(response_code);
214 return;
215 }
216 }
217
218 RequestType type = request_type_;
219 request_type_ = NO_PENDING_REQUEST;
220
221 switch (type) {
222 case ACCEPT_LEGAL_DOCUMENTS: {
223 observer_->OnAcceptLegalDocuments();
224 break;
225 }
226 case SEND_STATUS: {
227 observer_->OnSendExtendedAutofillStatus();
228 break;
229 }
230 case ENCRYPT_OTP: {
231 if (!data.empty()) {
232 std::vector<std::string> splits;
233 base::SplitString(data, '|', &splits);
234 if (splits.size() == 2)
235 observer_->OnEncryptOtp(splits[1], splits[0]);
236 else
237 observer_->OnNetworkError(response_code);
238 } else {
239 observer_->OnWalletError();
240 }
241 break;
242 }
243 case GET_FULL_WALLET: {
244 if (response_dict.get()) {
245 scoped_ptr<FullWallet> full_wallet(
246 FullWallet::CreateFullWallet(*response_dict));
247 if (full_wallet.get())
248 observer_->OnGetFullWallet(full_wallet.release());
249 else
250 observer_->OnNetworkError(response_code);
251 } else {
252 observer_->OnWalletError();
253 }
254 break;
255 }
256 case GET_WALLET_ITEMS: {
257 if (response_dict.get()) {
258 scoped_ptr<WalletItems> wallet_items(
259 WalletItems::CreateWalletItems(*response_dict));
260 if (wallet_items.get())
261 observer_->OnGetWalletItems(wallet_items.release());
262 else
263 observer_->OnNetworkError(response_code);
264 } else {
265 observer_->OnWalletError();
266 }
267 break;
268 }
269 default: {
270 NOTREACHED();
271 }
272 }
273 }
274
275 WalletClient::WalletClient(net::URLRequestContextGetter* context_getter)
276 : context_getter_(context_getter),
277 observer_(NULL),
278 request_type_(NO_PENDING_REQUEST) {
279 DCHECK(context_getter);
280 }
281
282 WalletClient::~WalletClient() {}
283
284 } // namespace wallet
285
OLDNEW
« no previous file with comments | « chrome/browser/autofill/wallet/wallet_client.h ('k') | chrome/browser/autofill/wallet/wallet_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698