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 }