exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_deposits_get.c (10514B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014-2021, 2024 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU General Public License as
      7   published by the Free Software Foundation; either version 3, or
      8   (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but
     11   WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU General Public License for more details.
     14 
     15   You should have received a copy of the GNU General Public
     16   License along with TALER; see the file COPYING.  If not, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 
     20 /**
     21  * @file testing/testing_api_cmd_deposits_get.c
     22  * @brief Implement the testing CMDs for the /deposits/ GET operations.
     23  * @author Marcello Stanisci
     24  */
     25 #include "taler/platform.h"
     26 #include "taler/taler_json_lib.h"
     27 #include <gnunet/gnunet_curl_lib.h>
     28 #include "taler/taler_testing_lib.h"
     29 
     30 /**
     31  * State for a "track transaction" CMD.
     32  */
     33 struct TrackTransactionState
     34 {
     35 
     36   /**
     37    * If non NULL, will provide a WTID to be compared against
     38    * the one returned by the "track transaction" operation.
     39    */
     40   const char *bank_transfer_reference;
     41 
     42   /**
     43    * Our command.
     44    */
     45   const struct TALER_TESTING_Command *cmd;
     46 
     47   /**
     48    * The WTID associated by the transaction being tracked.
     49    */
     50   struct TALER_WireTransferIdentifierRawP wtid;
     51 
     52   /**
     53    * Expected HTTP response code.
     54    */
     55   unsigned int expected_response_code;
     56 
     57   /**
     58    * Set to the KYC requirement payto hash *if* the exchange replied with a
     59    * request for KYC (#MHD_HTTP_ACCEPTED).
     60    * Note: set based on our @e merchant_payto_uri, as
     61    * the exchange does not respond with the payto hash.
     62    */
     63   struct TALER_NormalizedPaytoHashP h_payto;
     64 
     65   /**
     66    * Set to the KYC requirement row *if* the exchange replied with
     67    * a request for KYC (#MHD_HTTP_ACCEPTED).
     68    */
     69   uint64_t requirement_row;
     70 
     71   /**
     72    * Reference to any operation that can provide a transaction.
     73    * Will be the transaction to track.
     74    */
     75   const char *transaction_reference;
     76 
     77   /**
     78    * Payto URI of the merchant receiving the deposit.
     79    */
     80   struct TALER_FullPayto merchant_payto_uri;
     81 
     82   /**
     83    * Index of the coin involved in the transaction.  Recall:
     84    * at the exchange, the tracking is done _per coin_.
     85    */
     86   unsigned int coin_index;
     87 
     88   /**
     89    * Handle to the "track transaction" pending operation.
     90    */
     91   struct TALER_EXCHANGE_DepositGetHandle *tth;
     92 
     93   /**
     94    * Interpreter state.
     95    */
     96   struct TALER_TESTING_Interpreter *is;
     97 };
     98 
     99 
    100 /**
    101  * Checks what is returned by the "track transaction" operation.
    102  * Checks that the HTTP response code is acceptable, and - if the
    103  * right reference is non NULL - that the wire transfer subject
    104  * line matches our expectations.
    105  *
    106  * @param cls closure.
    107  * @param dr GET deposit response details
    108  */
    109 static void
    110 deposit_wtid_cb (
    111   void *cls,
    112   const struct TALER_EXCHANGE_GetDepositResponse *dr)
    113 {
    114   struct TrackTransactionState *tts = cls;
    115   struct TALER_TESTING_Interpreter *is = tts->is;
    116 
    117   tts->tth = NULL;
    118   if (tts->expected_response_code != dr->hr.http_status)
    119   {
    120     TALER_TESTING_unexpected_status (is,
    121                                      dr->hr.http_status,
    122                                      tts->expected_response_code);
    123     return;
    124   }
    125   switch (dr->hr.http_status)
    126   {
    127   case MHD_HTTP_OK:
    128     tts->wtid = dr->details.ok.wtid;
    129     if (NULL != tts->bank_transfer_reference)
    130     {
    131       const struct TALER_TESTING_Command *bank_transfer_cmd;
    132       const struct TALER_WireTransferIdentifierRawP *wtid_want;
    133 
    134       /* _this_ wire transfer subject line.  */
    135       bank_transfer_cmd
    136         = TALER_TESTING_interpreter_lookup_command (is,
    137                                                     tts->bank_transfer_reference
    138                                                     );
    139       if (NULL == bank_transfer_cmd)
    140       {
    141         GNUNET_break (0);
    142         TALER_TESTING_interpreter_fail (is);
    143         return;
    144       }
    145 
    146       if (GNUNET_OK !=
    147           TALER_TESTING_get_trait_wtid (bank_transfer_cmd,
    148                                         &wtid_want))
    149       {
    150         GNUNET_break (0);
    151         TALER_TESTING_interpreter_fail (is);
    152         return;
    153       }
    154 
    155       /* Compare that expected and gotten subjects match.  */
    156       if (0 != GNUNET_memcmp (&dr->details.ok.wtid,
    157                               wtid_want))
    158       {
    159         GNUNET_break (0);
    160         TALER_TESTING_interpreter_fail (tts->is);
    161         return;
    162       }
    163     }
    164     break;
    165   case MHD_HTTP_ACCEPTED:
    166     /* allowed, nothing to check here */
    167     TALER_full_payto_normalize_and_hash (tts->merchant_payto_uri,
    168                                          &tts->h_payto);
    169     tts->requirement_row
    170       = dr->details.accepted.requirement_row;
    171     break;
    172   case MHD_HTTP_NOT_FOUND:
    173     /* allowed, nothing to check here */
    174     break;
    175   default:
    176     GNUNET_break (0);
    177     break;
    178   }
    179   TALER_TESTING_interpreter_next (tts->is);
    180 }
    181 
    182 
    183 /**
    184  * Run the command.
    185  *
    186  * @param cls closure.
    187  * @param cmd the command to execute.
    188  * @param is the interpreter state.
    189  */
    190 static void
    191 deposits_get_run (
    192   void *cls,
    193   const struct TALER_TESTING_Command *cmd,
    194   struct TALER_TESTING_Interpreter *is)
    195 {
    196   struct TrackTransactionState *tts = cls;
    197   const struct TALER_TESTING_Command *transaction_cmd;
    198   const struct TALER_CoinSpendPrivateKeyP *coin_priv;
    199   struct TALER_CoinSpendPublicKeyP coin_pub;
    200   const json_t *contract_terms;
    201   const json_t *wire_details;
    202   struct TALER_MerchantWireHashP h_wire_details;
    203   struct TALER_PrivateContractHashP h_contract_terms;
    204   const struct TALER_MerchantPrivateKeyP *merchant_priv;
    205 
    206   tts->cmd = cmd;
    207   tts->is = is;
    208   transaction_cmd
    209     = TALER_TESTING_interpreter_lookup_command (tts->is,
    210                                                 tts->transaction_reference);
    211   if (NULL == transaction_cmd)
    212   {
    213     GNUNET_break (0);
    214     TALER_TESTING_interpreter_fail (tts->is);
    215     return;
    216   }
    217 
    218   if (GNUNET_OK !=
    219       TALER_TESTING_get_trait_coin_priv (transaction_cmd,
    220                                          tts->coin_index,
    221                                          &coin_priv))
    222   {
    223     GNUNET_break (0);
    224     TALER_TESTING_interpreter_fail (tts->is);
    225     return;
    226   }
    227 
    228   GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
    229                                       &coin_pub.eddsa_pub);
    230 
    231   /* Get the strings.. */
    232   if (GNUNET_OK !=
    233       TALER_TESTING_get_trait_wire_details (transaction_cmd,
    234                                             &wire_details))
    235   {
    236     GNUNET_break (0);
    237     TALER_TESTING_interpreter_fail (tts->is);
    238     return;
    239   }
    240   tts->merchant_payto_uri.full_payto
    241     = GNUNET_strdup (json_string_value (json_object_get (wire_details,
    242                                                          "payto_uri")));
    243   if (GNUNET_OK !=
    244       TALER_TESTING_get_trait_contract_terms (transaction_cmd,
    245                                               &contract_terms))
    246   {
    247     GNUNET_break (0);
    248     TALER_TESTING_interpreter_fail (tts->is);
    249     return;
    250   }
    251 
    252   if ( (NULL == wire_details) ||
    253        (NULL == contract_terms) )
    254   {
    255     GNUNET_break (0);
    256     TALER_TESTING_interpreter_fail (tts->is);
    257     return;
    258   }
    259 
    260   /* Should not fail here, json has been parsed already */
    261   GNUNET_assert
    262     ( (GNUNET_OK ==
    263        TALER_JSON_merchant_wire_signature_hash (wire_details,
    264                                                 &h_wire_details)) &&
    265     (GNUNET_OK ==
    266      TALER_JSON_contract_hash (contract_terms,
    267                                &h_contract_terms)) );
    268 
    269   if (GNUNET_OK !=
    270       TALER_TESTING_get_trait_merchant_priv (transaction_cmd,
    271                                              &merchant_priv))
    272   {
    273     GNUNET_break (0);
    274     TALER_TESTING_interpreter_fail (tts->is);
    275     return;
    276   }
    277 
    278   tts->tth = TALER_EXCHANGE_deposits_get (
    279     TALER_TESTING_interpreter_get_context (is),
    280     TALER_TESTING_get_exchange_url (is),
    281     TALER_TESTING_get_keys (is),
    282     merchant_priv,
    283     &h_wire_details,
    284     &h_contract_terms,
    285     &coin_pub,
    286     GNUNET_TIME_UNIT_ZERO,
    287     &deposit_wtid_cb,
    288     tts);
    289   GNUNET_assert (NULL != tts->tth);
    290 }
    291 
    292 
    293 /**
    294  * Cleanup the state from a "track transaction" CMD, and possibly
    295  * cancel a operation thereof.
    296  *
    297  * @param cls closure.
    298  * @param cmd the command which is being cleaned up.
    299  */
    300 static void
    301 deposits_get_cleanup (
    302   void *cls,
    303   const struct TALER_TESTING_Command *cmd)
    304 {
    305   struct TrackTransactionState *tts = cls;
    306 
    307   if (NULL != tts->tth)
    308   {
    309     TALER_TESTING_command_incomplete (tts->is,
    310                                       cmd->label);
    311     TALER_EXCHANGE_deposits_get_cancel (tts->tth);
    312     tts->tth = NULL;
    313   }
    314   GNUNET_free (tts->merchant_payto_uri.full_payto);
    315   GNUNET_free (tts);
    316 }
    317 
    318 
    319 /**
    320  * Offer internal data from a "track transaction" CMD.
    321  *
    322  * @param cls closure.
    323  * @param[out] ret result (could be anything).
    324  * @param trait name of the trait.
    325  * @param index index number of the object to offer.
    326  * @return #GNUNET_OK on success.
    327  */
    328 static enum GNUNET_GenericReturnValue
    329 deposits_get_traits (void *cls,
    330                      const void **ret,
    331                      const char *trait,
    332                      unsigned int index)
    333 {
    334   struct TrackTransactionState *tts = cls;
    335   struct TALER_TESTING_Trait traits[] = {
    336     TALER_TESTING_make_trait_wtid (&tts->wtid),
    337     TALER_TESTING_make_trait_legi_requirement_row (
    338       &tts->requirement_row),
    339     TALER_TESTING_make_trait_h_normalized_payto (&tts->h_payto),
    340     TALER_TESTING_make_trait_full_payto_uri (&tts->merchant_payto_uri),
    341     TALER_TESTING_trait_end ()
    342   };
    343 
    344   return TALER_TESTING_get_trait (traits,
    345                                   ret,
    346                                   trait,
    347                                   index);
    348 }
    349 
    350 
    351 struct TALER_TESTING_Command
    352 TALER_TESTING_cmd_deposits_get (
    353   const char *label,
    354   const char *transaction_reference,
    355   unsigned int coin_index,
    356   unsigned int expected_response_code,
    357   const char *bank_transfer_reference)
    358 {
    359   struct TrackTransactionState *tts;
    360 
    361   tts = GNUNET_new (struct TrackTransactionState);
    362   tts->transaction_reference = transaction_reference;
    363   tts->expected_response_code = expected_response_code;
    364   tts->bank_transfer_reference = bank_transfer_reference;
    365   tts->coin_index = coin_index;
    366   {
    367     struct TALER_TESTING_Command cmd = {
    368       .cls = tts,
    369       .label = label,
    370       .run = &deposits_get_run,
    371       .cleanup = &deposits_get_cleanup,
    372       .traits = &deposits_get_traits
    373     };
    374 
    375     return cmd;
    376   }
    377 }
    378 
    379 
    380 /* end of testing_api_cmd_deposits_get.c */