From 1b751d3f8c6bb7efd9b4acd54b4a1bf5266043bf Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 11 Aug 2022 23:35:57 +0200 Subject: -fix handling of serialization failure --- .../taler-merchant-httpd_post-orders-ID-pay.c | 6 ++++-- ...r-merchant-httpd_private-get-instances-ID-kyc.c | 23 ++++++++++++++++++++++ src/include/taler_merchant_service.h | 12 ++++++----- src/lib/merchant_api_get_kyc.c | 2 ++ src/lib/merchant_api_merchant_get_order.c | 6 ++++++ src/testing/test_kyc_api.c | 16 +++++++++++++++ src/testing/test_merchant_api.c | 9 ++++++--- src/testing/testing_api_cmd_kyc_get.c | 19 ++++++++++++++---- src/testing/testing_api_cmd_merchant_get_order.c | 6 ------ 9 files changed, 79 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c index 91533de5..72c3e4da 100644 --- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c +++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c @@ -942,7 +942,6 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg, const struct TALER_EXCHANGE_BatchDepositResult *dr) { struct PayContext *pc = eg->pc; - unsigned int j = 0; enum GNUNET_DB_QueryStatus qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; @@ -954,6 +953,8 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg, pc->hc->instance->settings.id); for (unsigned int r = 0; rpreflight (TMH_db->cls); if (GNUNET_OK != TMH_db->start (TMH_db->cls, @@ -982,6 +983,7 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg, it is possible to over-pay if two wallets literally make a concurrent payment, as the earlier check for 'paid' is not in the same transaction scope as this 'insert' operation. */ + GNUNET_assert (j < dr->details.success.num_signatures); qs = TMH_db->insert_deposit ( TMH_db->cls, pc->hc->instance->settings.id, @@ -999,7 +1001,7 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg, if (GNUNET_DB_STATUS_SOFT_ERROR == qs) { TMH_db->rollback (TMH_db->cls); - continue; + break; } if (0 > qs) { diff --git a/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c b/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c index fbb4f63f..d3f32da2 100644 --- a/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c +++ b/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c @@ -114,6 +114,7 @@ struct ExchangeKycRequest * Last KYC status returned by the exchange. */ bool kyc_ok; + }; @@ -217,6 +218,13 @@ struct KycContext * True if @e h_wire was given. */ bool have_h_wire; + + /** + * We're still waiting on the exchange to determine + * the KYC status of our deposit(s). + */ + bool kyc_serial_pending; + }; @@ -615,6 +623,11 @@ kyc_status_cb (void *cls, <, STALE_KYC_TIMEOUT)) ) return; /* KYC ok, ignore! */ + if (0 == exchange_kyc_serial) + { + kc->kyc_serial_pending = true; + return; + } kc->response_code = MHD_HTTP_ACCEPTED; ekr = GNUNET_new (struct ExchangeKycRequest); GNUNET_CONTAINER_DLL_insert (kc->exchange_pending_head, @@ -766,6 +779,16 @@ get_instances_ID_kyc (struct TMH_MerchantInstance *mi, "account_kyc_get_status"); } } + if (kc->kyc_serial_pending) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Exchange legitimization UUID unknown, assuming KYC pending\n"); + return TALER_MHD_REPLY_JSON_PACK ( + connection, + MHD_HTTP_SERVICE_UNAVAILABLE, + GNUNET_JSON_pack_string ("hint", + "awaiting legitimization UUID")); + } if (NULL == kc->exchange_pending_head) return TALER_MHD_reply_static (connection, MHD_HTTP_NO_CONTENT, diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h index 2e6ea1fa..089518f8 100644 --- a/src/include/taler_merchant_service.h +++ b/src/include/taler_merchant_service.h @@ -2031,7 +2031,7 @@ typedef void * @param order_id order id to identify the payment * @param session_id sesion id for the payment (or NULL if the check is not * bound to a session) - * @param transfer if true, obtain the wire transfer status from the exhcange. + * @param transfer if true, obtain the wire transfer status from the exchange. * Otherwise, the wire transfer status MAY be returned if it is available. * @param timeout timeout to use in long polling (how long may the server wait to reply * before generating an unpaid response). Note that this is just provided to @@ -3561,12 +3561,14 @@ struct TALER_MERCHANT_TipStatusResponse /** * Details depending on the HTTP status. */ - union { + union + { /** * Details on #MHD_HTTP_OK. */ - struct { + struct + { /** * Amount that was authorized under this tip @@ -3603,9 +3605,9 @@ struct TALER_MERCHANT_TipStatusResponse */ struct TALER_MERCHANT_PickupDetail *pickups; } success; - + } details; - + }; diff --git a/src/lib/merchant_api_get_kyc.c b/src/lib/merchant_api_get_kyc.c index 2a1725cf..bc688eed 100644 --- a/src/lib/merchant_api_get_kyc.c +++ b/src/lib/merchant_api_get_kyc.c @@ -217,6 +217,8 @@ handle_get_kyc_finished (void *cls, kr.hr.hint = TALER_JSON_get_error_hint (json); /* Nothing really to verify, merchant says we need to authenticate. */ break; + case MHD_HTTP_SERVICE_UNAVAILABLE: + break; default: /* unexpected response code */ kr.hr.ec = TALER_JSON_get_error_code (json); diff --git a/src/lib/merchant_api_merchant_get_order.c b/src/lib/merchant_api_merchant_get_order.c index f3181a3c..0e6b53bf 100644 --- a/src/lib/merchant_api_merchant_get_order.c +++ b/src/lib/merchant_api_merchant_get_order.c @@ -378,6 +378,12 @@ handle_merchant_order_get_finished (void *cls, case MHD_HTTP_OK: /* see below */ break; + case MHD_HTTP_ACCEPTED: + /* see below */ + omgh->cb (omgh->cb_cls, + &osr); + TALER_MERCHANT_merchant_order_get_cancel (omgh); + return; case MHD_HTTP_UNAUTHORIZED: osr.hr.ec = TALER_JSON_get_error_code (json); osr.hr.hint = TALER_JSON_get_error_hint (json); diff --git a/src/testing/test_kyc_api.c b/src/testing/test_kyc_api.c index bacf0586..cde93368 100644 --- a/src/testing/test_kyc_api.c +++ b/src/testing/test_kyc_api.c @@ -222,6 +222,22 @@ run (void *cls, CMD_EXEC_AGGREGATOR ("run-aggregator"), /* KYC: hence nothing happened at the bank yet: */ TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-2"), + /* KYC: we don't even know the legitimization UUID yet */ + TALER_TESTING_cmd_merchant_kyc_get ("kyc-pending", + merchant_url, + NULL, + NULL, + EXCHANGE_URL, + MHD_HTTP_SERVICE_UNAVAILABLE), + /* now we get the legi UUID */ + TALER_TESTING_cmd_merchant_get_order ("get-order-kyc", + merchant_url, + "create-proposal-1", + TALER_MERCHANT_OSC_PAID, + false, + MHD_HTTP_OK, + NULL), + /* Now we should get a status of pending */ TALER_TESTING_cmd_merchant_kyc_get ("kyc-pending", merchant_url, NULL, diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c index 3a32a981..9d9802a6 100644 --- a/src/testing/test_merchant_api.c +++ b/src/testing/test_merchant_api.c @@ -242,7 +242,8 @@ run (void *cls, "create-proposal-4", TALER_MERCHANT_OSC_UNPAID, false, - MHD_HTTP_OK), + MHD_HTTP_OK, + NULL), TALER_TESTING_cmd_merchant_delete_order ("delete-order-4", merchant_url, "4", @@ -381,7 +382,8 @@ run (void *cls, "create-proposal-1", TALER_MERCHANT_OSC_CLAIMED, false, - MHD_HTTP_OK), + MHD_HTTP_OK, + NULL), TALER_TESTING_cmd_wallet_poll_order_start ("poll-order-wallet-start-1", merchant_url, "create-proposal-1", @@ -435,7 +437,8 @@ run (void *cls, "create-proposal-1", TALER_MERCHANT_OSC_PAID, false, - MHD_HTTP_OK), + MHD_HTTP_OK, + NULL), TALER_TESTING_cmd_merchant_get_orders ("get-orders-1-paid", merchant_url, MHD_HTTP_OK, diff --git a/src/testing/testing_api_cmd_kyc_get.c b/src/testing/testing_api_cmd_kyc_get.c index f35a0028..f6f947df 100644 --- a/src/testing/testing_api_cmd_kyc_get.c +++ b/src/testing/testing_api_cmd_kyc_get.c @@ -133,6 +133,7 @@ kyc_get_cb (void *cls, const char *end; char *dec; const char *eq; + const char *nq; size_t toklen; url = kr->details.kyc_status.pending_kycs[0].kyc_url; @@ -148,7 +149,18 @@ kyc_get_cb (void *cls, (void) GNUNET_STRINGS_urldecode (tok, toklen, &dec); - eq = strrchr (dec, '/'); + eq = strstr (dec, "/kyc-proof/"); + if (NULL == eq) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Received unexpected KYC URL `%s' (%s)\n", + url, + dec); + GNUNET_free (dec); + TALER_TESTING_FAIL (cs->is); + } + eq += strlen ("/kyc-proof/"); + nq = strchr (eq, '/'); if (NULL == eq) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -158,10 +170,9 @@ kyc_get_cb (void *cls, GNUNET_free (dec); TALER_TESTING_FAIL (cs->is); } - eq++; if (GNUNET_OK != GNUNET_STRINGS_string_to_data (eq, - strlen (eq), + nq - eq, &cs->h_payto, sizeof (cs->h_payto))) { @@ -257,7 +268,7 @@ kyc_get_traits (void *cls, { struct KycGetState *cs = cls; struct TALER_TESTING_Trait traits[] = { - TALER_TESTING_make_trait_h_payto ( + TALER_TESTING_make_trait_h_payto ( &cs->h_payto), TALER_TESTING_trait_end () }; diff --git a/src/testing/testing_api_cmd_merchant_get_order.c b/src/testing/testing_api_cmd_merchant_get_order.c index 8001ac43..467b6d61 100644 --- a/src/testing/testing_api_cmd_merchant_get_order.c +++ b/src/testing/testing_api_cmd_merchant_get_order.c @@ -693,12 +693,6 @@ TALER_TESTING_cmd_merchant_get_order2 (const char *label, gos->wired = wired; gos->refunded = refunded; gos->http_status = http_status; - gos->transfers = NULL; - gos->transfers_length = 0; - gos->refunds = NULL; - gos->refunds_length = 0; - gos->forgets = NULL; - gos->forgets_length = 0; if (wired) { for (const char **clabel = transfers; *clabel != NULL; ++clabel) -- cgit v1.2.3