diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/taler_mint_service.h | 2 | ||||
| -rw-r--r-- | src/mint-lib/Makefile.am | 3 | ||||
| -rw-r--r-- | src/mint-lib/mint_api_json.c | 34 | ||||
| -rw-r--r-- | src/mint-lib/mint_api_json.h | 21 | ||||
| -rw-r--r-- | src/mint-lib/mint_api_wire_deposits.c | 296 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_db.c | 4 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_db.h | 2 | ||||
| -rw-r--r-- | src/mint/taler-mint-httpd_tracking.c | 9 | 
8 files changed, 359 insertions, 12 deletions
diff --git a/src/include/taler_mint_service.h b/src/include/taler_mint_service.h index 070f77f0..b151cb00 100644 --- a/src/include/taler_mint_service.h +++ b/src/include/taler_mint_service.h @@ -1086,7 +1086,7 @@ struct TALER_WireDepositDetails    /**     * Value of the deposit (including fee).     */ -  struct TALER_Amount coin_contribution; +  struct TALER_Amount coin_value;    /**     * Fee charged by the mint for the deposit. diff --git a/src/mint-lib/Makefile.am b/src/mint-lib/Makefile.am index 3ee1f5a1..171a4246 100644 --- a/src/mint-lib/Makefile.am +++ b/src/mint-lib/Makefile.am @@ -24,7 +24,8 @@ libtalermint_la_SOURCES = \    mint_api_refresh.c \    mint_api_refresh_link.c \    mint_api_reserve.c \ -  mint_api_wire.c +  mint_api_wire.c \ +  mint_api_wire_deposits.c  libtalermint_la_LIBADD = \    -lgnunetutil \ diff --git a/src/mint-lib/mint_api_json.c b/src/mint-lib/mint_api_json.c index a728a549..7de33e5e 100644 --- a/src/mint-lib/mint_api_json.c +++ b/src/mint-lib/mint_api_json.c @@ -232,6 +232,20 @@ parse_json (json_t *root,        }        break; +    case MAJ_CMD_UINT64: +      { +        json_int_t val; + +        if (! json_is_integer (pos)) +        { +          GNUNET_break_op (0); +          return i; +        } +        val = json_integer_value (pos); +        *spec[i].details.u64 = (uint64_t) val; +      } +      break; +      case MAJ_CMD_JSON_OBJECT:        {          if (! (json_is_object (pos) || json_is_array (pos)) ) @@ -429,6 +443,26 @@ MAJ_spec_uint16 (const char *name,  /** + * 64-bit integer. + * + * @param name name of the JSON field + * @param[out] u64 where to store the integer found under @a name + */ +struct MAJ_Specification +MAJ_spec_uint64 (const char *name, +                 uint64_t *u64) +{ +  struct MAJ_Specification ret = +    { +      .cmd = MAJ_CMD_UINT64, +      .field = name, +      .details.u64 = u64 +    }; +  return ret; +} + + +/**   * JSON object.   *   * @param name name of the JSON field diff --git a/src/mint-lib/mint_api_json.h b/src/mint-lib/mint_api_json.h index 68809059..6bc3a557 100644 --- a/src/mint-lib/mint_api_json.h +++ b/src/mint-lib/mint_api_json.h @@ -79,6 +79,11 @@ enum MAJ_Command    MAJ_CMD_UINT16,    /** +   * Parse `uint64_t` integer at the current position. +   */ +  MAJ_CMD_UINT64, + +  /**     * Parse JSON object at the current position.     */    MAJ_CMD_JSON_OBJECT, @@ -192,6 +197,11 @@ struct MAJ_Specification      uint16_t *u16;      /** +     * Where to store 64-bit integer. +     */ +    uint64_t *u64; + +    /**       * Where to store a JSON object.       */      json_t **obj; @@ -283,6 +293,17 @@ MAJ_spec_uint16 (const char *name,  /** + * 64-bit integer. + * + * @param name name of the JSON field + * @param[out] u64 where to store the integer found under @a name + */ +struct MAJ_Specification +MAJ_spec_uint64 (const char *name, +                 uint64_t *u64); + + +/**   * JSON object.   *   * @param name name of the JSON field diff --git a/src/mint-lib/mint_api_wire_deposits.c b/src/mint-lib/mint_api_wire_deposits.c new file mode 100644 index 00000000..6fd4d75d --- /dev/null +++ b/src/mint-lib/mint_api_wire_deposits.c @@ -0,0 +1,296 @@ +/* +  This file is part of TALER +  Copyright (C) 2014, 2015, 2016 GNUnet e.V. + +  TALER is free software; you can redistribute it and/or modify it under the +  terms of the GNU 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 General Public License for more details. + +  You should have received a copy of the GNU General Public License along with +  TALER; see the file COPYING.  If not, If not, see +  <http://www.gnu.org/licenses/> +*/ +/** + * @file mint-lib/mint_api_wire_deposits.c + * @brief Implementation of the /wire/deposits request of the mint's HTTP API + * @author Christian Grothoff + */ +#include "platform.h" +#include <curl/curl.h> +#include <jansson.h> +#include <microhttpd.h> /* just for HTTP status codes */ +#include <gnunet/gnunet_util_lib.h> +#include "taler_mint_service.h" +#include "mint_api_common.h" +#include "mint_api_json.h" +#include "mint_api_context.h" +#include "mint_api_handle.h" +#include "taler_signatures.h" + + +/** + * @brief A /wire/deposits Handle + */ +struct TALER_MINT_WireDepositsHandle +{ + +  /** +   * The connection to mint this request handle will use +   */ +  struct TALER_MINT_Handle *mint; + +  /** +   * The url for this request. +   */ +  char *url; + +  /** +   * JSON encoding of the request to POST. +   */ +  char *json_enc; + +  /** +   * Handle for the request. +   */ +  struct MAC_Job *job; + +  /** +   * Function to call with the result. +   */ +  TALER_MINT_WireDepositsCallback cb; + +  /** +   * Closure for @a cb. +   */ +  void *cb_cls; + +  /** +   * Download buffer +   */ +  struct MAC_DownloadBuffer db; + +}; + + +/** + * Function called when we're done processing the + * HTTP /wire/deposits request. + * + * @param cls the `struct TALER_MINT_WireDepositsHandle` + * @param eh the curl request handle + */ +static void +handle_wire_deposits_finished (void *cls, +                               CURL *eh) +{ +  struct TALER_MINT_WireDepositsHandle *wdh = cls; +  long response_code; +  json_t *json; + +  wdh->job = NULL; +  json = MAC_download_get_result (&wdh->db, +                                  eh, +                                  &response_code); +  switch (response_code) +  { +  case 0: +    break; +  case MHD_HTTP_OK: +    { +      json_t *details_j; +      struct GNUNET_HashCode h_wire; +      struct TALER_Amount total_amount; +      struct TALER_MerchantPublicKeyP merchant_pub; +      unsigned int num_details; +      struct MAJ_Specification spec[] = { +        MAJ_spec_fixed_auto ("H_wire", &h_wire), +        MAJ_spec_fixed_auto ("merchant_pub", &merchant_pub), +        MAJ_spec_amount ("total_amount", &total_amount), +        MAJ_spec_json ("details", &details_j), +        MAJ_spec_end +      }; + +      if (GNUNET_OK != +          MAJ_parse_json (json, +                          spec)) +      { +        GNUNET_break_op (0); +        response_code = 0; +        break; +      } +      num_details = json_array_size (details_j); +      { +        struct TALER_WireDepositDetails details[num_details]; +        unsigned int i; + +        for (i=0;i<num_details;i++) +        { +          struct TALER_WireDepositDetails *detail = &details[i]; +          struct json_t *detail_j = json_array_get (details_j, i); +          struct MAJ_Specification spec_detail[] = { +            MAJ_spec_fixed_auto ("H_contract", &detail->h_contract), +            MAJ_spec_amount ("deposit_value", &detail->coin_value), +            MAJ_spec_amount ("deposit_fee", &detail->coin_fee), +            MAJ_spec_uint64 ("transaction_id", &detail->transaction_id), +            MAJ_spec_fixed_auto ("coin_pub", &detail->coin_pub), +            MAJ_spec_end +          }; + +          if (GNUNET_OK != +              MAJ_parse_json (detail_j, +                              spec_detail)) +          { +            GNUNET_break_op (0); +            response_code = 0; +            break; +          } +        } +        if (0 == response_code) +          break; +        wdh->cb (wdh->cb_cls, +                 response_code, +                 json, +                 &h_wire, +                 &total_amount, +                 num_details, +                 details); +        json_decref (json); +        TALER_MINT_wire_deposits_cancel (wdh); +        return; +      } +    } +    break; +  case MHD_HTTP_BAD_REQUEST: +    /* This should never happen, either us or the mint is buggy +       (or API version conflict); just pass JSON reply to the application */ +    break; +  case MHD_HTTP_UNAUTHORIZED: +    /* Nothing really to verify, mint says one of the signatures is +       invalid; as we checked them, this should never happen, we +       should pass the JSON reply to the application */ +    break; +  case MHD_HTTP_NOT_FOUND: +    /* Mint does not know about transaction; +       we should pass the reply to the application */ +    break; +  case MHD_HTTP_INTERNAL_SERVER_ERROR: +    /* Server had an internal issue; we should retry, but this API +       leaves this to the application */ +    break; +  default: +    /* unexpected response code */ +    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +                "Unexpected response code %u\n", +                response_code); +    GNUNET_break (0); +    response_code = 0; +    break; +  } +  wdh->cb (wdh->cb_cls, +           response_code, +           json, +           NULL, NULL, 0, NULL); +  json_decref (json); +  TALER_MINT_wire_deposits_cancel (wdh); +} + + +/** + * Query the mint about which transactions were combined + * to create a wire transfer. + * + * @param mint mint to query + * @param wtid raw wire transfer identifier to get information about + * @param cb callback to call + * @param cb_cls closure for @a cb + * @return handle to cancel operation + */ +struct TALER_MINT_WireDepositsHandle * +TALER_MINT_wire_deposits (struct TALER_MINT_Handle *mint, +                          const struct TALER_WireTransferIdentifierRawP *wtid, +                          TALER_MINT_WireDepositsCallback cb, +                          void *cb_cls) +{ +  struct TALER_MINT_WireDepositsHandle *wdh; +  struct TALER_MINT_Context *ctx; +  json_t *wdh_obj; +  CURL *eh; + +  if (GNUNET_YES != +      MAH_handle_is_ready (mint)) +  { +    GNUNET_break (0); +    return NULL; +  } + +  wdh_obj = json_pack ("{s:o}", +                       "wtid", TALER_json_from_data (wtid, +                                                     sizeof (struct TALER_WireTransferIdentifierRawP))); + +  wdh = GNUNET_new (struct TALER_MINT_WireDepositsHandle); +  wdh->mint = mint; +  wdh->cb = cb; +  wdh->cb_cls = cb_cls; +  wdh->url = MAH_path_to_url (mint, "/wire/deposits"); + +  eh = curl_easy_init (); +  GNUNET_assert (NULL != (wdh->json_enc = +                          json_dumps (wdh_obj, +                                      JSON_COMPACT))); +  json_decref (wdh_obj); +  GNUNET_assert (CURLE_OK == +                 curl_easy_setopt (eh, +                                   CURLOPT_URL, +                                   wdh->url)); +  GNUNET_assert (CURLE_OK == +                 curl_easy_setopt (eh, +                                   CURLOPT_POSTFIELDS, +                                   wdh->json_enc)); +  GNUNET_assert (CURLE_OK == +                 curl_easy_setopt (eh, +                                   CURLOPT_POSTFIELDSIZE, +                                   strlen (wdh->json_enc))); +  GNUNET_assert (CURLE_OK == +                 curl_easy_setopt (eh, +                                   CURLOPT_WRITEFUNCTION, +                                   &MAC_download_cb)); +  GNUNET_assert (CURLE_OK == +                 curl_easy_setopt (eh, +                                   CURLOPT_WRITEDATA, +                                   &wdh->db)); +  ctx = MAH_handle_to_context (mint); +  wdh->job = MAC_job_add (ctx, +                          eh, +                          GNUNET_YES, +                          &handle_wire_deposits_finished, +                          wdh); +  return wdh; +} + + +/** + * Cancel wire deposits request.  This function cannot be used on a request + * handle if a response is already served for it. + * + * @param wdh the wire deposits request handle + */ +void +TALER_MINT_wire_deposits_cancel (struct TALER_MINT_WireDepositsHandle *wdh) +{ +  if (NULL != wdh->job) +  { +    MAC_job_cancel (wdh->job); +    wdh->job = NULL; +  } +  GNUNET_free_non_null (wdh->db.buf); +  GNUNET_free (wdh->url); +  GNUNET_free (wdh->json_enc); +  GNUNET_free (wdh); +} + + +/* end of mint_api_wire_deposits.c */ diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index fb4ee1b7..19c21398 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -1704,7 +1704,7 @@ handle_transaction_data (void *cls,   */  int  TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, -                             const struct TALER_WireTransferIdentifierP *wtid) +                             const struct TALER_WireTransferIdentifierRawP *wtid)  {    int ret;    struct WtidTransactionContext ctx; @@ -1720,7 +1720,7 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection,    ctx.deposits = json_array ();    ret = TMH_plugin->lookup_wire_transfer (TMH_plugin->cls,                                            session, -                                          &wtid->raw, +                                          wtid,                                            &handle_transaction_data,                                            &ctx);    if (GNUNET_SYSERR == ret) diff --git a/src/mint/taler-mint-httpd_db.h b/src/mint/taler-mint-httpd_db.h index e366112d..0327bef2 100644 --- a/src/mint/taler-mint-httpd_db.h +++ b/src/mint/taler-mint-httpd_db.h @@ -202,7 +202,7 @@ TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,   */  int  TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, -                              const struct TALER_WireTransferIdentifierP *wtid); +                              const struct TALER_WireTransferIdentifierRawP *wtid);  /** diff --git a/src/mint/taler-mint-httpd_tracking.c b/src/mint/taler-mint-httpd_tracking.c index e61b4bae..76293803 100644 --- a/src/mint/taler-mint-httpd_tracking.c +++ b/src/mint/taler-mint-httpd_tracking.c @@ -46,22 +46,17 @@ TMH_TRACKING_handler_wire_deposits (struct TMH_RequestHandler *rh,                                      const char *upload_data,                                      size_t *upload_data_size)  { -  struct TALER_WireTransferIdentifierP wtid; +  struct TALER_WireTransferIdentifierRawP wtid;    int res;    res = TMH_PARSE_mhd_request_arg_data (connection,                                          "wtid",                                          &wtid, -                                        sizeof (struct TALER_WireTransferIdentifierP)); +                                        sizeof (struct TALER_WireTransferIdentifierRawP));    if (GNUNET_SYSERR == res)      return MHD_NO; /* internal error */    if (GNUNET_NO == res)      return MHD_YES; /* parse error */ -  if (wtid.crc8 != -      GNUNET_CRYPTO_crc8_n (&wtid.raw, -                            sizeof (wtid.raw))) -    return TMH_RESPONSE_reply_arg_invalid (connection, -                                           "wtid");    return TMH_DB_execute_wire_deposits (connection,                                         &wtid);  }  | 
