exchange

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

plugin_kyclogic_template.c (11531B)


      1 /*
      2   This file is part of GNU Taler
      3   Copyright (C) 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.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file plugin_kyclogic_template.c
     18  * @brief template for an authentication flow logic
     19  * @author Christian Grothoff
     20  */
     21 #include "taler/platform.h"
     22 #include "taler/taler_kyclogic_plugin.h"
     23 #include "taler/taler_mhd_lib.h"
     24 #include "taler/taler_json_lib.h"
     25 #include <regex.h>
     26 #include "taler/taler_util.h"
     27 
     28 
     29 /**
     30  * Saves the state of a plugin.
     31  */
     32 struct PluginState
     33 {
     34 
     35   /**
     36    * Our base URL.
     37    */
     38   char *exchange_base_url;
     39 
     40   /**
     41    * Our global configuration.
     42    */
     43   const struct GNUNET_CONFIGURATION_Handle *cfg;
     44 
     45   /**
     46    * Context for CURL operations (useful to the event loop)
     47    */
     48   struct GNUNET_CURL_Context *curl_ctx;
     49 
     50   /**
     51    * Context for integrating @e curl_ctx with the
     52    * GNUnet event loop.
     53    */
     54   struct GNUNET_CURL_RescheduleContext *curl_rc;
     55 
     56 };
     57 
     58 
     59 /**
     60  * Keeps the plugin-specific state for
     61  * a given configuration section.
     62  */
     63 struct TALER_KYCLOGIC_ProviderDetails
     64 {
     65 
     66   /**
     67    * Overall plugin state.
     68    */
     69   struct PluginState *ps;
     70 
     71   /**
     72    * Configuration section that configured us.
     73    */
     74   char *section;
     75 
     76 };
     77 
     78 
     79 /**
     80  * Handle for an initiation operation.
     81  */
     82 struct TALER_KYCLOGIC_InitiateHandle
     83 {
     84 
     85   /**
     86    * Hash of the payto:// URI we are initiating
     87    * the KYC for.
     88    */
     89   struct TALER_NormalizedPaytoHashP h_payto;
     90 
     91   /**
     92    * UUID being checked.
     93    */
     94   uint64_t legitimization_uuid;
     95 
     96   /**
     97    * Our configuration details.
     98    */
     99   const struct TALER_KYCLOGIC_ProviderDetails *pd;
    100 
    101   /**
    102    * Continuation to call.
    103    */
    104   TALER_KYCLOGIC_InitiateCallback cb;
    105 
    106   /**
    107    * Closure for @a cb.
    108    */
    109   void *cb_cls;
    110 };
    111 
    112 
    113 /**
    114  * Handle for an KYC proof operation.
    115  */
    116 struct TALER_KYCLOGIC_ProofHandle
    117 {
    118 
    119   /**
    120    * Overall plugin state.
    121    */
    122   struct PluginState *ps;
    123 
    124   /**
    125    * Our configuration details.
    126    */
    127   const struct TALER_KYCLOGIC_ProviderDetails *pd;
    128 
    129   /**
    130    * Continuation to call.
    131    */
    132   TALER_KYCLOGIC_ProofCallback cb;
    133 
    134   /**
    135    * Closure for @e cb.
    136    */
    137   void *cb_cls;
    138 
    139   /**
    140    * Connection we are handling.
    141    */
    142   struct MHD_Connection *connection;
    143 };
    144 
    145 
    146 /**
    147  * Handle for an KYC Web hook operation.
    148  */
    149 struct TALER_KYCLOGIC_WebhookHandle
    150 {
    151 
    152   /**
    153    * Continuation to call when done.
    154    */
    155   TALER_KYCLOGIC_WebhookCallback cb;
    156 
    157   /**
    158    * Closure for @a cb.
    159    */
    160   void *cb_cls;
    161 
    162   /**
    163    * Task for asynchronous execution.
    164    */
    165   struct GNUNET_SCHEDULER_Task *task;
    166 
    167   /**
    168    * Overall plugin state.
    169    */
    170   struct PluginState *ps;
    171 
    172   /**
    173    * Our configuration details.
    174    */
    175   const struct TALER_KYCLOGIC_ProviderDetails *pd;
    176 
    177   /**
    178    * Connection we are handling.
    179    */
    180   struct MHD_Connection *connection;
    181 };
    182 
    183 
    184 /**
    185  * Release configuration resources previously loaded
    186  *
    187  * @param[in] pd configuration to release
    188  */
    189 static void
    190 template_unload_configuration (struct TALER_KYCLOGIC_ProviderDetails *pd)
    191 {
    192   GNUNET_free (pd);
    193 }
    194 
    195 
    196 /**
    197  * Load the configuration of the KYC provider.
    198  *
    199  * @param cls closure
    200  * @param provider_section_name configuration section to parse
    201  * @return NULL if configuration is invalid
    202  */
    203 static struct TALER_KYCLOGIC_ProviderDetails *
    204 template_load_configuration (void *cls,
    205                              const char *provider_section_name)
    206 {
    207   struct PluginState *ps = cls;
    208   struct TALER_KYCLOGIC_ProviderDetails *pd;
    209 
    210   pd = GNUNET_new (struct TALER_KYCLOGIC_ProviderDetails);
    211   pd->ps = ps;
    212   pd->section = GNUNET_strdup (provider_section_name);
    213   GNUNET_break (0); // FIXME: parse config here!
    214   return pd;
    215 }
    216 
    217 
    218 /**
    219  * Cancel KYC check initiation.
    220  *
    221  * @param[in] ih handle of operation to cancel
    222  */
    223 static void
    224 template_initiate_cancel (struct TALER_KYCLOGIC_InitiateHandle *ih)
    225 {
    226   GNUNET_break (0); // FIXME: add cancel logic here
    227   GNUNET_free (ih);
    228 }
    229 
    230 
    231 /**
    232  * Initiate KYC check.
    233  *
    234  * @param cls the @e cls of this struct with the plugin-specific state
    235  * @param pd provider configuration details
    236  * @param account_id which account to trigger process for
    237  * @param legitimization_uuid unique ID for the legitimization process
    238  * @param context additional contextual information for the legi process
    239  * @param cb function to call with the result
    240  * @param cb_cls closure for @a cb
    241  * @return handle to cancel operation early
    242  */
    243 static struct TALER_KYCLOGIC_InitiateHandle *
    244 template_initiate (void *cls,
    245                    const struct TALER_KYCLOGIC_ProviderDetails *pd,
    246                    const struct TALER_NormalizedPaytoHashP *account_id,
    247                    uint64_t legitimization_uuid,
    248                    const json_t *context,
    249                    TALER_KYCLOGIC_InitiateCallback cb,
    250                    void *cb_cls)
    251 {
    252   struct TALER_KYCLOGIC_InitiateHandle *ih;
    253 
    254   (void) cls;
    255   (void) context;
    256   ih = GNUNET_new (struct TALER_KYCLOGIC_InitiateHandle);
    257   ih->legitimization_uuid = legitimization_uuid;
    258   ih->cb = cb;
    259   ih->cb_cls = cb_cls;
    260   ih->h_payto = *account_id;
    261   ih->pd = pd;
    262   GNUNET_break (0); // FIXME: add actual initiation logic!
    263   return ih;
    264 }
    265 
    266 
    267 /**
    268  * Cancel KYC proof.
    269  *
    270  * @param[in] ph handle of operation to cancel
    271  */
    272 static void
    273 template_proof_cancel (struct TALER_KYCLOGIC_ProofHandle *ph)
    274 {
    275   GNUNET_break (0); // FIXME: stop activities...
    276   GNUNET_free (ph);
    277 }
    278 
    279 
    280 /**
    281  * Check KYC status and return status to human.
    282  *
    283  * @param cls the @e cls of this struct with the plugin-specific state
    284  * @param pd provider configuration details
    285  * @param connection MHD connection object (for HTTP headers)
    286  * @param account_id which account to trigger process for
    287  * @param process_row row in the legitimization processes table the legitimization is for
    288  * @param provider_user_id user ID (or NULL) the proof is for
    289  * @param provider_legitimization_id legitimization ID the proof is for
    290  * @param cb function to call with the result
    291  * @param cb_cls closure for @a cb
    292  * @return handle to cancel operation early
    293  */
    294 static struct TALER_KYCLOGIC_ProofHandle *
    295 template_proof (void *cls,
    296                 const struct TALER_KYCLOGIC_ProviderDetails *pd,
    297                 struct MHD_Connection *connection,
    298                 const struct TALER_NormalizedPaytoHashP *account_id,
    299                 uint64_t process_row,
    300                 const char *provider_user_id,
    301                 const char *provider_legitimization_id,
    302                 TALER_KYCLOGIC_ProofCallback cb,
    303                 void *cb_cls)
    304 {
    305   struct PluginState *ps = cls;
    306   struct TALER_KYCLOGIC_ProofHandle *ph;
    307 
    308   (void) account_id;
    309   (void) process_row;
    310   (void) provider_user_id;
    311   (void) provider_legitimization_id;
    312   ph = GNUNET_new (struct TALER_KYCLOGIC_ProofHandle);
    313   ph->ps = ps;
    314   ph->pd = pd;
    315   ph->cb = cb;
    316   ph->cb_cls = cb_cls;
    317   ph->connection = connection;
    318 
    319   GNUNET_break (0); // FIXME: start check!
    320   return ph;
    321 }
    322 
    323 
    324 /**
    325  * Cancel KYC webhook execution.
    326  *
    327  * @param[in] wh handle of operation to cancel
    328  */
    329 static void
    330 template_webhook_cancel (struct TALER_KYCLOGIC_WebhookHandle *wh)
    331 {
    332   GNUNET_break (0); /*  FIXME: stop activity */
    333   GNUNET_free (wh);
    334 }
    335 
    336 
    337 /**
    338  * Check KYC status and return result for Webhook.
    339  *
    340  * @param cls the @e cls of this struct with the plugin-specific state
    341  * @param pd provider configuration details
    342  * @param plc callback to lookup accounts with
    343  * @param plc_cls closure for @a plc
    344  * @param http_method HTTP method used for the webhook
    345  * @param url_path rest of the URL after `/kyc-webhook/`
    346  * @param connection MHD connection object (for HTTP headers)
    347  * @param body HTTP request body
    348  * @param cb function to call with the result
    349  * @param cb_cls closure for @a cb
    350  * @return handle to cancel operation early
    351  */
    352 static struct TALER_KYCLOGIC_WebhookHandle *
    353 template_webhook (void *cls,
    354                   const struct TALER_KYCLOGIC_ProviderDetails *pd,
    355                   TALER_KYCLOGIC_ProviderLookupCallback plc,
    356                   void *plc_cls,
    357                   const char *http_method,
    358                   const char *const url_path[],
    359                   struct MHD_Connection *connection,
    360                   const json_t *body,
    361                   TALER_KYCLOGIC_WebhookCallback cb,
    362                   void *cb_cls)
    363 {
    364   struct PluginState *ps = cls;
    365   struct TALER_KYCLOGIC_WebhookHandle *wh;
    366 
    367   (void) plc;
    368   (void) plc_cls;
    369   (void) http_method;
    370   (void) url_path;
    371   (void) body;
    372   wh = GNUNET_new (struct TALER_KYCLOGIC_WebhookHandle);
    373   wh->cb = cb;
    374   wh->cb_cls = cb_cls;
    375   wh->ps = ps;
    376   wh->pd = pd;
    377   wh->connection = connection;
    378   GNUNET_break (0); /* FIXME: start activity */
    379   return wh;
    380 }
    381 
    382 
    383 /**
    384  * Initialize Template.0 KYC logic plugin
    385  *
    386  * @param cls a configuration instance
    387  * @return NULL on error, otherwise a `struct TALER_KYCLOGIC_Plugin`
    388  */
    389 void *
    390 libtaler_plugin_kyclogic_template_init (void *cls);
    391 
    392 /* declaration to avoid compiler warning */
    393 void *
    394 libtaler_plugin_kyclogic_template_init (void *cls)
    395 {
    396   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
    397   struct TALER_KYCLOGIC_Plugin *plugin;
    398   struct PluginState *ps;
    399 
    400   ps = GNUNET_new (struct PluginState);
    401   ps->cfg = cfg;
    402   if (GNUNET_OK !=
    403       GNUNET_CONFIGURATION_get_value_string (cfg,
    404                                              "exchange",
    405                                              "BASE_URL",
    406                                              &ps->exchange_base_url))
    407   {
    408     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
    409                                "exchange",
    410                                "BASE_URL");
    411     GNUNET_free (ps);
    412     return NULL;
    413   }
    414 
    415   ps->curl_ctx
    416     = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
    417                         &ps->curl_rc);
    418   if (NULL == ps->curl_ctx)
    419   {
    420     GNUNET_break (0);
    421     GNUNET_free (ps->exchange_base_url);
    422     GNUNET_free (ps);
    423     return NULL;
    424   }
    425   ps->curl_rc = GNUNET_CURL_gnunet_rc_create (ps->curl_ctx);
    426 
    427   plugin = GNUNET_new (struct TALER_KYCLOGIC_Plugin);
    428   plugin->cls = ps;
    429   plugin->load_configuration
    430     = &template_load_configuration;
    431   plugin->unload_configuration
    432     = &template_unload_configuration;
    433   plugin->initiate
    434     = &template_initiate;
    435   plugin->initiate_cancel
    436     = &template_initiate_cancel;
    437   plugin->proof
    438     = &template_proof;
    439   plugin->proof_cancel
    440     = &template_proof_cancel;
    441   plugin->webhook
    442     = &template_webhook;
    443   plugin->webhook_cancel
    444     = &template_webhook_cancel;
    445   return plugin;
    446 }
    447 
    448 
    449 /**
    450  * Unload authorization plugin
    451  *
    452  * @param cls a `struct TALER_KYCLOGIC_Plugin`
    453  * @return NULL (always)
    454  */
    455 void *
    456 libtaler_plugin_kyclogic_template_done (void *cls);
    457 
    458 /* declaration to avoid compiler warning */
    459 void *
    460 libtaler_plugin_kyclogic_template_done (void *cls)
    461 {
    462   struct TALER_KYCLOGIC_Plugin *plugin = cls;
    463   struct PluginState *ps = plugin->cls;
    464 
    465   if (NULL != ps->curl_ctx)
    466   {
    467     GNUNET_CURL_fini (ps->curl_ctx);
    468     ps->curl_ctx = NULL;
    469   }
    470   if (NULL != ps->curl_rc)
    471   {
    472     GNUNET_CURL_gnunet_rc_destroy (ps->curl_rc);
    473     ps->curl_rc = NULL;
    474   }
    475   GNUNET_free (ps->exchange_base_url);
    476   GNUNET_free (ps);
    477   GNUNET_free (plugin);
    478   return NULL;
    479 }