diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-11-03 14:44:25 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-11-03 14:44:25 +0100 |
commit | ee57a5f9c481555d0462012439a99778a2dbcbcb (patch) | |
tree | 223b26d17fdeecc19194ca661ac1b15fcf067f36 /src/kyclogic/plugin_kyclogic_oauth2.c | |
parent | 082728f839e909453b60ba76396a9ae30f86a58f (diff) | |
download | exchange-ee57a5f9c481555d0462012439a99778a2dbcbcb.tar.gz exchange-ee57a5f9c481555d0462012439a99778a2dbcbcb.tar.bz2 exchange-ee57a5f9c481555d0462012439a99778a2dbcbcb.zip |
add external converter logic for oauth2 plugin
Diffstat (limited to 'src/kyclogic/plugin_kyclogic_oauth2.c')
-rw-r--r-- | src/kyclogic/plugin_kyclogic_oauth2.c | 204 |
1 files changed, 87 insertions, 117 deletions
diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c b/src/kyclogic/plugin_kyclogic_oauth2.c index 4bd0bbfef..5ef1330ad 100644 --- a/src/kyclogic/plugin_kyclogic_oauth2.c +++ b/src/kyclogic/plugin_kyclogic_oauth2.c @@ -113,10 +113,10 @@ struct TALER_KYCLOGIC_ProviderDetails char *post_kyc_redirect_url; /** - * Template for converting user-data returned by - * the provider into our KYC attribute data. + * Name of the program we use to convert outputs + * from Persona into our JSON inputs. */ - char *attribute_template; + char *conversion_binary; /** * Validity time for a successful KYC process. @@ -188,6 +188,12 @@ struct TALER_KYCLOGIC_ProofHandle struct MHD_Connection *connection; /** + * Handle to an external process that converts the + * Persona response to our internal format. + */ + struct TALER_JSON_ExternalConversion *ec; + + /** * Hash of the payto URI that this is about. */ struct TALER_PaytoHashP h_payto; @@ -301,7 +307,7 @@ oauth2_unload_configuration (struct TALER_KYCLOGIC_ProviderDetails *pd) GNUNET_free (pd->client_id); GNUNET_free (pd->client_secret); GNUNET_free (pd->post_kyc_redirect_url); - GNUNET_free (pd->attribute_template); + GNUNET_free (pd->conversion_binary); GNUNET_free (pd); } @@ -501,16 +507,14 @@ oauth2_load_configuration (void *cls, if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (ps->cfg, provider_section_name, - "KYC_OAUTH2_ATTRIBUTE_TEMPLATE", - &s)) + "KYC_OAUTH2_CONVERTER_HELPER", + &pd->conversion_binary)) { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, provider_section_name, - "KYC_OAUTH2_ATTRIBUTE_TEMPLATE"); - } - else - { - pd->attribute_template = s; + "KYC_OAUTH2_CONVERTER_HELPER"); + oauth2_unload_configuration (pd); + return NULL; } return pd; @@ -791,6 +795,11 @@ oauth2_initiate_cancel (struct TALER_KYCLOGIC_InitiateHandle *ih) static void oauth2_proof_cancel (struct TALER_KYCLOGIC_ProofHandle *ph) { + if (NULL != ph->ec) + { + TALER_JSON_external_conversion_stop (ph->ec); + ph->ec = NULL; + } if (NULL != ph->task) { GNUNET_SCHEDULER_cancel (ph->task); @@ -907,93 +916,26 @@ handle_proof_error (struct TALER_KYCLOGIC_ProofHandle *ph, /** - * Convert user data returned by the provider into - * standardized attribute data. - * - * @param pd our provider configuration - * @param data user-data given by the provider - * @return converted KYC attribute data object - */ -static json_t * -data2attributes (const struct TALER_KYCLOGIC_ProviderDetails *pd, - const json_t *data) -{ - json_t *ret; - void *attr_data; - size_t attr_size; - int rv; - json_error_t err; - - if (NULL == pd->attribute_template) - return json_object (); - if (0 != - (rv = TALER_TEMPLATING_fill (pd->attribute_template, - data, - &attr_data, - &attr_size))) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to convert KYC provider data to attributes: %d\n", - rv); - json_dumpf (data, - stderr, - JSON_INDENT (2)); - return NULL; - } - ret = json_loadb (attr_data, - attr_size, - JSON_REJECT_DUPLICATES, - &err); - GNUNET_free (attr_data); - if (NULL == ret) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse converted KYC attributes as JSON: %s (at offset %d)\n", - err.text, - err.position); - return NULL; - } - return ret; -} - - -/** - * The request for @a ph succeeded (presumably). - * Call continuation with the result. + * Type of a callback that receives a JSON @a result. * - * @param[in,out] ph request that succeeded - * @param j reply from the server + * @param cls closure with a `struct TALER_KYCLOGIC_ProofHandle *` + * @param status_type how did the process die + * @param code termination status code from the process + * @param attr result some JSON result, NULL if we failed to get an JSON output */ static void -parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, - const json_t *j) +converted_proof_cb (void *cls, + enum GNUNET_OS_ProcessStatusType status_type, + unsigned long code, + const json_t *attr) { - // FIXME: this is not OAuth2.0, this is - // already implementation-specific! - // => move into helper shell script! - const char *state; - const json_t *data; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("status", - &state), - GNUNET_JSON_spec_object_const ("data", - &data), - GNUNET_JSON_spec_end () - }; - enum GNUNET_GenericReturnValue res; - const char *emsg; - unsigned int line; - - res = GNUNET_JSON_parse (j, - spec, - &emsg, - &line); - if (GNUNET_OK != res) + struct TALER_KYCLOGIC_ProofHandle *ph = cls; + + ph->ec = NULL; + if ( (NULL == attr) || + (0 != code) ) { GNUNET_break_op (0); - json_dumpf (j, - stderr, - JSON_INDENT (2)); ph->status = TALER_KYCLOGIC_STATUS_PROVIDER_FAILED; ph->response = TALER_MHD_make_error ( @@ -1001,16 +943,11 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, "Unexpected response from KYC gateway: proof success must contain data and status"); ph->http_status = MHD_HTTP_BAD_GATEWAY; + ph->task = GNUNET_SCHEDULER_add_now (&return_proof_response, + ph); return; } - if (0 != strcasecmp (state, - "success")) - { - GNUNET_break_op (0); - handle_proof_error (ph, - j); - return; - } + { const char *id; struct GNUNET_JSON_Specification ispec[] = { @@ -1018,15 +955,18 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, &id), GNUNET_JSON_spec_end () }; + enum GNUNET_GenericReturnValue res; + const char *emsg; + unsigned int line; - res = GNUNET_JSON_parse (data, + res = GNUNET_JSON_parse (attr, ispec, &emsg, &line); if (GNUNET_OK != res) { GNUNET_break_op (0); - json_dumpf (data, + json_dumpf (attr, stderr, JSON_INDENT (2)); ph->status = TALER_KYCLOGIC_STATUS_PROVIDER_FAILED; @@ -1038,21 +978,51 @@ parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, = MHD_HTTP_BAD_GATEWAY; return; } - ph->status = TALER_KYCLOGIC_STATUS_SUCCESS; - ph->response = MHD_create_response_from_buffer (0, - "", - MHD_RESPMEM_PERSISTENT); - GNUNET_assert (NULL != ph->response); - GNUNET_break (MHD_YES == - MHD_add_response_header ( - ph->response, - MHD_HTTP_HEADER_LOCATION, - ph->pd->post_kyc_redirect_url)); - ph->http_status = MHD_HTTP_SEE_OTHER; ph->provider_user_id = GNUNET_strdup (id); } - ph->attributes = data2attributes (ph->pd, - data); + ph->status = TALER_KYCLOGIC_STATUS_SUCCESS; + ph->response = MHD_create_response_from_buffer (0, + "", + MHD_RESPMEM_PERSISTENT); + GNUNET_assert (NULL != ph->response); + GNUNET_break (MHD_YES == + MHD_add_response_header ( + ph->response, + MHD_HTTP_HEADER_LOCATION, + ph->pd->post_kyc_redirect_url)); + ph->http_status = MHD_HTTP_SEE_OTHER; + ph->attributes = json_incref ((json_t *) attr); + ph->task = GNUNET_SCHEDULER_add_now (&return_proof_response, + ph); +} + + +/** + * The request for @a ph succeeded (presumably). + * Call continuation with the result. + * + * @param[in,out] ph request that succeeded + * @param j reply from the server + */ +static void +parse_proof_success_reply (struct TALER_KYCLOGIC_ProofHandle *ph, + const json_t *j) +{ + const struct TALER_KYCLOGIC_ProviderDetails *pd = ph->pd; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Calling converter `%s' with JSON\n", + pd->conversion_binary); + json_dumpf (j, + stderr, + JSON_INDENT (2)); + ph->ec = TALER_JSON_external_conversion_start ( + j, + &converted_proof_cb, + ph, + pd->conversion_binary, + pd->conversion_binary, + NULL); } @@ -1079,7 +1049,7 @@ handle_curl_proof_finished (void *cls, case MHD_HTTP_OK: parse_proof_success_reply (ph, j); - break; + return; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "OAuth2.0 info URL returned HTTP status %u\n", |