LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_bank_admin_add_kycauth.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 62.0 % 108 67
Test Date: 2026-04-14 15:39:31 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2024 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_bank_admin_add_kycauth.c
      21              :  * @brief implementation of a bank /admin/add-kycauth command
      22              :  * @author Christian Grothoff
      23              :  * @author Marcello Stanisci
      24              :  */
      25              : #include "taler/taler_json_lib.h"
      26              : #include <gnunet/gnunet_curl_lib.h>
      27              : #include "taler/taler_bank_service.h"
      28              : #include "taler/taler_signatures.h"
      29              : #include "taler/taler_testing_lib.h"
      30              : 
      31              : 
      32              : /**
      33              :  * State for a KYCAUTH wire transfer CMD.
      34              :  */
      35              : struct AdminAddKycauthState
      36              : {
      37              : 
      38              :   /**
      39              :    * Label of any command that can trait-offer an account priv.
      40              :    */
      41              :   const char *account_ref;
      42              : 
      43              :   /**
      44              :    * Wire transfer amount.
      45              :    */
      46              :   struct TALER_Amount amount;
      47              : 
      48              :   /**
      49              :    * Base URL of the credited account.
      50              :    */
      51              :   const char *exchange_credit_url;
      52              : 
      53              :   /**
      54              :    * Money sender payto URL.
      55              :    */
      56              :   struct TALER_FullPayto payto_debit_account;
      57              : 
      58              :   /**
      59              :    * Username to use for authentication.
      60              :    */
      61              :   struct TALER_BANK_AuthenticationData auth;
      62              : 
      63              :   /**
      64              :    * Set (by the interpreter) to the account's private key
      65              :    * we used to make a wire transfer subject line with.
      66              :    */
      67              :   union TALER_AccountPrivateKeyP account_priv;
      68              : 
      69              :   /**
      70              :    * Account public key matching @e account_priv.
      71              :    */
      72              :   union TALER_AccountPublicKeyP account_pub;
      73              : 
      74              :   /**
      75              :    * Handle to the pending request at the bank.
      76              :    */
      77              :   struct TALER_BANK_AdminAddKycauthHandle *aih;
      78              : 
      79              :   /**
      80              :    * Interpreter state.
      81              :    */
      82              :   struct TALER_TESTING_Interpreter *is;
      83              : 
      84              :   /**
      85              :    * Set to the wire transfer's unique ID.
      86              :    */
      87              :   uint64_t serial_id;
      88              : 
      89              :   /**
      90              :    * Timestamp of the transaction (as returned from the bank).
      91              :    */
      92              :   struct GNUNET_TIME_Timestamp timestamp;
      93              : 
      94              :   /**
      95              :    * Expected HTTP status code.
      96              :    */
      97              :   unsigned int expected_http_status;
      98              : 
      99              :   /**
     100              :    * Do we have @e account_priv?
     101              :    */
     102              :   bool have_priv;
     103              : };
     104              : 
     105              : 
     106              : /**
     107              :  * This callback will process the bank response to the wire
     108              :  * transfer.  It just checks whether the HTTP response code is
     109              :  * acceptable.
     110              :  *
     111              :  * @param cls closure with the interpreter state
     112              :  * @param air response details
     113              :  */
     114              : static void
     115           16 : confirmation_cb (void *cls,
     116              :                  const struct TALER_BANK_AdminAddKycauthResponse *air)
     117              : {
     118           16 :   struct AdminAddKycauthState *fts = cls;
     119           16 :   struct TALER_TESTING_Interpreter *is = fts->is;
     120              : 
     121           16 :   fts->aih = NULL;
     122           16 :   if (air->http_status != fts->expected_http_status)
     123              :   {
     124            0 :     TALER_TESTING_unexpected_status (is,
     125              :                                      air->http_status,
     126              :                                      fts->expected_http_status);
     127            0 :     return;
     128              :   }
     129           16 :   switch (air->http_status)
     130              :   {
     131           16 :   case MHD_HTTP_OK:
     132              :     fts->serial_id
     133           16 :       = air->details.ok.serial_id;
     134              :     fts->timestamp
     135           16 :       = air->details.ok.timestamp;
     136           16 :     TALER_TESTING_interpreter_next (is);
     137           16 :     return;
     138            0 :   case MHD_HTTP_UNAUTHORIZED:
     139            0 :     switch (fts->auth.method)
     140              :     {
     141            0 :     case TALER_BANK_AUTH_NONE:
     142            0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     143              :                   "Authentication required, but none configure.\n");
     144            0 :       break;
     145            0 :     case TALER_BANK_AUTH_BASIC:
     146            0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     147              :                   "Basic authentication (%s) failed.\n",
     148              :                   fts->auth.details.basic.username);
     149            0 :       break;
     150            0 :     case TALER_BANK_AUTH_BEARER:
     151            0 :       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     152              :                   "Bearer authentication (%s) failed.\n",
     153              :                   fts->auth.details.bearer.token);
     154            0 :       break;
     155              :     }
     156            0 :     break;
     157            0 :   case MHD_HTTP_CONFLICT:
     158            0 :     TALER_TESTING_interpreter_next (is);
     159            0 :     return;
     160            0 :   default:
     161            0 :     GNUNET_break (0);
     162            0 :     break;
     163              :   }
     164            0 :   GNUNET_break (0);
     165            0 :   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     166              :               "Bank returned HTTP status %u/%d\n",
     167              :               air->http_status,
     168              :               (int) air->ec);
     169            0 :   TALER_TESTING_interpreter_fail (is);
     170              : }
     171              : 
     172              : 
     173              : /**
     174              :  * Run the KYC AUTH transfer CMD.
     175              :  *
     176              :  * @param cls closure.
     177              :  * @param cmd CMD being run.
     178              :  * @param is interpreter state.
     179              :  */
     180              : static void
     181           16 : admin_add_kycauth_run (void *cls,
     182              :                        const struct TALER_TESTING_Command *cmd,
     183              :                        struct TALER_TESTING_Interpreter *is)
     184              : {
     185           16 :   struct AdminAddKycauthState *fts = cls;
     186              : 
     187              :   (void) cmd;
     188           16 :   fts->is = is;
     189              :   /* Use account public key as subject */
     190           16 :   if (NULL != fts->account_ref)
     191              :   {
     192              :     const struct TALER_TESTING_Command *ref;
     193              :     const union TALER_AccountPrivateKeyP *account_priv;
     194              : 
     195           10 :     ref = TALER_TESTING_interpreter_lookup_command (
     196              :       is,
     197              :       fts->account_ref);
     198           10 :     if (NULL == ref)
     199              :     {
     200            0 :       GNUNET_break (0);
     201            0 :       TALER_TESTING_interpreter_fail (is);
     202            0 :       return;
     203              :     }
     204           10 :     if (GNUNET_OK !=
     205           10 :         TALER_TESTING_get_trait_account_priv (ref,
     206              :                                               &account_priv))
     207              :     {
     208              :       const union TALER_AccountPublicKeyP *account_pub;
     209              : 
     210            0 :       if (GNUNET_OK !=
     211            0 :           TALER_TESTING_get_trait_account_pub (ref,
     212              :                                                &account_pub))
     213              :       {
     214            0 :         GNUNET_break (0);
     215            0 :         TALER_TESTING_interpreter_fail (is);
     216            0 :         return;
     217              :       }
     218            0 :       fts->account_pub = *account_pub;
     219              :     }
     220              :     else
     221              :     {
     222           10 :       fts->account_priv = *account_priv;
     223           10 :       fts->have_priv = true;
     224           10 :       GNUNET_CRYPTO_eddsa_key_get_public (
     225           10 :         &fts->account_priv.merchant_priv.eddsa_priv,
     226              :         &fts->account_pub.merchant_pub.eddsa_pub);
     227              :     }
     228              :   }
     229              :   else
     230              :   {
     231              :     /* No referenced account, no instance to take priv
     232              :      * from, no explicit subject given: create new key! */
     233            6 :     GNUNET_CRYPTO_eddsa_key_create (
     234              :       &fts->account_priv.merchant_priv.eddsa_priv);
     235            6 :     fts->have_priv = true;
     236            6 :     GNUNET_CRYPTO_eddsa_key_get_public (
     237            6 :       &fts->account_priv.merchant_priv.eddsa_priv,
     238              :       &fts->account_pub.merchant_pub.eddsa_pub);
     239              :   }
     240              :   fts->aih
     241           16 :     = TALER_BANK_admin_add_kycauth (
     242              :         TALER_TESTING_interpreter_get_context (is),
     243           16 :         &fts->auth,
     244           16 :         &fts->account_pub,
     245           16 :         &fts->amount,
     246              :         fts->payto_debit_account,
     247              :         &confirmation_cb,
     248              :         fts);
     249           16 :   if (NULL == fts->aih)
     250              :   {
     251            0 :     GNUNET_break (0);
     252            0 :     TALER_TESTING_interpreter_fail (is);
     253            0 :     return;
     254              :   }
     255              : }
     256              : 
     257              : 
     258              : /**
     259              :  * Free the state of a "/admin/add-kycauth" CMD, and possibly
     260              :  * cancel a pending operation thereof.
     261              :  *
     262              :  * @param cls closure
     263              :  * @param cmd current CMD being cleaned up.
     264              :  */
     265              : static void
     266           16 : admin_add_kycauth_cleanup (void *cls,
     267              :                            const struct TALER_TESTING_Command *cmd)
     268              : {
     269           16 :   struct AdminAddKycauthState *fts = cls;
     270              : 
     271           16 :   if (NULL != fts->aih)
     272              :   {
     273            0 :     TALER_TESTING_command_incomplete (fts->is,
     274              :                                       cmd->label);
     275            0 :     TALER_BANK_admin_add_kycauth_cancel (fts->aih);
     276            0 :     fts->aih = NULL;
     277              :   }
     278           16 :   GNUNET_free (fts);
     279           16 : }
     280              : 
     281              : 
     282              : /**
     283              :  * Offer internal data from a "/admin/add-kycauth" CMD to other
     284              :  * commands.
     285              :  *
     286              :  * @param cls closure.
     287              :  * @param[out] ret result
     288              :  * @param trait name of the trait.
     289              :  * @param index index number of the object to offer.
     290              :  * @return #GNUNET_OK on success.
     291              :  */
     292              : static enum GNUNET_GenericReturnValue
     293           33 : admin_add_kycauth_traits (void *cls,
     294              :                           const void **ret,
     295              :                           const char *trait,
     296              :                           unsigned int index)
     297              : {
     298           33 :   struct AdminAddKycauthState *fts = cls;
     299              :   static struct TALER_FullPayto void_uri = {
     300              :     .full_payto = (char *) "payto://void/the-exchange?receiver=name=exchange"
     301              :   };
     302              :   struct TALER_TESTING_Trait traits[] = {
     303              :     /* must be first! */
     304           33 :     TALER_TESTING_make_trait_account_priv (&fts->account_priv),
     305           33 :     TALER_TESTING_make_trait_bank_row (&fts->serial_id),
     306           33 :     TALER_TESTING_make_trait_debit_payto_uri (&fts->payto_debit_account),
     307           33 :     TALER_TESTING_make_trait_full_payto_uri (&fts->payto_debit_account),
     308              :     /* Used as a marker, content does not matter */
     309           33 :     TALER_TESTING_make_trait_credit_payto_uri (&void_uri),
     310           33 :     TALER_TESTING_make_trait_exchange_bank_account_url (
     311              :       fts->exchange_credit_url),
     312           33 :     TALER_TESTING_make_trait_amount (&fts->amount),
     313           33 :     TALER_TESTING_make_trait_timestamp (0,
     314           33 :                                         &fts->timestamp),
     315           33 :     TALER_TESTING_make_trait_account_pub (&fts->account_pub),
     316           33 :     TALER_TESTING_trait_end ()
     317              :   };
     318              : 
     319           33 :   if (MHD_HTTP_OK !=
     320           33 :       fts->expected_http_status)
     321            0 :     return GNUNET_NO; /* requests that failed generate no history */
     322              : 
     323           33 :   return TALER_TESTING_get_trait (traits + (fts->have_priv ? 0 : 1),
     324              :                                   ret,
     325              :                                   trait,
     326              :                                   index);
     327              : }
     328              : 
     329              : 
     330              : /**
     331              :  * Create internal state for "/admin/add-kycauth" CMD.
     332              :  *
     333              :  * @param amount the amount to transfer.
     334              :  * @param payto_debit_account which account sends money
     335              :  * @param auth authentication data
     336              :  * @param account_ref reference to command with account
     337              :  *    private key to use; NULL to create a fresh key pair
     338              :  * @return the internal state
     339              :  */
     340              : static struct AdminAddKycauthState *
     341           16 : make_fts (const char *amount,
     342              :           const struct TALER_BANK_AuthenticationData *auth,
     343              :           const struct TALER_FullPayto payto_debit_account,
     344              :           const char *account_ref)
     345              : {
     346              :   struct AdminAddKycauthState *fts;
     347              : 
     348           16 :   fts = GNUNET_new (struct AdminAddKycauthState);
     349           16 :   fts->exchange_credit_url = auth->wire_gateway_url;
     350           16 :   fts->payto_debit_account = payto_debit_account;
     351           16 :   fts->account_ref = account_ref;
     352           16 :   fts->auth = *auth;
     353           16 :   fts->expected_http_status = MHD_HTTP_OK;
     354           16 :   if (GNUNET_OK !=
     355           16 :       TALER_string_to_amount (amount,
     356              :                               &fts->amount))
     357              :   {
     358            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     359              :                 "Failed to parse amount `%s'\n",
     360              :                 amount);
     361            0 :     GNUNET_assert (0);
     362              :   }
     363           16 :   return fts;
     364              : }
     365              : 
     366              : 
     367              : struct TALER_TESTING_Command
     368           16 : TALER_TESTING_cmd_admin_add_kycauth (
     369              :   const char *label,
     370              :   const char *amount,
     371              :   const struct TALER_BANK_AuthenticationData *auth,
     372              :   const struct TALER_FullPayto payto_debit_account,
     373              :   const char *account_ref)
     374              : {
     375           32 :   struct TALER_TESTING_Command cmd = {
     376           16 :     .cls = make_fts (amount,
     377              :                      auth,
     378              :                      payto_debit_account,
     379              :                      account_ref),
     380              :     .label = label,
     381              :     .run = &admin_add_kycauth_run,
     382              :     .cleanup = &admin_add_kycauth_cleanup,
     383              :     .traits = &admin_add_kycauth_traits
     384              :   };
     385              : 
     386           16 :   return cmd;
     387              : }
     388              : 
     389              : 
     390              : /* end of testing_api_cmd_bank_admin_add_kycauth.c */
        

Generated by: LCOV version 2.0-1