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 }