exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

taler-exchange-httpd_common_kyc.h (10675B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2023, 2024 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_common_kyc.h
     18  * @brief shared logic for finishing a KYC process
     19  * @author Christian Grothoff
     20  */
     21 #ifndef TALER_EXCHANGE_HTTPD_COMMON_KYC_H
     22 #define TALER_EXCHANGE_HTTPD_COMMON_KYC_H
     23 
     24 #include <gnunet/gnunet_util_lib.h>
     25 #include <gnunet/gnunet_json_lib.h>
     26 #include <jansson.h>
     27 #include <microhttpd.h>
     28 #include "taler/taler_json_lib.h"
     29 #include "taler/taler_kyclogic_lib.h"
     30 #include "taler/taler_mhd_lib.h"
     31 #include "taler-exchange-httpd.h"
     32 
     33 
     34 /**
     35  * Function called after a measure has been run.
     36  *
     37  * @param cls closure
     38  * @param ec error code or 0 on success
     39  * @param detail error message or NULL on success / no info
     40  */
     41 typedef void
     42 (*TEH_KycMeasureRunContextCallback) (
     43   void *cls,
     44   enum TALER_ErrorCode ec,
     45   const char *detail);
     46 
     47 
     48 /**
     49  * Handle for an asynchronous operation to finish
     50  * a KYC process after running the AML trigger.
     51  */
     52 struct TEH_KycMeasureRunContext;
     53 
     54 
     55 /**
     56  * Store attributes from the given KYC provider.
     57  *
     58  * FIXME: Isn't the account_id redundant via the process_row?
     59  *
     60  * @param process_row legitimization process the data provided is about
     61  * @param account_id account the the data provided is about
     62  * @param provider_name name of the provider that provided the attributes
     63  * @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown
     64  * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown
     65  * @param expiration until when is the KYC check valid
     66  * @param new_attributes user attributes returned by the provider
     67  * @return handle to cancel the operation
     68  */
     69 enum GNUNET_DB_QueryStatus
     70 TEH_kyc_store_attributes (
     71   uint64_t process_row,
     72   const struct TALER_NormalizedPaytoHashP *account_id,
     73   const char *provider_name,
     74   const char *provider_user_id,
     75   const char *provider_legitimization_id,
     76   struct GNUNET_TIME_Absolute expiration,
     77   const json_t *new_attributes);
     78 
     79 
     80 /**
     81  * Run measure after storing attributes from the given
     82  * provider.
     83  *
     84  * Only works when a process is active.
     85  *
     86  * @param scope the HTTP request logging scope
     87  * @param process_row legitimization process the data provided is about
     88  * @param account_id account the the data provided is about
     89  * @param is_wallet true if @a account_id is a wallet
     90  * @param cb function to call with the result
     91  * @param cb_cls closure for @a cb
     92  * @return handle to cancel the operation
     93  */
     94 // FIXME: function should probably be renamed...
     95 struct TEH_KycMeasureRunContext *
     96 TEH_kyc_run_measure_for_attributes (
     97   const struct GNUNET_AsyncScopeId *scope,
     98   uint64_t process_row,
     99   const struct TALER_NormalizedPaytoHashP *account_id,
    100   bool is_wallet,
    101   TEH_KycMeasureRunContextCallback cb,
    102   void *cb_cls);
    103 
    104 
    105 /**
    106  * Run an measure directly.
    107  *
    108  * Inserts a legitimization process and measure
    109  * into the database before running the measure program.
    110  *
    111  * After running the measure program, the result is stored
    112  * in the DB.
    113  *
    114  * @param scope the HTTP request logging scope
    115  * @param instant_ms instant measure to run
    116  * @param account_id account affected by the measure
    117  * @param is_wallet true if @a account_id is for a wallet
    118  * @param cb function to call with the result
    119  * @param cb_cls closure for @a cb
    120  * @return handle to cancel the operation
    121  */
    122 struct TEH_KycMeasureRunContext *
    123 TEH_kyc_run_measure_directly (
    124   const struct GNUNET_AsyncScopeId *scope,
    125   const struct TALER_KYCLOGIC_Measure *instant_ms,
    126   const struct TALER_NormalizedPaytoHashP *account_id,
    127   bool is_wallet,
    128   TEH_KycMeasureRunContextCallback cb,
    129   void *cb_cls);
    130 
    131 
    132 /**
    133  * Cancel running KYC measure.
    134  *
    135  * @param[in] kat operation to abort
    136  */
    137 void
    138 TEH_kyc_run_measure_cancel (struct TEH_KycMeasureRunContext *kat);
    139 
    140 
    141 /**
    142  * Handle for an asynchronous operation to run some
    143  * fallback measure.
    144  */
    145 struct TEH_KycAmlFallback;
    146 
    147 
    148 /**
    149  * Function called after the KYC-AML fallback
    150  * processing is done.
    151  *
    152  * @param cls closure
    153  * @param result true if fallback handling was OK
    154  * @param requirement_row row of
    155  *    new KYC requirement that was created, 0 for none
    156  */
    157 typedef void
    158 (*TEH_KycAmlFallbackCallback) (
    159   void *cls,
    160   bool result,
    161   uint64_t requirement_row);
    162 
    163 
    164 /**
    165  * Activate fallback measure for the given account.
    166  *
    167  * @param scope the HTTP request logging scope
    168  * @param account_id account to activate fallback for
    169  * @param is_wallet true if @a account_id is for a wallet
    170  * @param orig_requirement_row original requirement
    171  *    row that now triggered the fallback
    172  * @param fallback_measure fallback to activate
    173  * @param cb callback to call with result
    174  * @param cb_cls closure for @a cb
    175  * @return handle for fallback operation, NULL
    176  *    if @a fallback_measure is unknown
    177  */
    178 struct TEH_KycAmlFallback *
    179 TEH_kyc_fallback (
    180   const struct GNUNET_AsyncScopeId *scope,
    181   const struct TALER_NormalizedPaytoHashP *account_id,
    182   bool is_wallet,
    183   uint64_t orig_requirement_row,
    184   const char *fallback_measure,
    185   TEH_KycAmlFallbackCallback cb,
    186   void *cb_cls);
    187 
    188 
    189 /**
    190  * Cancel fallback operation.
    191  *
    192  * @param[in] fb operation to cancel
    193  */
    194 void
    195 TEH_kyc_fallback_cancel (
    196   struct TEH_KycAmlFallback *fb);
    197 
    198 
    199 /**
    200  * Update state of a legitmization process to 'finished'
    201  * (and failed, no attributes were obtained).
    202  *
    203  * @param process_row legitimization process the webhook was about
    204  * @param account_id account the webhook was about
    205  * @param provider_name name KYC provider with the logic that was run
    206  * @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown
    207  * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown
    208  * @param error_message error message to log
    209  * @param ec error code to log
    210  * @return true if the error was handled successfully
    211  */
    212 bool
    213 TEH_kyc_failed (
    214   uint64_t process_row,
    215   const struct TALER_NormalizedPaytoHashP *account_id,
    216   const char *provider_name,
    217   const char *provider_user_id,
    218   const char *provider_legitimization_id,
    219   const char *error_message,
    220   enum TALER_ErrorCode ec);
    221 
    222 
    223 /**
    224  * Result from a legitimization check.
    225  */
    226 struct TEH_LegitimizationCheckResult
    227 {
    228   /**
    229    * KYC status for the account
    230    */
    231   struct TALER_EXCHANGEDB_KycStatus kyc;
    232 
    233   /**
    234    * Last reserve public key of a wire transfer from
    235    * the account to the exchange.
    236    */
    237   union TALER_AccountPublicKeyP reserve_pub;
    238 
    239   /**
    240    * Smallest amount (over any timeframe) that may
    241    * require additional KYC checks (if @a kyc.ok).
    242    */
    243   struct TALER_Amount next_threshold;
    244 
    245   /**
    246    * When do the current KYC rules possibly expire.
    247    * Only valid if @a kyc.ok.
    248    */
    249   struct GNUNET_TIME_Timestamp expiration_date;
    250 
    251   /**
    252    * Response to return. Note that the response must
    253    * be queued or destroyed by the callee.  NULL
    254    * if the legitimization check was successful and the handler should return
    255    * a handler-specific result.
    256    */
    257   struct MHD_Response *response;
    258 
    259   /**
    260    * HTTP status code for @a response, or 0
    261    */
    262   unsigned int http_status;
    263 
    264   /**
    265    * True if @e reserve_pub is set.
    266    */
    267   bool have_reserve_pub;
    268 
    269   /**
    270    * Set to true if the merchant public key does not
    271    * match the public key we have on file for this
    272    * target account (and thus a new KYC AUTH is
    273    * required).
    274    */
    275   bool bad_kyc_auth;
    276 };
    277 
    278 
    279 /**
    280  * Function called with the result of a legitimization
    281  * check.
    282  *
    283  * @param cls closure
    284  * @param lcr legitimization check result
    285  */
    286 typedef void
    287 (*TEH_LegitimizationCheckCallback)(
    288   void *cls,
    289   const struct TEH_LegitimizationCheckResult *lcr);
    290 
    291 /**
    292  * Handle for a legitimization check.
    293  */
    294 struct TEH_LegitimizationCheckHandle;
    295 
    296 
    297 /* FIXME: add another variation of this API with a
    298    NormalizedPayto payto_uri, as we currently 'fake'
    299    a full payto in 3 places related to wallets! */
    300 /**
    301  * Do legitimization check.
    302  *
    303  * @param scope scope for logging
    304  * @param et type of event we are checking
    305  * @param payto_uri account we are checking for
    306  * @param h_payto hash of @a payto_uri
    307  * @param account_pub public key to enable for the
    308  *    KYC authorization, NULL if not known
    309  * @param ai callback to get amounts involved historically
    310  * @param ai_cls closure for @a ai
    311  * @param result_cb function to call with the result
    312  * @param result_cb_cls closure for @a result_cb
    313  * @return handle for the operation
    314  */
    315 struct TEH_LegitimizationCheckHandle *
    316 TEH_legitimization_check (
    317   const struct GNUNET_AsyncScopeId *scope,
    318   enum TALER_KYCLOGIC_KycTriggerEvent et,
    319   const struct TALER_FullPayto payto_uri,
    320   const struct TALER_NormalizedPaytoHashP *h_payto,
    321   const union TALER_AccountPublicKeyP *account_pub,
    322   TALER_KYCLOGIC_KycAmountIterator ai,
    323   void *ai_cls,
    324   TEH_LegitimizationCheckCallback result_cb,
    325   void *result_cb_cls);
    326 
    327 
    328 /**
    329  * Do legitimization check and enforce that the current
    330  * public key associated with the account is the given
    331  * merchant public key.
    332  *
    333  * @param scope scope for logging
    334  * @param et type of event we are checking
    335  * @param payto_uri account we are checking for
    336  * @param h_payto hash of @a payto_uri
    337  * @param merchant_pub public key that must match the
    338  *    KYC authorization
    339  * @param ai callback to get amounts involved historically
    340  * @param ai_cls closure for @a ai
    341  * @param result_cb function to call with the result
    342  * @param result_cb_cls closure for @a result_cb
    343  * @return handle for the operation
    344  */
    345 struct TEH_LegitimizationCheckHandle *
    346 TEH_legitimization_check2 (
    347   const struct GNUNET_AsyncScopeId *scope,
    348   enum TALER_KYCLOGIC_KycTriggerEvent et,
    349   const struct TALER_FullPayto payto_uri,
    350   const struct TALER_NormalizedPaytoHashP *h_payto,
    351   const struct TALER_MerchantPublicKeyP *merchant_pub,
    352   TALER_KYCLOGIC_KycAmountIterator ai,
    353   void *ai_cls,
    354   TEH_LegitimizationCheckCallback result_cb,
    355   void *result_cb_cls);
    356 
    357 
    358 /**
    359  * Cancel legitimization check.
    360  *
    361  * @param[in] lch handle of the check to cancel
    362  */
    363 void
    364 TEH_legitimization_check_cancel (
    365   struct TEH_LegitimizationCheckHandle *lch);
    366 
    367 #endif