merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit 280bbb526c245ac69762e989816cb4c4848cd22c
parent 119de8db9e317e46ebe800524b806809d2b435b0
Author: Jonathan Buchanan <jonathan.russ.buchanan@gmail.com>
Date:   Mon, 10 Aug 2020 16:10:52 -0400

implement parse refund uri (untested) & add more tests for pay uri

Diffstat:
Msrc/include/taler_merchant_service.h | 54+++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/lib/merchant_api_common.c | 134++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc/testing/testing_api_cmd_merchant_get_order.c | 40++++++++++++++++++++++++++++++++++++++--
Msrc/testing/testing_api_cmd_wallet_get_order.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 251 insertions(+), 38 deletions(-)

diff --git a/src/include/taler_merchant_service.h b/src/include/taler_merchant_service.h @@ -197,22 +197,54 @@ TALER_MERCHANT_parse_pay_uri_free ( /** + * Contains information gathered from parsing a taler://refund URI. + */ +struct TALER_MERCHANT_RefundUriData +{ + /** + * Hostname (and possibly port) of the merchant. + */ + char *merchant_host; + + /** + * Prefix to the base url of the merchant backend. May be NULL. + */ + char *merchant_prefix_path; + + /** + * The id of the order to pay. + */ + char *order_id; + + /** + * A WLAN SSID that the wallet can use to connect to the internet in order to + * to pay. May be NULL. + */ + char *ssid; +}; + + +/** * Extracts information from a taler://refund URI. * * @param refund_uri the URI to parse. - * @param[out] merchant_host the hostname of the merchant. - * @param[out] merchant_prefix_path prefix of the base URL - * (NULL if not present). - * @param[out] order_id the id of the order to pay. - * @param[out] ssid the ssid for internet connectivity (NULL if not present). - * @return GNUNET_OK on success, GNUNET_SYSERR otherwise. + * @param[out] parse_data data extracted from the URI. Must be free'd. + * @return GNUNET_SYSERR if @e refund_uri is malformed, GNUNET_OK otherwise. */ int -TALER_MERCHANT_parse_refund_uri (const char *refund_uri, - const char **merchant_host, - const char **merchant_prefix_path, - const char **order_id, - const char **ssid); +TALER_MERCHANT_parse_refund_uri ( + const char *refund_uri, + struct TALER_MERCHANT_RefundUriData *parse_data); + + +/** + * Frees data contained in the result of parsing a taler://refund URI. + * + * @param parse_data the data to free. + */ +void +TALER_MERCHANT_parse_refund_uri_free ( + struct TALER_MERCHANT_RefundUriData *parse_data); /* ********************* /public/config ****************** */ diff --git a/src/lib/merchant_api_common.c b/src/lib/merchant_api_common.c @@ -211,27 +211,6 @@ parse_taler_uri_scheme_action (const char *uri, /** - * Finds the last occurrence of @e c in the string @e str. - * - * @param str the string to search in. - * @param c the character to search for. - * @return pointer to the last occurrence of @e c in @e str, if it exists, - * otherwise NULL. - */ -static char * -strchr_last (char *str, - char c) -{ - for (size_t i = strlen (str) - 1; i >= 0; --i) - { - if (c == str[i]) - return &str[i]; - } - return NULL; -} - - -/** * Extracts information from a taler://pay URI. * * @param pay_uri the URI to parse. @@ -263,8 +242,8 @@ TALER_MERCHANT_parse_pay_uri (const char *pay_uri, { char *mpp; char *order_id; - char *session_id = strchr_last (path, - '/'); + char *session_id = strrchr (path, + '/'); struct TALER_ClaimTokenP *claim_token = NULL; char *ssid; @@ -276,8 +255,8 @@ TALER_MERCHANT_parse_pay_uri (const char *pay_uri, *session_id = '\0'; ++session_id; - order_id = strchr_last (path, - '/'); + order_id = strrchr (path, + '/'); if (NULL == order_id) { GNUNET_free (path); @@ -370,3 +349,108 @@ TALER_MERCHANT_parse_pay_uri_free ( GNUNET_free (parse_data->claim_token); GNUNET_free (parse_data->ssid); } + + +/** + * Extracts information from a taler://refund URI. + * + * @param refund_uri the URI to parse. + * @param[out] parse_data data extracted from the URI. Must be free'd. + * @return GNUNET_SYSERR if @e refund_uri is malformed, GNUNET_OK otherwise. + */ +int +TALER_MERCHANT_parse_refund_uri ( + const char *refund_uri, + struct TALER_MERCHANT_RefundUriData *parse_data) +{ + char *path; + { + char *action; + + if ((GNUNET_OK != + parse_taler_uri_scheme_action (refund_uri, + &action, + &path)) || + (0 != strcmp ("refund", + action))) + { + GNUNET_free (action); + GNUNET_free (path); + return GNUNET_SYSERR; + } + GNUNET_free (action); + } + + { + char *mpp; + char *order_id; + char *last_seg = strrchr (path, + '/'); + char *ssid; + + if (NULL == last_seg) + { + GNUNET_free (path); + return GNUNET_SYSERR; + } + *last_seg = '\0'; + ++last_seg; + + order_id = strrchr (path, + '/'); + if (NULL == order_id) + { + GNUNET_free (path); + return GNUNET_SYSERR; + } + *order_id = '\0'; + ++order_id; + + ssid = strchr (last_seg, + '#'); + if (NULL != ssid) + { + *ssid = '\0'; + ++ssid; + } + + if (0 != strlen (last_seg)) + { + GNUNET_free (path); + return GNUNET_SYSERR; + } + + mpp = strchr (path, + '/'); + if (NULL != mpp) + { + *mpp = '\0'; + ++mpp; + } + + parse_data->merchant_host = GNUNET_strdup (path); + parse_data->merchant_prefix_path = + (NULL == mpp) ? NULL : GNUNET_strdup (mpp); + parse_data->order_id = GNUNET_strdup (order_id); + parse_data->ssid = + (NULL == ssid) ? NULL : GNUNET_strdup (ssid); + } + GNUNET_free (path); + return GNUNET_OK; +} + + +/** + * Frees data contained in the result of parsing a taler://refund URI. + * + * @param parse_data the data to free. + */ +void +TALER_MERCHANT_parse_refund_uri_free ( + struct TALER_MERCHANT_RefundUriData *parse_data) +{ + GNUNET_free (parse_data->merchant_host); + GNUNET_free (parse_data->merchant_prefix_path); + GNUNET_free (parse_data->order_id); + GNUNET_free (parse_data->ssid); +} diff --git a/src/testing/testing_api_cmd_merchant_get_order.c b/src/testing/testing_api_cmd_merchant_get_order.c @@ -445,6 +445,10 @@ merchant_get_order_cb ( { /* FIXME: Check all of the members of `pud` */ struct TALER_MERCHANT_PayUriData pud; + const struct TALER_TESTING_Command *order_cmd; + const char *order_id; + const struct TALER_ClaimTokenP *claim_token; + if (GNUNET_OK != TALER_MERCHANT_parse_pay_uri (osr->details.unpaid.taler_pay_uri, &pud)) @@ -455,12 +459,44 @@ merchant_get_order_cb ( return; } + order_cmd = TALER_TESTING_interpreter_lookup_command ( + gos->is, + gos->order_reference); + + if (GNUNET_OK != + TALER_TESTING_get_trait_order_id (order_cmd, + 0, + &order_id)) + TALER_TESTING_FAIL (gos->is); + + if (GNUNET_OK != + TALER_TESTING_get_trait_claim_token (order_cmd, + 0, + &claim_token)) + TALER_TESTING_FAIL (gos->is); + if ((0 != strcmp ("localhost:8080", pud.merchant_host)) || - (NULL != pud.merchant_prefix_path)) + (NULL != pud.merchant_prefix_path) || + (0 != strcmp (order_id, + pud.order_id)) || + (NULL != pud.ssid)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Order pay uri does not match\n"); + TALER_TESTING_interpreter_fail (gos->is); + TALER_MERCHANT_parse_pay_uri_free (&pud); + return; + } + /* The claim token is not given in the pay uri if the order + has been claimed already. */ + if ((NULL != pud.claim_token) && + ((NULL == claim_token) || + (0 != GNUNET_memcmp (claim_token, + pud.claim_token)))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Taler pay uri is incorrect\n"); + "Order pay uri does not match\n"); TALER_TESTING_interpreter_fail (gos->is); TALER_MERCHANT_parse_pay_uri_free (&pud); return; diff --git a/src/testing/testing_api_cmd_wallet_get_order.c b/src/testing/testing_api_cmd_wallet_get_order.c @@ -190,6 +190,67 @@ wallet_get_order_cb ( return; } } + if (!paid_b) + { + /* FIXME: Check all of the members of `pud` */ + struct TALER_MERCHANT_PayUriData pud; + const struct TALER_TESTING_Command *order_cmd; + const char *order_id; + const struct TALER_ClaimTokenP *claim_token; + + if (GNUNET_OK != + TALER_MERCHANT_parse_pay_uri (taler_pay_uri, + &pud)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Taler pay uri is malformed\n"); + TALER_TESTING_interpreter_fail (gos->is); + return; + } + + order_cmd = TALER_TESTING_interpreter_lookup_command ( + gos->is, + gos->order_reference); + + if (GNUNET_OK != + TALER_TESTING_get_trait_order_id (order_cmd, + 0, + &order_id)) + TALER_TESTING_FAIL (gos->is); + + if (GNUNET_OK != + TALER_TESTING_get_trait_claim_token (order_cmd, + 0, + &claim_token)) + TALER_TESTING_FAIL (gos->is); + + if ((0 != strcmp ("localhost:8080", + pud.merchant_host)) || + (NULL != pud.merchant_prefix_path) || + (0 != strcmp (order_id, + pud.order_id)) || + (NULL != pud.ssid)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Order pay uri does not match\n"); + TALER_TESTING_interpreter_fail (gos->is); + TALER_MERCHANT_parse_pay_uri_free (&pud); + return; + } + /* The claim token is not given in the pay uri if the order + has been claimed already. */ + if ((NULL != pud.claim_token) && + ((NULL == claim_token) || + (0 != GNUNET_memcmp (claim_token, + pud.claim_token)))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Order pay uri does not match\n"); + TALER_TESTING_interpreter_fail (gos->is); + TALER_MERCHANT_parse_pay_uri_free (&pud); + return; + } + } break; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING,