1649d2ec818ad8cdb4484fc4d633c8126b8784f0
[WebKit-https.git] / Source / WebKit / Shared / Cocoa / WebCoreArgumentCodersCocoa.mm
1 /*
2  * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "WebCoreArgumentCoders.h"
28
29 #if ENABLE(APPLE_PAY)
30
31 #import "DataReference.h"
32 #import <WebCore/PaymentAuthorizationStatus.h>
33 #import <pal/cocoa/PassKitSoftLink.h>
34 #import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
35
36 namespace IPC {
37 using namespace WebCore;
38
39 void ArgumentCoder<WebCore::Payment>::encode(Encoder& encoder, const WebCore::Payment& payment)
40 {
41     auto archiver = secureArchiver();
42     [archiver encodeObject:payment.pkPayment() forKey:NSKeyedArchiveRootObjectKey];
43     [archiver finishEncoding];
44
45     auto data = archiver.get().encodedData;
46     encoder << DataReference(static_cast<const uint8_t*>([data bytes]), [data length]);
47 }
48
49 bool ArgumentCoder<WebCore::Payment>::decode(Decoder& decoder, WebCore::Payment& payment)
50 {
51     IPC::DataReference dataReference;
52     if (!decoder.decode(dataReference))
53         return false;
54
55     auto data = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(dataReference.data())) length:dataReference.size() freeWhenDone:NO]);
56     auto unarchiver = secureUnarchiverFromData(data.get());
57     @try {
58         PKPayment *pkPayment = [unarchiver decodeObjectOfClass:PAL::getPKPaymentClass() forKey:NSKeyedArchiveRootObjectKey];
59         payment = Payment(pkPayment);
60     } @catch (NSException *exception) {
61         LOG_ERROR("Failed to decode PKPayment: %@", exception);
62         return false;
63     }
64
65     [unarchiver finishDecoding];
66     return true;
67 }
68
69 void ArgumentCoder<WebCore::PaymentAuthorizationResult>::encode(Encoder& encoder, const WebCore::PaymentAuthorizationResult& result)
70 {
71     encoder << result.status;
72     encoder << result.errors;
73 }
74
75 std::optional<WebCore::PaymentAuthorizationResult> ArgumentCoder<WebCore::PaymentAuthorizationResult>::decode(Decoder& decoder)
76 {
77     std::optional<PaymentAuthorizationStatus> status;
78     decoder >> status;
79     if (!status)
80         return std::nullopt;
81
82     std::optional<Vector<PaymentError>> errors;
83     decoder >> errors;
84     if (!errors)
85         return std::nullopt;
86     
87     return {{ WTFMove(*status), WTFMove(*errors) }};
88 }
89
90 void ArgumentCoder<WebCore::PaymentContact>::encode(Encoder& encoder, const WebCore::PaymentContact& paymentContact)
91 {
92     auto archiver = secureArchiver();
93     [archiver encodeObject:paymentContact.pkContact() forKey:NSKeyedArchiveRootObjectKey];
94     [archiver finishEncoding];
95
96     auto data = archiver.get().encodedData;
97     encoder << DataReference(static_cast<const uint8_t*>([data bytes]), [data length]);
98 }
99
100 bool ArgumentCoder<WebCore::PaymentContact>::decode(Decoder& decoder, WebCore::PaymentContact& paymentContact)
101 {
102     IPC::DataReference dataReference;
103     if (!decoder.decode(dataReference))
104         return false;
105
106     auto data = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(dataReference.data())) length:dataReference.size() freeWhenDone:NO]);
107     auto unarchiver = secureUnarchiverFromData(data.get());
108     @try {
109         PKContact *pkContact = [unarchiver decodeObjectOfClass:PAL::getPKContactClass() forKey:NSKeyedArchiveRootObjectKey];
110         paymentContact = PaymentContact(pkContact);
111     } @catch (NSException *exception) {
112         LOG_ERROR("Failed to decode PKContact: %@", exception);
113         return false;
114     }
115
116     [unarchiver finishDecoding];
117     return true;
118 }
119
120 void ArgumentCoder<WebCore::PaymentError>::encode(Encoder& encoder, const WebCore::PaymentError& error)
121 {
122     encoder << error.code;
123     encoder << error.message;
124     encoder << error.contactField;
125 }
126
127 std::optional<WebCore::PaymentError> ArgumentCoder<WebCore::PaymentError>::decode(Decoder& decoder)
128 {
129     std::optional<WebCore::PaymentError::Code> code;
130     decoder >> code;
131     if (!code)
132         return std::nullopt;
133     
134     std::optional<String> message;
135     decoder >> message;
136     if (!message)
137         return std::nullopt;
138     
139     std::optional<std::optional<WebCore::PaymentError::ContactField>> contactField;
140     decoder >> contactField;
141     if (!contactField)
142         return std::nullopt;
143
144     return {{ WTFMove(*code), WTFMove(*message), WTFMove(*contactField) }};
145 }
146
147 void ArgumentCoder<WebCore::PaymentMerchantSession>::encode(Encoder& encoder, const WebCore::PaymentMerchantSession& paymentMerchantSession)
148 {
149     auto archiver = secureArchiver();
150     [archiver encodeObject:paymentMerchantSession.pkPaymentMerchantSession() forKey:NSKeyedArchiveRootObjectKey];
151     [archiver finishEncoding];
152
153     auto data = archiver.get().encodedData;
154     encoder << DataReference(static_cast<const uint8_t*>([data bytes]), [data length]);
155 }
156
157 bool ArgumentCoder<WebCore::PaymentMerchantSession>::decode(Decoder& decoder, WebCore::PaymentMerchantSession& paymentMerchantSession)
158 {
159     IPC::DataReference dataReference;
160     if (!decoder.decode(dataReference))
161         return false;
162
163     auto data = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(dataReference.data())) length:dataReference.size() freeWhenDone:NO]);
164     auto unarchiver = secureUnarchiverFromData(data.get());
165     @try {
166         PKPaymentMerchantSession *pkPaymentMerchantSession = [unarchiver decodeObjectOfClass:PAL::getPKPaymentMerchantSessionClass() forKey:NSKeyedArchiveRootObjectKey];
167         paymentMerchantSession = PaymentMerchantSession(pkPaymentMerchantSession);
168     } @catch (NSException *exception) {
169         LOG_ERROR("Failed to decode PKPaymentMerchantSession: %@", exception);
170         return false;
171     }
172
173     [unarchiver finishDecoding];
174     return true;
175 }
176
177 void ArgumentCoder<WebCore::PaymentMethod>::encode(Encoder& encoder, const WebCore::PaymentMethod& paymentMethod)
178 {
179     auto archiver = secureArchiver();
180     [archiver encodeObject:paymentMethod.pkPaymentMethod() forKey:NSKeyedArchiveRootObjectKey];
181     [archiver finishEncoding];
182
183     auto data = archiver.get().encodedData;
184     encoder << DataReference(static_cast<const uint8_t*>([data bytes]), [data length]);
185 }
186
187 bool ArgumentCoder<WebCore::PaymentMethod>::decode(Decoder& decoder, WebCore::PaymentMethod& paymentMethod)
188 {
189     IPC::DataReference dataReference;
190     if (!decoder.decode(dataReference))
191         return false;
192
193     auto data = adoptNS([[NSData alloc] initWithBytesNoCopy:const_cast<void*>(static_cast<const void*>(dataReference.data())) length:dataReference.size() freeWhenDone:NO]);
194     auto unarchiver = secureUnarchiverFromData(data.get());
195     @try {
196         PKPaymentMethod *pkPaymentMethod = [unarchiver decodeObjectOfClass:PAL::getPKPaymentMethodClass() forKey:NSKeyedArchiveRootObjectKey];
197         paymentMethod = PaymentMethod(pkPaymentMethod);
198     } @catch (NSException *exception) {
199         LOG_ERROR("Failed to decode PKPayment: %@", exception);
200         return false;
201     }
202
203     [unarchiver finishDecoding];
204     return true;
205 }
206
207 void ArgumentCoder<WebCore::PaymentMethodUpdate>::encode(Encoder& encoder, const WebCore::PaymentMethodUpdate& update)
208 {
209     encoder << update.newTotalAndLineItems;
210 }
211
212 std::optional<WebCore::PaymentMethodUpdate> ArgumentCoder<WebCore::PaymentMethodUpdate>::decode(Decoder& decoder)
213 {
214     std::optional<ApplePaySessionPaymentRequest::TotalAndLineItems> newTotalAndLineItems;
215     decoder >> newTotalAndLineItems;
216     if (!newTotalAndLineItems)
217         return std::nullopt;
218     return {{ WTFMove(*newTotalAndLineItems) }};
219 }
220
221 void ArgumentCoder<ApplePaySessionPaymentRequest>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest& request)
222 {
223     encoder << request.countryCode();
224     encoder << request.currencyCode();
225     encoder << request.requiredBillingContactFields();
226     encoder << request.billingContact();
227     encoder << request.requiredShippingContactFields();
228     encoder << request.shippingContact();
229     encoder << request.merchantCapabilities();
230     encoder << request.supportedNetworks();
231     encoder.encodeEnum(request.shippingType());
232     encoder << request.shippingMethods();
233     encoder << request.lineItems();
234     encoder << request.total();
235     encoder << request.applicationData();
236     encoder << request.supportedCountries();
237     encoder.encodeEnum(request.requester());
238 }
239
240 bool ArgumentCoder<ApplePaySessionPaymentRequest>::decode(Decoder& decoder, ApplePaySessionPaymentRequest& request)
241 {
242     String countryCode;
243     if (!decoder.decode(countryCode))
244         return false;
245     request.setCountryCode(countryCode);
246
247     String currencyCode;
248     if (!decoder.decode(currencyCode))
249         return false;
250     request.setCurrencyCode(currencyCode);
251
252     ApplePaySessionPaymentRequest::ContactFields requiredBillingContactFields;
253     if (!decoder.decode((requiredBillingContactFields)))
254         return false;
255     request.setRequiredBillingContactFields(requiredBillingContactFields);
256
257     PaymentContact billingContact;
258     if (!decoder.decode(billingContact))
259         return false;
260     request.setBillingContact(billingContact);
261
262     ApplePaySessionPaymentRequest::ContactFields requiredShippingContactFields;
263     if (!decoder.decode((requiredShippingContactFields)))
264         return false;
265     request.setRequiredShippingContactFields(requiredShippingContactFields);
266
267     PaymentContact shippingContact;
268     if (!decoder.decode(shippingContact))
269         return false;
270     request.setShippingContact(shippingContact);
271
272     ApplePaySessionPaymentRequest::MerchantCapabilities merchantCapabilities;
273     if (!decoder.decode(merchantCapabilities))
274         return false;
275     request.setMerchantCapabilities(merchantCapabilities);
276
277     Vector<String> supportedNetworks;
278     if (!decoder.decode(supportedNetworks))
279         return false;
280     request.setSupportedNetworks(supportedNetworks);
281
282     ApplePaySessionPaymentRequest::ShippingType shippingType;
283     if (!decoder.decodeEnum(shippingType))
284         return false;
285     request.setShippingType(shippingType);
286
287     Vector<ApplePaySessionPaymentRequest::ShippingMethod> shippingMethods;
288     if (!decoder.decode(shippingMethods))
289         return false;
290     request.setShippingMethods(shippingMethods);
291
292     Vector<ApplePaySessionPaymentRequest::LineItem> lineItems;
293     if (!decoder.decode(lineItems))
294         return false;
295     request.setLineItems(lineItems);
296
297     std::optional<ApplePaySessionPaymentRequest::LineItem> total;
298     decoder >> total;
299     if (!total)
300         return false;
301     request.setTotal(*total);
302
303     String applicationData;
304     if (!decoder.decode(applicationData))
305         return false;
306     request.setApplicationData(applicationData);
307
308     Vector<String> supportedCountries;
309     if (!decoder.decode(supportedCountries))
310         return false;
311     request.setSupportedCountries(WTFMove(supportedCountries));
312
313     ApplePaySessionPaymentRequest::Requester requester;
314     if (!decoder.decodeEnum(requester))
315         return false;
316     request.setRequester(requester);
317
318     return true;
319 }
320
321 void ArgumentCoder<ApplePaySessionPaymentRequest::ContactFields>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::ContactFields& contactFields)
322 {
323     encoder << contactFields.postalAddress;
324     encoder << contactFields.phone;
325     encoder << contactFields.email;
326     encoder << contactFields.name;
327     encoder << contactFields.phoneticName;
328 }
329
330 bool ArgumentCoder<ApplePaySessionPaymentRequest::ContactFields>::decode(Decoder& decoder, ApplePaySessionPaymentRequest::ContactFields& contactFields)
331 {
332     if (!decoder.decode(contactFields.postalAddress))
333         return false;
334     if (!decoder.decode(contactFields.phone))
335         return false;
336     if (!decoder.decode(contactFields.email))
337         return false;
338     if (!decoder.decode(contactFields.name))
339         return false;
340     if (!decoder.decode(contactFields.phoneticName))
341         return false;
342
343     return true;
344 }
345
346 void ArgumentCoder<ApplePaySessionPaymentRequest::LineItem>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::LineItem& lineItem)
347 {
348     encoder.encodeEnum(lineItem.type);
349     encoder << lineItem.label;
350     encoder << lineItem.amount;
351 }
352
353 std::optional<ApplePaySessionPaymentRequest::LineItem> ArgumentCoder<ApplePaySessionPaymentRequest::LineItem>::decode(Decoder& decoder)
354 {
355     WebCore::ApplePaySessionPaymentRequest::LineItem lineItem;
356     if (!decoder.decodeEnum(lineItem.type))
357         return std::nullopt;
358     if (!decoder.decode(lineItem.label))
359         return std::nullopt;
360     if (!decoder.decode(lineItem.amount))
361         return std::nullopt;
362
363     return WTFMove(lineItem);
364 }
365
366 void ArgumentCoder<ApplePaySessionPaymentRequest::MerchantCapabilities>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::MerchantCapabilities& merchantCapabilities)
367 {
368     encoder << merchantCapabilities.supports3DS;
369     encoder << merchantCapabilities.supportsEMV;
370     encoder << merchantCapabilities.supportsCredit;
371     encoder << merchantCapabilities.supportsDebit;
372 }
373
374 bool ArgumentCoder<ApplePaySessionPaymentRequest::MerchantCapabilities>::decode(Decoder& decoder, ApplePaySessionPaymentRequest::MerchantCapabilities& merchantCapabilities)
375 {
376     if (!decoder.decode(merchantCapabilities.supports3DS))
377         return false;
378     if (!decoder.decode(merchantCapabilities.supportsEMV))
379         return false;
380     if (!decoder.decode(merchantCapabilities.supportsCredit))
381         return false;
382     if (!decoder.decode(merchantCapabilities.supportsDebit))
383         return false;
384
385     return true;
386 }
387
388 void ArgumentCoder<ApplePaySessionPaymentRequest::ShippingMethod>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::ShippingMethod& shippingMethod)
389 {
390     encoder << shippingMethod.label;
391     encoder << shippingMethod.detail;
392     encoder << shippingMethod.amount;
393     encoder << shippingMethod.identifier;
394 }
395
396 std::optional<ApplePaySessionPaymentRequest::ShippingMethod> ArgumentCoder<ApplePaySessionPaymentRequest::ShippingMethod>::decode(Decoder& decoder)
397 {
398     ApplePaySessionPaymentRequest::ShippingMethod shippingMethod;
399     if (!decoder.decode(shippingMethod.label))
400         return std::nullopt;
401     if (!decoder.decode(shippingMethod.detail))
402         return std::nullopt;
403     if (!decoder.decode(shippingMethod.amount))
404         return std::nullopt;
405     if (!decoder.decode(shippingMethod.identifier))
406         return std::nullopt;
407     return WTFMove(shippingMethod);
408 }
409
410 void ArgumentCoder<ApplePaySessionPaymentRequest::TotalAndLineItems>::encode(Encoder& encoder, const ApplePaySessionPaymentRequest::TotalAndLineItems& totalAndLineItems)
411 {
412     encoder << totalAndLineItems.total;
413     encoder << totalAndLineItems.lineItems;
414 }
415
416 std::optional<ApplePaySessionPaymentRequest::TotalAndLineItems> ArgumentCoder<ApplePaySessionPaymentRequest::TotalAndLineItems>::decode(Decoder& decoder)
417 {
418     std::optional<ApplePaySessionPaymentRequest::LineItem> total;
419     decoder >> total;
420     if (!total)
421         return std::nullopt;
422     
423     std::optional<Vector<ApplePaySessionPaymentRequest::LineItem>> lineItems;
424     decoder >> lineItems;
425     if (!lineItems)
426         return std::nullopt;
427     
428     return {{ WTFMove(*total), WTFMove(*lineItems) }};
429 }
430
431 void ArgumentCoder<WebCore::ShippingContactUpdate>::encode(Encoder& encoder, const WebCore::ShippingContactUpdate& update)
432 {
433     encoder << update.errors;
434     encoder << update.newShippingMethods;
435     encoder << update.newTotalAndLineItems;
436 }
437
438 std::optional<WebCore::ShippingContactUpdate> ArgumentCoder<WebCore::ShippingContactUpdate>::decode(Decoder& decoder)
439 {
440     std::optional<Vector<PaymentError>> errors;
441     decoder >> errors;
442     if (!errors)
443         return std::nullopt;
444     
445     std::optional<Vector<ApplePaySessionPaymentRequest::ShippingMethod>> newShippingMethods;
446     decoder >> newShippingMethods;
447     if (!newShippingMethods)
448         return std::nullopt;
449     
450     std::optional<ApplePaySessionPaymentRequest::TotalAndLineItems> newTotalAndLineItems;
451     decoder >> newTotalAndLineItems;
452     if (!newTotalAndLineItems)
453         return std::nullopt;
454     
455     return {{ WTFMove(*errors), WTFMove(*newShippingMethods), WTFMove(*newTotalAndLineItems) }};
456 }
457
458 void ArgumentCoder<WebCore::ShippingMethodUpdate>::encode(Encoder& encoder, const WebCore::ShippingMethodUpdate& update)
459 {
460     encoder << update.newTotalAndLineItems;
461 }
462
463 std::optional<WebCore::ShippingMethodUpdate> ArgumentCoder<WebCore::ShippingMethodUpdate>::decode(Decoder& decoder)
464 {
465     std::optional<ApplePaySessionPaymentRequest::TotalAndLineItems> newTotalAndLineItems;
466     decoder >> newTotalAndLineItems;
467     if (!newTotalAndLineItems)
468         return std::nullopt;
469     return {{ WTFMove(*newTotalAndLineItems) }};
470 }
471
472 }
473 #endif