LCOV - code coverage report
Current view: top level - exchange - taler-exchange-httpd_kyc-wallet.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 0 51 0.0 %
Date: 2022-08-25 06:15:09 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2021, 2022 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify it under the
       6             :   terms of the GNU Affero General Public License as published by the Free Software
       7             :   Foundation; either version 3, or (at your option) any later version.
       8             : 
       9             :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10             :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11             :   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
      12             : 
      13             :   You should have received a copy of the GNU Affero General Public License along with
      14             :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15             : */
      16             : /**
      17             :  * @file taler-exchange-httpd_kyc-wallet.c
      18             :  * @brief Handle request for wallet for KYC check.
      19             :  * @author Christian Grothoff
      20             :  */
      21             : #include "platform.h"
      22             : #include <gnunet/gnunet_util_lib.h>
      23             : #include <gnunet/gnunet_json_lib.h>
      24             : #include <jansson.h>
      25             : #include <microhttpd.h>
      26             : #include <pthread.h>
      27             : #include "taler_json_lib.h"
      28             : #include "taler_mhd_lib.h"
      29             : #include "taler_kyclogic_lib.h"
      30             : #include "taler-exchange-httpd_kyc-wallet.h"
      31             : #include "taler-exchange-httpd_responses.h"
      32             : 
      33             : 
      34             : /**
      35             :  * Context for the request.
      36             :  */
      37             : struct KycRequestContext
      38             : {
      39             :   /**
      40             :    * Public key of the reserve/wallet this is about.
      41             :    */
      42             :   struct TALER_PaytoHashP h_payto;
      43             : 
      44             :   /**
      45             :    * KYC status, with row with the legitimization requirement.
      46             :    */
      47             :   struct TALER_EXCHANGEDB_KycStatus kyc;
      48             : 
      49             :   /**
      50             :    * Balance threshold crossed by the wallet.
      51             :    */
      52             :   struct TALER_Amount balance;
      53             : 
      54             :   /**
      55             :    * Name of the required check.
      56             :    */
      57             :   const char *required;
      58             : 
      59             : };
      60             : 
      61             : 
      62             : /**
      63             :  * Function called to iterate over KYC-relevant
      64             :  * transaction amounts for a particular time range.
      65             :  * Returns the wallet balance.
      66             :  *
      67             :  * @param cls closure, a `struct KycRequestContext`
      68             :  * @param limit maximum time-range for which events
      69             :  *        should be fetched (timestamp in the past)
      70             :  * @param cb function to call on each event found,
      71             :  *        events must be returned in reverse chronological
      72             :  *        order
      73             :  * @param cb_cls closure for @a cb
      74             :  */
      75             : static void
      76           0 : balance_iterator (void *cls,
      77             :                   struct GNUNET_TIME_Absolute limit,
      78             :                   TALER_EXCHANGEDB_KycAmountCallback cb,
      79             :                   void *cb_cls)
      80             : {
      81           0 :   struct KycRequestContext *krc = cls;
      82             : 
      83             :   (void) limit;
      84           0 :   cb (cb_cls,
      85           0 :       &krc->balance,
      86             :       GNUNET_TIME_absolute_get ());
      87           0 : }
      88             : 
      89             : 
      90             : /**
      91             :  * Function implementing database transaction to check wallet's KYC status.
      92             :  * Runs the transaction logic; IF it returns a non-error code, the transaction
      93             :  * logic MUST NOT queue a MHD response.  IF it returns an hard error, the
      94             :  * transaction logic MUST queue a MHD response and set @a mhd_ret.  IF it
      95             :  * returns the soft error code, the function MAY be called again to retry and
      96             :  * MUST not queue a MHD response.
      97             :  *
      98             :  * @param cls closure with a `struct KycRequestContext *`
      99             :  * @param connection MHD request which triggered the transaction
     100             :  * @param[out] mhd_ret set to MHD response status for @a connection,
     101             :  *             if transaction failed (!)
     102             :  * @return transaction status
     103             :  */
     104             : static enum GNUNET_DB_QueryStatus
     105           0 : wallet_kyc_check (void *cls,
     106             :                   struct MHD_Connection *connection,
     107             :                   MHD_RESULT *mhd_ret)
     108             : {
     109           0 :   struct KycRequestContext *krc = cls;
     110             :   enum GNUNET_DB_QueryStatus qs;
     111             : 
     112           0 :   krc->required = TALER_KYCLOGIC_kyc_test_required (
     113             :     TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE,
     114           0 :     &krc->h_payto,
     115           0 :     TEH_plugin->select_satisfied_kyc_processes,
     116           0 :     TEH_plugin->cls,
     117             :     &balance_iterator,
     118             :     krc);
     119           0 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     120             :               "KYC check required at %s is `%s'\n",
     121             :               TALER_amount2s (&krc->balance),
     122             :               krc->required);
     123           0 :   if (NULL == krc->required)
     124             :   {
     125           0 :     krc->kyc.ok = true;
     126           0 :     return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
     127             :   }
     128           0 :   krc->kyc.ok = false;
     129           0 :   qs = TEH_plugin->insert_kyc_requirement_for_account (TEH_plugin->cls,
     130             :                                                        krc->required,
     131           0 :                                                        &krc->h_payto,
     132             :                                                        &krc->kyc.requirement_row);
     133           0 :   if (qs < 0)
     134             :   {
     135           0 :     if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
     136           0 :       return qs;
     137           0 :     GNUNET_break (0);
     138           0 :     *mhd_ret = TALER_MHD_reply_with_error (connection,
     139             :                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
     140             :                                            TALER_EC_GENERIC_DB_FETCH_FAILED,
     141             :                                            "insert_kyc_requirement_for_account");
     142           0 :     return qs;
     143             :   }
     144           0 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     145             :               "KYC requirement inserted for wallet %s (%llu, %d)\n",
     146             :               TALER_B2S (&krc->h_payto),
     147             :               (unsigned long long) krc->kyc.requirement_row,
     148             :               qs);
     149           0 :   return qs;
     150             : }
     151             : 
     152             : 
     153             : MHD_RESULT
     154           0 : TEH_handler_kyc_wallet (
     155             :   struct TEH_RequestContext *rc,
     156             :   const json_t *root,
     157             :   const char *const args[])
     158             : {
     159             :   struct TALER_ReserveSignatureP reserve_sig;
     160             :   struct KycRequestContext krc;
     161             :   struct TALER_ReservePublicKeyP reserve_pub;
     162             :   struct GNUNET_JSON_Specification spec[] = {
     163           0 :     GNUNET_JSON_spec_fixed_auto ("reserve_sig",
     164             :                                  &reserve_sig),
     165           0 :     GNUNET_JSON_spec_fixed_auto ("reserve_pub",
     166             :                                  &reserve_pub),
     167             :     // FIXME: add balance threshold crossed to the request
     168             :     // to spec and client API!
     169           0 :     TALER_JSON_spec_amount ("balance",
     170             :                             TEH_currency,
     171             :                             &krc.balance),
     172           0 :     GNUNET_JSON_spec_end ()
     173             :   };
     174             :   MHD_RESULT res;
     175             :   enum GNUNET_GenericReturnValue ret;
     176             : 
     177             :   (void) args;
     178           0 :   ret = TALER_MHD_parse_json_data (rc->connection,
     179             :                                    root,
     180             :                                    spec);
     181           0 :   if (GNUNET_SYSERR == ret)
     182           0 :     return MHD_NO;   /* hard failure */
     183           0 :   if (GNUNET_NO == ret)
     184           0 :     return MHD_YES;   /* failure */
     185             : 
     186           0 :   TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
     187             :   // FIXME: add balance threshold crossed to
     188             :   // what the wallet signs over!
     189           0 :   if (GNUNET_OK !=
     190           0 :       TALER_wallet_account_setup_verify (&reserve_pub,
     191             :                                          &reserve_sig))
     192             :   {
     193           0 :     GNUNET_break_op (0);
     194           0 :     return TALER_MHD_reply_with_error (
     195             :       rc->connection,
     196             :       MHD_HTTP_FORBIDDEN,
     197             :       TALER_EC_EXCHANGE_KYC_WALLET_SIGNATURE_INVALID,
     198             :       NULL);
     199             :   }
     200             :   {
     201             :     char *payto_uri;
     202             : 
     203           0 :     payto_uri = TALER_reserve_make_payto (TEH_base_url,
     204             :                                           &reserve_pub);
     205           0 :     TALER_payto_hash (payto_uri,
     206             :                       &krc.h_payto);
     207           0 :     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     208             :                 "h_payto of wallet %s is %s\n",
     209             :                 payto_uri,
     210             :                 TALER_B2S (&krc.h_payto));
     211           0 :     GNUNET_free (payto_uri);
     212             :   }
     213           0 :   ret = TEH_DB_run_transaction (rc->connection,
     214             :                                 "check wallet kyc",
     215             :                                 TEH_MT_REQUEST_OTHER,
     216             :                                 &res,
     217             :                                 &wallet_kyc_check,
     218             :                                 &krc);
     219           0 :   if (GNUNET_SYSERR == ret)
     220           0 :     return res;
     221           0 :   if (NULL == krc.required)
     222             :   {
     223             :     /* KYC not required or already satisfied */
     224           0 :     return TALER_MHD_reply_static (
     225             :       rc->connection,
     226             :       MHD_HTTP_NO_CONTENT,
     227             :       NULL,
     228             :       NULL,
     229             :       0);
     230             :   }
     231           0 :   return TEH_RESPONSE_reply_kyc_required (rc->connection,
     232             :                                           &krc.h_payto,
     233             :                                           &krc.kyc);
     234             : }
     235             : 
     236             : 
     237             : /* end of taler-exchange-httpd_kyc-wallet.c */

Generated by: LCOV version 1.14