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_reserve_close.c (6657B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014-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  * @file testing/testing_api_cmd_reserve_close.c
     21  * @brief Implement the /reserve/$RID/close test command.
     22  * @author Christian Grothoff
     23  */
     24 #include "taler/platform.h"
     25 #include "taler/taler_json_lib.h"
     26 #include <gnunet/gnunet_curl_lib.h>
     27 #include "taler/taler_testing_lib.h"
     28 
     29 
     30 /**
     31  * State for a "close" CMD.
     32  */
     33 struct CloseState
     34 {
     35   /**
     36    * Label to the command which created the reserve to check,
     37    * needed to resort the reserve key.
     38    */
     39   const char *reserve_reference;
     40 
     41   /**
     42    * Handle to the "reserve close" operation.
     43    */
     44   struct TALER_EXCHANGE_ReservesCloseHandle *rsh;
     45 
     46   /**
     47    * payto://-URI where to wire the funds.
     48    */
     49   struct TALER_FullPayto target_account;
     50 
     51   /**
     52    * Private key of the reserve being analyzed.
     53    */
     54   const struct TALER_ReservePrivateKeyP *reserve_priv;
     55 
     56   /**
     57    * Public key of the reserve being analyzed.
     58    */
     59   struct TALER_ReservePublicKeyP reserve_pub;
     60 
     61   /**
     62    * Expected HTTP response code.
     63    */
     64   unsigned int expected_response_code;
     65 
     66   /**
     67    * Interpreter state.
     68    */
     69   struct TALER_TESTING_Interpreter *is;
     70 
     71   /**
     72    * Set to the KYC requirement payto hash *if* the exchange replied with a
     73    * request for KYC.
     74    */
     75   struct TALER_NormalizedPaytoHashP h_payto;
     76 
     77   /**
     78    * Set to the KYC requirement row *if* the exchange replied with
     79    * a request for KYC.
     80    */
     81   uint64_t requirement_row;
     82 };
     83 
     84 
     85 /**
     86  * Check that the reserve balance and HTTP response code are
     87  * both acceptable.
     88  *
     89  * @param cls closure.
     90  * @param rs HTTP response details
     91  */
     92 static void
     93 reserve_close_cb (void *cls,
     94                   const struct TALER_EXCHANGE_ReserveCloseResult *rs)
     95 {
     96   struct CloseState *ss = cls;
     97   struct TALER_TESTING_Interpreter *is = ss->is;
     98 
     99   ss->rsh = NULL;
    100   if (ss->expected_response_code != rs->hr.http_status)
    101   {
    102     TALER_TESTING_unexpected_status (ss->is,
    103                                      rs->hr.http_status,
    104                                      ss->expected_response_code);
    105     json_dumpf (rs->hr.reply,
    106                 stderr,
    107                 JSON_INDENT (2));
    108     return;
    109   }
    110   switch (rs->hr.http_status)
    111   {
    112   case MHD_HTTP_OK:
    113     break;
    114   case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
    115     /* nothing to check */
    116     ss->requirement_row
    117       = rs->details.unavailable_for_legal_reasons.requirement_row;
    118     ss->h_payto
    119       = rs->details.unavailable_for_legal_reasons.h_payto;
    120     break;
    121   default:
    122     break;
    123   }
    124   TALER_TESTING_interpreter_next (is);
    125 }
    126 
    127 
    128 /**
    129  * Run the command.
    130  *
    131  * @param cls closure.
    132  * @param cmd the command being executed.
    133  * @param is the interpreter state.
    134  */
    135 static void
    136 close_run (void *cls,
    137            const struct TALER_TESTING_Command *cmd,
    138            struct TALER_TESTING_Interpreter *is)
    139 {
    140   struct CloseState *ss = cls;
    141   const struct TALER_TESTING_Command *create_reserve;
    142 
    143   ss->is = is;
    144   create_reserve
    145     = TALER_TESTING_interpreter_lookup_command (is,
    146                                                 ss->reserve_reference);
    147 
    148   if (NULL == create_reserve)
    149   {
    150     GNUNET_break (0);
    151     TALER_TESTING_interpreter_fail (is);
    152     return;
    153   }
    154   if (GNUNET_OK !=
    155       TALER_TESTING_get_trait_reserve_priv (create_reserve,
    156                                             &ss->reserve_priv))
    157   {
    158     GNUNET_break (0);
    159     TALER_LOG_ERROR ("Failed to find reserve_priv for close query\n");
    160     TALER_TESTING_interpreter_fail (is);
    161     return;
    162   }
    163   GNUNET_CRYPTO_eddsa_key_get_public (&ss->reserve_priv->eddsa_priv,
    164                                       &ss->reserve_pub.eddsa_pub);
    165   ss->rsh = TALER_EXCHANGE_reserves_close (
    166     TALER_TESTING_interpreter_get_context (is),
    167     TALER_TESTING_get_exchange_url (is),
    168     ss->reserve_priv,
    169     ss->target_account,
    170     &reserve_close_cb,
    171     ss);
    172 }
    173 
    174 
    175 /**
    176  * Cleanup the state from a "reserve close" CMD, and possibly
    177  * cancel a pending operation thereof.
    178  *
    179  * @param cls closure.
    180  * @param cmd the command which is being cleaned up.
    181  */
    182 static void
    183 close_cleanup (void *cls,
    184                const struct TALER_TESTING_Command *cmd)
    185 {
    186   struct CloseState *ss = cls;
    187 
    188   if (NULL != ss->rsh)
    189   {
    190     TALER_TESTING_command_incomplete (ss->is,
    191                                       cmd->label);
    192     TALER_EXCHANGE_reserves_close_cancel (ss->rsh);
    193     ss->rsh = NULL;
    194   }
    195   GNUNET_free (ss);
    196 }
    197 
    198 
    199 /**
    200  * Offer internal data to a "close" CMD state to other
    201  * commands.
    202  *
    203  * @param cls closure
    204  * @param[out] ret result (could be anything)
    205  * @param trait name of the trait
    206  * @param index index number of the object to offer.
    207  * @return #GNUNET_OK on success
    208  */
    209 static enum GNUNET_GenericReturnValue
    210 close_traits (void *cls,
    211               const void **ret,
    212               const char *trait,
    213               unsigned int index)
    214 {
    215   struct CloseState *cs = cls;
    216   struct TALER_TESTING_Trait traits[] = {
    217     TALER_TESTING_make_trait_legi_requirement_row (
    218       &cs->requirement_row),
    219     TALER_TESTING_make_trait_h_normalized_payto (
    220       &cs->h_payto),
    221     TALER_TESTING_trait_end ()
    222   };
    223 
    224   if (cs->expected_response_code != MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)
    225     return GNUNET_NO;
    226   return TALER_TESTING_get_trait (traits,
    227                                   ret,
    228                                   trait,
    229                                   index);
    230 }
    231 
    232 
    233 struct TALER_TESTING_Command
    234 TALER_TESTING_cmd_reserve_close (const char *label,
    235                                  const char *reserve_reference,
    236                                  struct TALER_FullPayto target_account,
    237                                  unsigned int expected_response_code)
    238 {
    239   struct CloseState *ss;
    240 
    241   GNUNET_assert (NULL != reserve_reference);
    242   ss = GNUNET_new (struct CloseState);
    243   ss->reserve_reference = reserve_reference;
    244   ss->target_account = target_account;
    245   ss->expected_response_code = expected_response_code;
    246   {
    247     struct TALER_TESTING_Command cmd = {
    248       .cls = ss,
    249       .label = label,
    250       .run = &close_run,
    251       .cleanup = &close_cleanup,
    252       .traits = &close_traits
    253     };
    254 
    255     return cmd;
    256   }
    257 }