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

Generated by: LCOV version 2.0-1