diff options
| -rw-r--r-- | src/kyclogic/Makefile.am | 3 | ||||
| -rw-r--r-- | src/kyclogic/kyclogic-oauth2.conf | 27 | ||||
| -rw-r--r-- | src/kyclogic/kyclogic.conf | 15 | ||||
| -rw-r--r-- | src/kyclogic/plugin_kyclogic_oauth2.c | 16 | ||||
| -rw-r--r-- | src/kyclogic/sample.conf | 33 | ||||
| -rw-r--r-- | src/kyclogic/taler-exchange-kyc-tester.c | 282 | 
6 files changed, 283 insertions, 93 deletions
| diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am index c57fc1fc..5531e9f9 100644 --- a/src/kyclogic/Makefile.am +++ b/src/kyclogic/Makefile.am @@ -14,7 +14,8 @@ pkgcfg_DATA = \  EXTRA_DIST = \    kyclogic.conf \ -  kyclogic-oauth2.conf +  kyclogic-oauth2.conf \ +  sample.conf  lib_LTLIBRARIES = \    libtalerkyclogic.la diff --git a/src/kyclogic/kyclogic-oauth2.conf b/src/kyclogic/kyclogic-oauth2.conf index e69de29b..7ccf81c0 100644 --- a/src/kyclogic/kyclogic-oauth2.conf +++ b/src/kyclogic/kyclogic-oauth2.conf @@ -0,0 +1,27 @@ +# This file is in the public domain. + +# Example Oauth2.0 provider configuration. + +[kyc-provider-example-oauth2] + +COST = 42 +LOGIC = oauth2 +USER_TYPE = INDIVIDUAL +PROVIDED_CHECKS = EXAMPLE_DO_NOT_USE + +# How long is the KYC check valid? +KYC_OAUTH2_VALIDITY = forever + +# URL where we initiate the user's login process +KYC_OAUTH2_LOGIN_URL = http://kyc.example.com/login +# URL where we send the user's authentication information +KYC_OAUTH2_AUTH_URL = http://kyc.example.com/auth +# URL of the user info access point. +KYC_OAUTH2_INFO_URL = http://kyc.example.com/info + +# Where does the client get redirected upon completion? +KYC_OAUTH2_POST_URL = http://example.com/thank-you + +# For authentication to the OAuth2.0 service +KYC_OAUTH2_CLIENT_ID = testcase +KYC_OAUTH2_CLIENT_SECRET = password diff --git a/src/kyclogic/kyclogic.conf b/src/kyclogic/kyclogic.conf index e69de29b..a66ce601 100644 --- a/src/kyclogic/kyclogic.conf +++ b/src/kyclogic/kyclogic.conf @@ -0,0 +1,15 @@ +# This file is in the public domain. +# +# Sample legitimization rule set. + +#[kyc-legitimization-withdraw-high] +# KYC hook is this rule is about. +#OPERATION_TYPE = WITHDRAW +# Which checks must be done. Give names used by providers. +#REQUIRED_CHECKS = PHONE GOVID SSN +# Treshold amount above which the checks are required. +#THRESHOLD = KUDOS:100 +# Timeframe over which amounts involved in the +# operation type are accumulated to test against +# the threshold. +#TIMEFRAME = 1a diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c index 42f195be..0a19a849 100644 --- a/src/kyclogic/plugin_kyclogic_oauth2.c +++ b/src/kyclogic/plugin_kyclogic_oauth2.c @@ -101,9 +101,9 @@ struct TALER_KYCLOGIC_ProviderDetails    char *post_kyc_redirect_url;    /** -   * Expiration time for a successful KYC process. +   * Validity time for a successful KYC process.     */ -  struct GNUNET_TIME_Relative expiration; +  struct GNUNET_TIME_Relative validity;  }; @@ -295,12 +295,12 @@ oauth2_load_configuration (void *cls,    if (GNUNET_OK !=        GNUNET_CONFIGURATION_get_value_time (ps->cfg,                                             provider_section_name, -                                           "KYC_OAUTH2_EXPIRATION", -                                           &pd->expiration)) +                                           "KYC_OAUTH2_VALIDITY", +                                           &pd->validity))    {      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,                                 provider_section_name, -                               "KYC_OAUTH2_EXPIARTION"); +                               "KYC_OAUTH2_VALIDITY");      oauth2_unload_configuration (pd);      return NULL;    } @@ -367,12 +367,12 @@ oauth2_load_configuration (void *cls,    if (GNUNET_OK !=        GNUNET_CONFIGURATION_get_value_string (ps->cfg,                                               provider_section_name, -                                             "KYC_INFO_URL", +                                             "KYC_OAUTH2_INFO_URL",                                               &s))    {      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,                                 provider_section_name, -                               "KYC_INFO_URL"); +                               "KYC_OAUTH2_INFO_URL");      oauth2_unload_configuration (pd);      return NULL;    } @@ -553,7 +553,7 @@ return_proof_response (void *cls)            ph->status,            ph->provider_user_id,            ph->provider_legitimization_id, -          GNUNET_TIME_relative_to_absolute (ph->pd->expiration), +          GNUNET_TIME_relative_to_absolute (ph->pd->validity),            ph->http_status,            ph->response);    GNUNET_free (ph->provider_user_id); diff --git a/src/kyclogic/sample.conf b/src/kyclogic/sample.conf new file mode 100644 index 00000000..b9a88c29 --- /dev/null +++ b/src/kyclogic/sample.conf @@ -0,0 +1,33 @@ +# This file is in the public domain. +# + +[exchange] + +# HTTP port the exchange listens to +PORT = 8081 + +# Base URL of the exchange. Must be set to a URL where the +# exchange (or the twister) is actually listening. +BASE_URL = "http://localhost:8081/" + +[kyc-provider-test-oauth2] + +COST = 0 +LOGIC = oauth2 +USER_TYPE = INDIVIDUAL +PROVIDED_CHECKS = DUMMY + +KYC_OAUTH2_VALIDITY = forever +KYC_OAUTH2_AUTH_URL = http://kyc.taler.net/auth +KYC_OAUTH2_LOGIN_URL = http://kyc.taler.net/login +KYC_OAUTH2_INFO_URL = http://kyc.taler.net/info +KYC_OAUTH2_POST_URL = http://kyc.taler.net/thank-you +KYC_OAUTH2_CLIENT_ID = testcase +KYC_OAUTH2_CLIENT_SECRET = password + +[kyc-legitimization-withdraw-high] + +OPERATION_TYPE = WITHDRAW +REQUIRED_CHECKS = DUMMY +THRESHOLD = KUDOS:100 +TIMEFRAME = 1a diff --git a/src/kyclogic/taler-exchange-kyc-tester.c b/src/kyclogic/taler-exchange-kyc-tester.c index 1fb0afa4..753c6517 100644 --- a/src/kyclogic/taler-exchange-kyc-tester.c +++ b/src/kyclogic/taler-exchange-kyc-tester.c @@ -172,14 +172,29 @@ static const struct GNUNET_CONFIGURATION_Handle *TEKT_cfg;  static struct MHD_Daemon *mhd;  /** - * Our currency. + * Our base URL.   */ -static char *TEKT_currency; +static char *TEKT_base_url;  /** - * Our base URL. + * Payto set via command-line (or otherwise random).   */ -static char *TEKT_base_url; +static struct TALER_PaytoHashP cmd_line_h_payto; + +/** + * Row ID to use, override with '-r' + */ +static unsigned int kyc_row_id = 42; + +/** + * -P command-line option. + */ +static int print_h_payto; + +/** + * -w command-line option. + */ +static int run_webservice;  /**   * Value to return from main() @@ -187,6 +202,21 @@ static char *TEKT_base_url;  static int global_ret;  /** + * -i command-line flag. + */ +static char *initiate_section; + +/** + * Handle for ongoing initiation operation. + */ +static struct TALER_KYCLOGIC_InitiateHandle *ih; + +/** + * KYC logic running for @e ih. + */ +static struct TALER_KYCLOGIC_Plugin *logic; + +/**   * Port to run the daemon on.   */  static uint16_t serve_port; @@ -204,24 +234,6 @@ static struct GNUNET_CURL_RescheduleContext *exchange_curl_rc;  /** - * Generate a 404 "not found" reply on @a connection with - * the hint @a details. - * - * @param connection where to send the reply on - * @param details details for the error message, can be NULL - */ -static MHD_RESULT -r404 (struct MHD_Connection *connection, -      const char *details) -{ -  return TALER_MHD_reply_with_error (connection, -                                     MHD_HTTP_NOT_FOUND, -                                     TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN, -                                     details); -} - - -/**   * Context for the webhook.   */  struct KycWebhookContext @@ -427,11 +439,12 @@ kyc_provider_account_lookup (    const char *provider_legitimization_id,    struct TALER_PaytoHashP *h_payto)  { -  // FIXME: pass value to use for h_payto via command-line? -  memset (h_payto, -          42, -          sizeof (*h_payto)); -  return 1; // FIXME... +  GNUNET_log (GNUNET_ERROR_TYPE_INFO, +              "Simulated account lookup using `%s/%s'\n", +              provider_section, +              provider_legitimization_id); +  *h_payto = cmd_line_h_payto; +  return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;  } @@ -745,25 +758,13 @@ handle_mhd_request (void *cls,  {    static struct TEKT_RequestHandler handlers[] = {  #if FIXME -    /* KYC endpoints */ -    { -      .url = "kyc-check", -      .method = MHD_HTTP_METHOD_GET, -      .handler.get = &TEKT_handler_kyc_check, -      .nargs = 1 -    }, +    /* simulated KYC endpoints */      {        .url = "kyc-proof",        .method = MHD_HTTP_METHOD_GET,        .handler.get = &TEKT_handler_kyc_proof,        .nargs = 1      }, -    { -      .url = "kyc-wallet", -      .method = MHD_HTTP_METHOD_POST, -      .handler.post = &TEKT_handler_kyc_wallet, -      .nargs = 0 -    },  #endif      {        .url = "kyc-webhook", @@ -994,6 +995,11 @@ do_shutdown (void *cls)    struct MHD_Daemon *mhd;    (void) cls; +  if (NULL != ih) +  { +    logic->initiate_cancel (ih); +    ih = NULL; +  }    kyc_webhook_cleanup ();    TALER_KYCLOGIC_kyc_done ();    mhd = TALER_MHD_daemon_stop (); @@ -1013,6 +1019,45 @@ do_shutdown (void *cls)  /** + * Function called with the result of a KYC initiation + * operation. + * + * @param cls closure + * @param ec #TALER_EC_NONE on success + * @param redirect_url set to where to redirect the user on success, NULL on failure + * @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown + * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown + * @param error_msg_hint set to additional details to return to user, NULL on success + */ +static void +initiate_cb ( +  void *cls, +  enum TALER_ErrorCode ec, +  const char *redirect_url, +  const char *provider_user_id, +  const char *provider_legitimization_id, +  const char *error_msg_hint) +{ +  ih = NULL; +  if (TALER_EC_NONE != ec) +  { +    fprintf (stderr, +             "Failed to start KYC process: %s (#%d)\n", +             error_msg_hint, +             ec); +    global_ret = EXIT_FAILURE; +    GNUNET_SCHEDULER_shutdown (); +    return; +  } +  fprintf (stdout, +           "Visit `%s' to begin KYC process (%s/%s)\n", +           redirect_url, +           provider_user_id, +           provider_legitimization_id); +} + + +/**   * Main function that will be run by the scheduler.   *   * @param cls closure @@ -1032,6 +1077,17 @@ run (void *cls,    (void) cls;    (void) args;    (void ) cfgfile; +  if (print_h_payto) +  { +    char *s; + +    s = GNUNET_STRINGS_data_to_string_alloc (&cmd_line_h_payto, +                                             sizeof (cmd_line_h_payto)); +    fprintf (stdout, +             "%s\n", +             s); +    GNUNET_free (s); +  }    TALER_MHD_setup (TALER_MHD_GO_NONE);    TEKT_cfg = config;    if (GNUNET_OK != @@ -1041,61 +1097,87 @@ run (void *cls,      GNUNET_SCHEDULER_shutdown ();      return;    } +  GNUNET_SCHEDULER_add_shutdown (&do_shutdown, +                                 NULL);    if (GNUNET_OK !=        exchange_serve_process_config ())    {      global_ret = EXIT_NOTCONFIGURED; -    TALER_KYCLOGIC_kyc_done (); -    GNUNET_SCHEDULER_shutdown (); -    return; -  } -  TEKT_curl_ctx -    = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, -                        &exchange_curl_rc); -  if (NULL == TEKT_curl_ctx) -  { -    GNUNET_break (0); -    global_ret = EXIT_FAILURE;      GNUNET_SCHEDULER_shutdown ();      return;    } -  exchange_curl_rc = GNUNET_CURL_gnunet_rc_create (TEKT_curl_ctx); -  GNUNET_SCHEDULER_add_shutdown (&do_shutdown, -                                 NULL); -  fh = TALER_MHD_bind (TEKT_cfg, -                       "exchange", -                       &serve_port); -  if ( (0 == serve_port) && -       (-1 == fh) ) +  global_ret = EXIT_SUCCESS; +  if (NULL != initiate_section)    { -    GNUNET_SCHEDULER_shutdown (); -    return; +    struct TALER_KYCLOGIC_ProviderDetails *pd; + +    if (GNUNET_OK != +        TALER_KYCLOGIC_kyc_get_logic (initiate_section, +                                      &logic, +                                      &pd)) +    { +      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +                  "Could not initiate KYC with provider `%s' (configuration error?)\n", +                  initiate_section); +      global_ret = EXIT_NOTCONFIGURED; +      GNUNET_SCHEDULER_shutdown (); +      return; +    } +    ih = logic->initiate (logic->cls, +                          pd, +                          &cmd_line_h_payto, +                          kyc_row_id, +                          &initiate_cb, +                          NULL); +    GNUNET_break (NULL != ih);    } -  mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME -                          | MHD_USE_PIPE_FOR_SHUTDOWN -                          | MHD_USE_DEBUG | MHD_USE_DUAL_STACK -                          | MHD_USE_TCP_FASTOPEN, -                          (-1 == fh) ? serve_port : 0, -                          NULL, NULL, -                          &handle_mhd_request, NULL, -                          MHD_OPTION_LISTEN_SOCKET, -                          fh, -                          MHD_OPTION_EXTERNAL_LOGGER, -                          &TALER_MHD_handle_logs, -                          NULL, -                          MHD_OPTION_NOTIFY_COMPLETED, -                          &handle_mhd_completion_callback, -                          NULL, -                          MHD_OPTION_END); -  if (NULL == mhd) +  if (run_webservice)    { -    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, -                "Failed to launch HTTP service. Is the port in use?\n"); -    GNUNET_SCHEDULER_shutdown (); -    return; +    TEKT_curl_ctx +      = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, +                          &exchange_curl_rc); +    if (NULL == TEKT_curl_ctx) +    { +      GNUNET_break (0); +      global_ret = EXIT_FAILURE; +      GNUNET_SCHEDULER_shutdown (); +      return; +    } +    exchange_curl_rc = GNUNET_CURL_gnunet_rc_create (TEKT_curl_ctx); +    fh = TALER_MHD_bind (TEKT_cfg, +                         "exchange", +                         &serve_port); +    if ( (0 == serve_port) && +         (-1 == fh) ) +    { +      GNUNET_SCHEDULER_shutdown (); +      return; +    } +    mhd = MHD_start_daemon (MHD_USE_SUSPEND_RESUME +                            | MHD_USE_PIPE_FOR_SHUTDOWN +                            | MHD_USE_DEBUG | MHD_USE_DUAL_STACK +                            | MHD_USE_TCP_FASTOPEN, +                            (-1 == fh) ? serve_port : 0, +                            NULL, NULL, +                            &handle_mhd_request, NULL, +                            MHD_OPTION_LISTEN_SOCKET, +                            fh, +                            MHD_OPTION_EXTERNAL_LOGGER, +                            &TALER_MHD_handle_logs, +                            NULL, +                            MHD_OPTION_NOTIFY_COMPLETED, +                            &handle_mhd_completion_callback, +                            NULL, +                            MHD_OPTION_END); +    if (NULL == mhd) +    { +      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, +                  "Failed to launch HTTP service. Is the port in use?\n"); +      GNUNET_SCHEDULER_shutdown (); +      return; +    } +    TALER_MHD_daemon_start (mhd);    } -  global_ret = EXIT_SUCCESS; -  TALER_MHD_daemon_start (mhd);  } @@ -1113,11 +1195,43 @@ main (int argc,    const struct GNUNET_GETOPT_CommandLineOption options[] = {      GNUNET_GETOPT_option_help (        "tool to test KYC provider integrations"), +    GNUNET_GETOPT_option_flag ( +      'P', +      "print-payto-hash", +      "output the hash of the payto://-URI", +      &print_h_payto), +    GNUNET_GETOPT_option_uint ( +      'r', +      "rowid", +      "NUMBER", +      "override row ID to use in simulation (default: 42)", +      &kyc_row_id), +    GNUNET_GETOPT_option_flag ( +      'w', +      "run-webservice", +      "run the integrated HTTP service", +      &run_webservice), +    GNUNET_GETOPT_option_string ( +      'i', +      "initiate", +      "SECTION_NAME", +      "initiate KYC check using provider configured in SECTION_NAME of the configuration", +      &initiate_section), +    GNUNET_GETOPT_option_base32_fixed_size ( +      'p', +      "payto-hash", +      "URI", +      "base32 encoding of the hash of a payto://-URI to use for the account (otherwise a random value will be used)", +      &cmd_line_h_payto, +      sizeof (cmd_line_h_payto)),      GNUNET_GETOPT_OPTION_END    };    enum GNUNET_GenericReturnValue ret;    TALER_OS_init (); +  GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, +                              &cmd_line_h_payto, +                              sizeof (cmd_line_h_payto));    ret = GNUNET_PROGRAM_run (argc, argv,                              "taler-exchange-kyc-tester",                              "tool to test KYC provider integrations", | 
