diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-02-29 16:42:10 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-02-29 16:42:10 +0100 |
commit | 0a2b049864c8dae0c53c203d46fca89e0e66849d (patch) | |
tree | 3e836be37902320a4a3a099ee62d960198057952 /src/exchange/taler-exchange-httpd_link.c | |
parent | de9ab28ab9e55597baf2ca32194ec65b441f0f36 (diff) | |
download | exchange-0a2b049864c8dae0c53c203d46fca89e0e66849d.tar.gz exchange-0a2b049864c8dae0c53c203d46fca89e0e66849d.tar.bz2 exchange-0a2b049864c8dae0c53c203d46fca89e0e66849d.zip |
big rename fest related to #6067 API renaming
Diffstat (limited to 'src/exchange/taler-exchange-httpd_link.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_link.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/exchange/taler-exchange-httpd_link.c b/src/exchange/taler-exchange-httpd_link.c new file mode 100644 index 000000000..83d7f6a05 --- /dev/null +++ b/src/exchange/taler-exchange-httpd_link.c @@ -0,0 +1,226 @@ +/* + This file is part of TALER + Copyright (C) 2014-2019 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 published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file taler-exchange-httpd_refresh_link.c + * @brief Handle /refresh/link requests + * @author Florian Dold + * @author Benedikt Mueller + * @author Christian Grothoff + */ +#include "platform.h" +#include <gnunet/gnunet_util_lib.h> +#include <jansson.h> +#include <microhttpd.h> +#include "taler_mhd_lib.h" +#include "taler-exchange-httpd_mhd.h" +#include "taler-exchange-httpd_link.h" +#include "taler-exchange-httpd_responses.h" +#include "taler-exchange-httpd_keystate.h" + + +/** + * Closure for #handle_transfer_data(). + */ +struct HTD_Context +{ + + /** + * Public key of the coin for which we are running /refresh/link. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Json array with transfer data we collect. + */ + json_t *mlist; + + /** + * Taler error code. + */ + enum TALER_ErrorCode ec; +}; + + +/** + * Function called with the session hashes and transfer secret + * information for a given coin. Gets the linkage data and + * builds the reply for the client. + * + * @param cls closure, a `struct HTD_Context` + * @param transfer_pub public transfer key for the session + * @param ldl link data related to @a transfer_pub + */ +static void +handle_link_data (void *cls, + const struct TALER_TransferPublicKeyP *transfer_pub, + const struct TALER_EXCHANGEDB_LinkDataList *ldl) +{ + struct HTD_Context *ctx = cls; + json_t *list; + json_t *root; + + if (NULL == ctx->mlist) + return; + if (NULL == (list = json_array ())) + goto fail; + + for (const struct TALER_EXCHANGEDB_LinkDataList *pos = ldl; + NULL != pos; + pos = pos->next) + { + json_t *obj; + + obj = json_pack ("{s:o, s:o, s:o}", + "denom_pub", + GNUNET_JSON_from_rsa_public_key + (pos->denom_pub.rsa_public_key), + "ev_sig", + GNUNET_JSON_from_rsa_signature + (pos->ev_sig.rsa_signature), + "link_sig", + GNUNET_JSON_from_data_auto (&pos->orig_coin_link_sig)); + if ( (NULL == obj) || + (0 != + json_array_append_new (list, + obj)) ) + { + json_decref (list); + goto fail; + } + } + root = json_pack ("{s:o, s:o}", + "new_coins", + list, + "transfer_pub", + GNUNET_JSON_from_data_auto (transfer_pub)); + if ( (NULL == root) || + (0 != + json_array_append_new (ctx->mlist, + root)) ) + goto fail; + return; +fail: + ctx->ec = TALER_EC_JSON_ALLOCATION_FAILURE; + json_decref (ctx->mlist); + ctx->mlist = NULL; +} + + +/** + * Execute a "/refresh/link". Returns the linkage information that + * will allow the owner of a coin to follow the refresh trail to + * the refreshed coin. + * + * If it returns a non-error code, the transaction logic MUST + * NOT queue a MHD response. IF it returns an hard error, the + * transaction logic MUST queue a MHD response and set @a mhd_ret. IF + * it returns the soft error code, the function MAY be called again to + * retry and MUST not queue a MHD response. + * + * @param cls closure + * @param connection MHD request which triggered the transaction + * @param session database session to use + * @param[out] mhd_ret set to MHD response status for @a connection, + * if transaction failed (!) + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +refresh_link_transaction (void *cls, + struct MHD_Connection *connection, + struct TALER_EXCHANGEDB_Session *session, + int *mhd_ret) +{ + struct HTD_Context *ctx = cls; + enum GNUNET_DB_QueryStatus qs; + + qs = TEH_plugin->get_link_data (TEH_plugin->cls, + session, + &ctx->coin_pub, + &handle_link_data, + ctx); + if (NULL == ctx->mlist) + { + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + ctx->ec, + "coin_pub"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) + { + *mhd_ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_REFRESH_LINK_COIN_UNKNOWN, + "coin_pub"); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} + + +/** + * Handle a "/coins/$COIN_PUB/link" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param args array of additional options (length: 2, first is the coin_pub, second must be "link") + * @return MHD result code + */ +int +TEH_REFRESH_handler_link (const struct TEH_RequestHandler *rh, + struct MHD_Connection *connection, + const char *const args[2]) +{ + struct HTD_Context ctx; + int mhd_ret; + + (void) rh; + memset (&ctx, + 0, + sizeof (ctx)); + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (args[0], + strlen (args[0]), + &ctx.coin_pub, + sizeof (ctx.coin_pub))) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_COINS_INVALID_COIN_PUB, + "coin public key malformed"); + } + ctx.mlist = json_array (); + if (GNUNET_OK != + TEH_DB_run_transaction (connection, + "run link", + &mhd_ret, + &refresh_link_transaction, + &ctx)) + { + if (NULL != ctx.mlist) + json_decref (ctx.mlist); + return mhd_ret; + } + mhd_ret = TALER_MHD_reply_json (connection, + ctx.mlist, + MHD_HTTP_OK); + json_decref (ctx.mlist); + return mhd_ret; +} + + +/* end of taler-exchange-httpd_refresh_link.c */ |