diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-04-11 18:38:55 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-04-11 18:38:55 +0200 |
commit | 6ff02bc7ea9ca1b39cebf7ac381dfce46f267627 (patch) | |
tree | f4bfc429206aa95c05fe3ef4b8cb638c4895e9f8 | |
parent | 19c56c7eb81efc272d864d6765d7d61943141ce2 (diff) | |
download | merchant-6ff02bc7ea9ca1b39cebf7ac381dfce46f267627.tar.gz merchant-6ff02bc7ea9ca1b39cebf7ac381dfce46f267627.tar.bz2 merchant-6ff02bc7ea9ca1b39cebf7ac381dfce46f267627.zip |
finish #4939 implementation: allow client to indicate preference for payment target
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 30 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd.h | 29 | ||||
-rw-r--r-- | src/backend/taler-merchant-httpd_order.c | 163 |
3 files changed, 122 insertions, 100 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index b86fde71..6c7eaf5e 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -56,6 +56,34 @@ */ #define UNIX_BACKLOG 500 + +/** + * Used by the iterator of the various merchant's instances given + * in configuration + */ +struct IterateInstancesCls +{ + + /** + * Current index in the global array of #MerchantInstance + * types. Used by the callback in order to know which index + * is associated to the element being processed. + */ + unsigned int current_index; + + /** + * Flag indicating whether config contains a default instance + */ + unsigned int default_instance; + + /** + * Tells if the parsing encountered any error. We need this + * field since the iterator must return void + */ + unsigned int ret; +}; + + /** * Hashmap pointing at merchant instances by 'id'. An 'id' is * just a string that identifies a merchant instance. When a frontend @@ -982,7 +1010,6 @@ wireformat_iterator_cb (void *cls, return; } - wm = GNUNET_new (struct WireMethod); wm->wire_method = TALER_payto_get_method (payto); GNUNET_free (payto); @@ -1001,7 +1028,6 @@ wireformat_iterator_cb (void *cls, GNUNET_CONTAINER_DLL_insert_tail (mi->wm_head, mi->wm_tail, wm); - wm->j_wire = j; wm->h_wire = jh_wire; } diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h index ad83a669..28a0f2ea 100644 --- a/src/backend/taler-merchant-httpd.h +++ b/src/backend/taler-merchant-httpd.h @@ -37,33 +37,6 @@ /** - * Used by the iterator of the various merchant's instances given - * in configuration - */ -struct IterateInstancesCls -{ - - /** - * Current index in the global array of #MerchantInstance - * types. Used by the callback in order to know which index - * is associated to the element being processed. - */ - unsigned int current_index; - - /** - * Flag indicating whether config contains a default instance - */ - unsigned int default_instance; - - /** - * Tells if the parsing encountered any error. We need this - * field since the iterator must return void - */ - unsigned int ret; -}; - - -/** * Supported wire method. Kept in a DLL. */ struct WireMethod @@ -79,7 +52,7 @@ struct WireMethod struct WireMethod *prev; /** - * Which wire method is @e j_wire using? Points into @e j_wire. + * Which wire method / payment target identifier is @e j_wire using? */ char *wire_method; diff --git a/src/backend/taler-merchant-httpd_order.c b/src/backend/taler-merchant-httpd_order.c index 1cf34632..317e451b 100644 --- a/src/backend/taler-merchant-httpd_order.c +++ b/src/backend/taler-merchant-httpd_order.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2014, 2015, 2016, 2018 Taler Systems SA + (C) 2014, 2015, 2016, 2018, 2020 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as @@ -144,8 +144,8 @@ json_parse_cleanup (struct TM_HandlerContext *hc) * @returns the merchant instance's base URL */ static char * -make_merchant_base_url (struct MHD_Connection *connection, const - char *instance_id) +make_merchant_base_url (struct MHD_Connection *connection, + const char *instance_id) { const char *host; const char *forwarded_host; @@ -210,7 +210,6 @@ proposal_put (struct MHD_Connection *connection, json_t *order, const struct MerchantInstance *mi) { - enum GNUNET_GenericReturnValue res; struct TALER_Amount total; const char *order_id; const char *summary; @@ -455,22 +454,25 @@ proposal_put (struct MHD_Connection *connection, } /* needed to synthesize merchant info */ /* extract fields we need to sign separately */ - res = TALER_MHD_parse_json_data (connection, - order, - spec); - /* json is malformed */ - if (GNUNET_NO == res) { - return MHD_YES; - } - /* other internal errors might have occurred */ - if (GNUNET_SYSERR == res) - { - return TALER_MHD_reply_with_error - (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_PROPOSAL_ORDER_PARSE_ERROR, - "Impossible to parse the order"); + enum GNUNET_GenericReturnValue res; + + res = TALER_MHD_parse_json_data (connection, + order, + spec); + /* json is malformed */ + if (GNUNET_NO == res) + { + return MHD_YES; + } + /* other internal errors might have occurred */ + if (GNUNET_SYSERR == res) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_PROPOSAL_ORDER_PARSE_ERROR, + "Impossible to parse the order"); + } } if (0 != strcasecmp (total.currency, @@ -509,11 +511,10 @@ proposal_put (struct MHD_Connection *connection, if (GNUNET_OK != check_products (products)) { GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error - (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_PARAMETER_MALFORMED, - "order:products"); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_PARAMETER_MALFORMED, + "order:products"); } /* add fields to the contract that the backend should provide */ @@ -524,14 +525,30 @@ proposal_put (struct MHD_Connection *connection, json_object_set (order, "auditors", j_auditors); - /* TODO (#4939-12806): add proper mechanism for - selection of wire method(s) by merchant! */ - wm = mi->wm_head; + { + const char *target; + + target = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "payment_target"); + wm = mi->wm_head; + if (NULL != target) + { + while ( (NULL != wm) && + (GNUNET_YES == wm->active) && + (0 != strcasecmp (target, + wm->wire_method) ) ) + wm = wm->next; + } + if (GNUNET_YES != wm->active) + wm = NULL; + } if (NULL == wm) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "No wire method available for instance '%s'\n", mi->id); + "No wire method available for instance '%s'\n", + mi->id); GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (connection, MHD_HTTP_NOT_FOUND, @@ -570,12 +587,11 @@ proposal_put (struct MHD_Connection *connection, if (GNUNET_DB_STATUS_SOFT_ERROR == qs) { GNUNET_break (0); - return TALER_MHD_reply_with_error - (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_PROPOSAL_STORE_DB_ERROR_SOFT, - "db error: could not check for existing order" - " due to repeated soft transaction failure"); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_PROPOSAL_STORE_DB_ERROR_SOFT, + "db error: could not check for existing order" + " due to repeated soft transaction failure"); } { @@ -604,22 +620,20 @@ proposal_put (struct MHD_Connection *connection, js = json_dumps (contract_terms, JSON_COMPACT); - GNUNET_log - (GNUNET_ERROR_TYPE_ERROR, - _ ("Order ID `%s' already exists with proposal `%s'\n"), - order_id, - js); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _ ("Order ID `%s' already exists with proposal `%s'\n"), + order_id, + js); free (js); } json_decref (contract_terms); /* contract_terms may be private, only expose * duplicate order_id to the network */ - rv = TALER_MHD_reply_with_error - (connection, - MHD_HTTP_BAD_REQUEST, /* or conflict? */ - TALER_EC_PROPOSAL_STORE_DB_ERROR_ALREADY_EXISTS, - msg); + rv = TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, /* or conflict? */ + TALER_EC_PROPOSAL_STORE_DB_ERROR_ALREADY_EXISTS, + msg); GNUNET_free (msg); return rv; } @@ -635,13 +649,17 @@ proposal_put (struct MHD_Connection *connection, } /* DB transaction succeeded, generate positive response */ - res = TALER_MHD_reply_json_pack (connection, - MHD_HTTP_OK, - "{s:s}", - "order_id", - order_id); - GNUNET_JSON_parse_free (spec); - return res; + { + MHD_RESULT ret; + + ret = TALER_MHD_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:s}", + "order_id", + order_id); + GNUNET_JSON_parse_free (spec); + return ret; + } } @@ -668,7 +686,6 @@ MH_handler_order_post (struct TMH_RequestHandler *rh, size_t *upload_data_size, struct MerchantInstance *mi) { - int res; struct TMH_JsonParseContext *ctx; json_t *root; json_t *order; @@ -684,20 +701,24 @@ MH_handler_order_post (struct TMH_RequestHandler *rh, ctx = *connection_cls; } - res = TALER_MHD_parse_post_json (connection, - &ctx->json_parse_context, - upload_data, - upload_data_size, - &root); + { + int res; - if (GNUNET_SYSERR == res) - return MHD_NO; + res = TALER_MHD_parse_post_json (connection, + &ctx->json_parse_context, + upload_data, + upload_data_size, + &root); - /* A error response was already generated */ - if ( (GNUNET_NO == res) || - /* or, need more data to accomplish parsing */ - (NULL == root) ) - return MHD_YES; + if (GNUNET_SYSERR == res) + return MHD_NO; + + /* A error response was already generated */ + if ( (GNUNET_NO == res) || + /* or, need more data to accomplish parsing */ + (NULL == root) ) + return MHD_YES; + } order = json_object_get (root, "order"); { @@ -705,15 +726,17 @@ MH_handler_order_post (struct TMH_RequestHandler *rh, if (NULL == order) { - ret = TALER_MHD_reply_with_error - (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_PARAMETER_MISSING, - "order"); + ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_PARAMETER_MISSING, + "order"); } else { - ret = proposal_put (connection, root, order, mi); + ret = proposal_put (connection, + root, + order, + mi); } json_decref (root); return ret; |