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 (11503B)


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