LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_contract_get.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 65.7 % 99 65
Test Date: 2026-04-14 15:39:31 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2022 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify it
       6              :   under the terms of the GNU General Public License as published by
       7              :   the Free Software Foundation; either version 3, or (at your
       8              :   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 GNU
      13              :   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_contract_get.c
      21              :  * @brief command for testing GET /contracts/$CPUB
      22              :  * @author Christian Grothoff
      23              :  */
      24              : #include "taler/taler_json_lib.h"
      25              : #include <gnunet/gnunet_curl_lib.h>
      26              : #include "taler/taler_testing_lib.h"
      27              : #include "taler/taler_signatures.h"
      28              : 
      29              : 
      30              : /**
      31              :  * State for a "contract get" CMD.
      32              :  */
      33              : struct ContractGetState
      34              : {
      35              : 
      36              :   /**
      37              :    * JSON string describing the resulting contract.
      38              :    */
      39              :   json_t *contract_terms;
      40              : 
      41              :   /**
      42              :    * Private key to decrypt the contract.
      43              :    */
      44              :   struct TALER_ContractDiffiePrivateP contract_priv;
      45              : 
      46              :   /**
      47              :    * Set to the returned merge key.
      48              :    */
      49              :   struct TALER_PurseMergePrivateKeyP merge_priv;
      50              : 
      51              :   /**
      52              :    * Public key of the purse.
      53              :    */
      54              :   struct TALER_PurseContractPublicKeyP purse_pub;
      55              : 
      56              :   /**
      57              :    * Reference to the command that uploaded the contract.
      58              :    */
      59              :   const char *contract_ref;
      60              : 
      61              :   /**
      62              :    * ContractGet handle while operation is running.
      63              :    */
      64              :   struct TALER_EXCHANGE_GetContractsHandle *dh;
      65              : 
      66              :   /**
      67              :    * Interpreter state.
      68              :    */
      69              :   struct TALER_TESTING_Interpreter *is;
      70              : 
      71              :   /**
      72              :    * Expected HTTP response code.
      73              :    */
      74              :   unsigned int expected_response_code;
      75              : 
      76              :   /**
      77              :    * True if this is for a 'merge' operation,
      78              :    * 'false' if this is for a 'deposit' operation.
      79              :    */
      80              :   bool merge;
      81              : 
      82              : };
      83              : 
      84              : 
      85              : /**
      86              :  * Callback to analyze the /contracts/$CPUB response, just used to check if
      87              :  * the response code is acceptable.
      88              :  *
      89              :  * @param cls closure.
      90              :  * @param dr get response details
      91              :  */
      92              : static void
      93            6 : get_cb (void *cls,
      94              :         const struct TALER_EXCHANGE_GetContractsResponse *dr)
      95              : {
      96            6 :   struct ContractGetState *ds = cls;
      97              :   const struct TALER_TESTING_Command *ref;
      98              : 
      99            6 :   ds->dh = NULL;
     100            6 :   if (ds->expected_response_code != dr->hr.http_status)
     101              :   {
     102            0 :     TALER_TESTING_unexpected_status (ds->is,
     103              :                                      dr->hr.http_status,
     104              :                                      ds->expected_response_code);
     105            0 :     return;
     106              :   }
     107            6 :   ref = TALER_TESTING_interpreter_lookup_command (ds->is,
     108              :                                                   ds->contract_ref);
     109            6 :   GNUNET_assert (NULL != ref);
     110            6 :   if (MHD_HTTP_OK == dr->hr.http_status)
     111              :   {
     112              :     const struct TALER_PurseMergePrivateKeyP *mp;
     113              :     const json_t *ct;
     114              : 
     115            6 :     ds->purse_pub = dr->details.ok.purse_pub;
     116            6 :     if (ds->merge)
     117              :     {
     118            3 :       if (GNUNET_OK !=
     119            3 :           TALER_TESTING_get_trait_merge_priv (ref,
     120              :                                               &mp))
     121              :       {
     122            0 :         GNUNET_break (0);
     123            0 :         TALER_TESTING_interpreter_fail (ds->is);
     124            0 :         return;
     125              :       }
     126            3 :       ds->contract_terms =
     127            3 :         TALER_CRYPTO_contract_decrypt_for_merge (
     128            3 :           &ds->contract_priv,
     129            3 :           &ds->purse_pub,
     130            3 :           dr->details.ok.econtract,
     131            3 :           dr->details.ok.econtract_size,
     132              :           &ds->merge_priv);
     133            3 :       if (0 !=
     134            3 :           GNUNET_memcmp (mp,
     135              :                          &ds->merge_priv))
     136              :       {
     137            0 :         GNUNET_break (0);
     138            0 :         TALER_TESTING_interpreter_fail (ds->is);
     139            0 :         return;
     140              :       }
     141              :     }
     142              :     else
     143              :     {
     144            3 :       ds->contract_terms =
     145            3 :         TALER_CRYPTO_contract_decrypt_for_deposit (
     146            3 :           &ds->contract_priv,
     147            3 :           dr->details.ok.econtract,
     148            3 :           dr->details.ok.econtract_size);
     149              :     }
     150            6 :     if (NULL == ds->contract_terms)
     151              :     {
     152            0 :       GNUNET_break (0);
     153            0 :       TALER_TESTING_interpreter_fail (ds->is);
     154            0 :       return;
     155              :     }
     156            6 :     if (GNUNET_OK !=
     157            6 :         TALER_TESTING_get_trait_contract_terms (ref,
     158              :                                                 &ct))
     159              :     {
     160            0 :       GNUNET_break (0);
     161            0 :       TALER_TESTING_interpreter_fail (ds->is);
     162            0 :       return;
     163              :     }
     164            6 :     if (1 != /* 1: equal, 0: not equal */
     165            6 :         json_equal (ct,
     166            6 :                     ds->contract_terms))
     167              :     {
     168            0 :       GNUNET_break (0);
     169            0 :       TALER_TESTING_interpreter_fail (ds->is);
     170            0 :       return;
     171              :     }
     172              :   }
     173            6 :   TALER_TESTING_interpreter_next (ds->is);
     174              : }
     175              : 
     176              : 
     177              : /**
     178              :  * Run the command.
     179              :  *
     180              :  * @param cls closure.
     181              :  * @param cmd the command to execute.
     182              :  * @param is the interpreter state.
     183              :  */
     184              : static void
     185            6 : get_run (void *cls,
     186              :          const struct TALER_TESTING_Command *cmd,
     187              :          struct TALER_TESTING_Interpreter *is)
     188              : {
     189            6 :   struct ContractGetState *ds = cls;
     190              :   const struct TALER_ContractDiffiePrivateP *contract_priv;
     191              :   const struct TALER_TESTING_Command *ref;
     192              :   const char *exchange_url;
     193              : 
     194              :   (void) cmd;
     195            6 :   ds->is = is;
     196            6 :   exchange_url = TALER_TESTING_get_exchange_url (is);
     197            6 :   if (NULL == exchange_url)
     198              :   {
     199            0 :     GNUNET_break (0);
     200            0 :     return;
     201              :   }
     202            6 :   ref = TALER_TESTING_interpreter_lookup_command (ds->is,
     203              :                                                   ds->contract_ref);
     204            6 :   GNUNET_assert (NULL != ref);
     205            6 :   if (GNUNET_OK !=
     206            6 :       TALER_TESTING_get_trait_contract_priv (ref,
     207              :                                              &contract_priv))
     208              :   {
     209            0 :     GNUNET_break (0);
     210            0 :     TALER_TESTING_interpreter_fail (ds->is);
     211            0 :     return;
     212              :   }
     213            6 :   ds->contract_priv = *contract_priv;
     214            6 :   ds->dh = TALER_EXCHANGE_get_contracts_create (
     215              :     TALER_TESTING_interpreter_get_context (is),
     216              :     exchange_url,
     217              :     contract_priv);
     218            6 :   if (NULL == ds->dh)
     219              :   {
     220            0 :     GNUNET_break (0);
     221            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     222              :                 "Could not GET contract\n");
     223            0 :     TALER_TESTING_interpreter_fail (is);
     224            0 :     return;
     225              :   }
     226            6 :   if (TALER_EC_NONE !=
     227            6 :       TALER_EXCHANGE_get_contracts_start (ds->dh,
     228              :                                           &get_cb,
     229              :                                           ds))
     230              :   {
     231            0 :     GNUNET_break (0);
     232            0 :     TALER_EXCHANGE_get_contracts_cancel (ds->dh);
     233            0 :     ds->dh = NULL;
     234            0 :     TALER_TESTING_interpreter_fail (is);
     235            0 :     return;
     236              :   }
     237              : }
     238              : 
     239              : 
     240              : /**
     241              :  * Free the state of a "get" CMD, and possibly cancel a
     242              :  * pending operation thereof.
     243              :  *
     244              :  * @param cls closure, must be a `struct ContractGetState`.
     245              :  * @param cmd the command which is being cleaned up.
     246              :  */
     247              : static void
     248            6 : get_cleanup (void *cls,
     249              :              const struct TALER_TESTING_Command *cmd)
     250              : {
     251            6 :   struct ContractGetState *ds = cls;
     252              : 
     253            6 :   if (NULL != ds->dh)
     254              :   {
     255            0 :     TALER_TESTING_command_incomplete (ds->is,
     256              :                                       cmd->label);
     257            0 :     TALER_EXCHANGE_get_contracts_cancel (ds->dh);
     258            0 :     ds->dh = NULL;
     259              :   }
     260            6 :   json_decref (ds->contract_terms);
     261            6 :   GNUNET_free (ds);
     262            6 : }
     263              : 
     264              : 
     265              : /**
     266              :  * Offer internal data from a "get" CMD, to other commands.
     267              :  *
     268              :  * @param cls closure.
     269              :  * @param[out] ret result.
     270              :  * @param trait name of the trait.
     271              :  * @param index index number of the object to offer.
     272              :  * @return #GNUNET_OK on success.
     273              :  */
     274              : static enum GNUNET_GenericReturnValue
     275           29 : get_traits (void *cls,
     276              :             const void **ret,
     277              :             const char *trait,
     278              :             unsigned int index)
     279              : {
     280           29 :   struct ContractGetState *ds = cls;
     281              :   struct TALER_TESTING_Trait traits[] = {
     282           29 :     TALER_TESTING_make_trait_merge_priv (&ds->merge_priv),
     283           29 :     TALER_TESTING_make_trait_purse_pub (&ds->purse_pub),
     284           29 :     TALER_TESTING_make_trait_contract_terms (ds->contract_terms),
     285           29 :     TALER_TESTING_trait_end ()
     286              :   };
     287              : 
     288              :   /* skip 'merge_priv' if we are in 'merge' mode */
     289           29 :   return TALER_TESTING_get_trait (&traits[ds->merge ? 0 : 1],
     290              :                                   ret,
     291              :                                   trait,
     292              :                                   index);
     293              : }
     294              : 
     295              : 
     296              : struct TALER_TESTING_Command
     297            6 : TALER_TESTING_cmd_contract_get (
     298              :   const char *label,
     299              :   unsigned int expected_http_status,
     300              :   bool for_merge,
     301              :   const char *contract_ref)
     302              : {
     303              :   struct ContractGetState *ds;
     304              : 
     305            6 :   ds = GNUNET_new (struct ContractGetState);
     306            6 :   ds->expected_response_code = expected_http_status;
     307            6 :   ds->contract_ref = contract_ref;
     308            6 :   ds->merge = for_merge;
     309              :   {
     310            6 :     struct TALER_TESTING_Command cmd = {
     311              :       .cls = ds,
     312              :       .label = label,
     313              :       .run = &get_run,
     314              :       .cleanup = &get_cleanup,
     315              :       .traits = &get_traits
     316              :     };
     317              : 
     318            6 :     return cmd;
     319              :   }
     320              : }
     321              : 
     322              : 
     323              : /* end of testing_api_cmd_contract_get.c */
        

Generated by: LCOV version 2.0-1