gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: add external converter logic for


From: gnunet
Subject: [taler-exchange] branch master updated: add external converter logic for oauth2 plugin
Date: Fri, 03 Nov 2023 14:44:28 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new ee57a5f9 add external converter logic for oauth2 plugin
ee57a5f9 is described below

commit ee57a5f9c481555d0462012439a99778a2dbcbcb
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Fri Nov 3 14:44:25 2023 +0100

    add external converter logic for oauth2 plugin
---
 src/kyclogic/Makefile.am                           |   5 +-
 src/kyclogic/kyclogic-oauth2.conf                  |   6 +-
 src/kyclogic/plugin_kyclogic_oauth2.c              | 204 +++++++++------------
 .../taler-exchange-kyc-oauth2-challenger.sh        |   0
 src/kyclogic/taler-exchange-kyc-oauth2-nda.sh      |   0
 .../taler-exchange-kyc-oauth2-test-converter.sh    |  23 +++
 src/testing/test_kyc_api.conf                      |   3 +-
 7 files changed, 119 insertions(+), 122 deletions(-)

diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am
index 91ec901e..3e98a956 100644
--- a/src/kyclogic/Makefile.am
+++ b/src/kyclogic/Makefile.am
@@ -16,7 +16,10 @@ pkgcfg_DATA = \
 
 bin_SCRIPTS = \
   taler-exchange-kyc-kycaid-converter.sh \
-  taler-exchange-kyc-persona-converter.sh
+  taler-exchange-kyc-persona-converter.sh \
+  taler-exchange-kyc-oauth2-test-converter.sh \
+  taler-exchange-kyc-oauth2-challenger.sh \
+  taler-exchange-kyc-oauth2-nda.sh 
 
 EXTRA_DIST = \
   $(pkgcfg_DATA) \
diff --git a/src/kyclogic/kyclogic-oauth2.conf 
b/src/kyclogic/kyclogic-oauth2.conf
index 61b38367..57e1fc13 100644
--- a/src/kyclogic/kyclogic-oauth2.conf
+++ b/src/kyclogic/kyclogic-oauth2.conf
@@ -29,7 +29,7 @@ KYC_OAUTH2_CLIENT_SECRET = password
 # Mustach template that converts OAuth2.0 data about the user
 # into GNU Taler standardized attribute data.
 #
-# This is just an example, details will depend on the
-# provider!
+# This is just an example, you need to pick the right converter
+# for the provider!
 #
-KYC_OAUTH2_ATTRIBUTE_TEMPLATE = "{"fullname":"{{last_name}}, 
{{first_name}}","phone":"{{phone}}"}"
\ No newline at end of file
+KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-converter.sh
diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c 
b/src/kyclogic/plugin_kyclogic_oauth2.c
index 4bd0bbfe..5ef1330a 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.
@@ -187,6 +187,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.
    */
@@ -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",
diff --git a/src/kyclogic/taler-exchange-kyc-oauth2-challenger.sh 
b/src/kyclogic/taler-exchange-kyc-oauth2-challenger.sh
old mode 100644
new mode 100755
diff --git a/src/kyclogic/taler-exchange-kyc-oauth2-nda.sh 
b/src/kyclogic/taler-exchange-kyc-oauth2-nda.sh
old mode 100644
new mode 100755
diff --git a/src/kyclogic/taler-exchange-kyc-oauth2-test-converter.sh 
b/src/kyclogic/taler-exchange-kyc-oauth2-test-converter.sh
new file mode 100755
index 00000000..06b8ed1a
--- /dev/null
+++ b/src/kyclogic/taler-exchange-kyc-oauth2-test-converter.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# This file is in the public domain.
+#
+# This code converts (some of) the JSON output from
+# Challenger into the GNU Taler
+# specific KYC attribute data (again in JSON format).
+#
+
+# Die if anything goes wrong.
+set -eu
+
+
+# First, extract everything from stdin.
+J=$(jq '{"first":.first_name,"last".last_name"}')
+
+# Next, combine some fields into larger values.
+FULLNAME=$(echo "$J" | jq -r '[.first,.last]|join(" ")')
+
+jq \
+   --arg full_name "${FULLNAME}" \
+  '{$full_name}'
+
+exit 0
diff --git a/src/testing/test_kyc_api.conf b/src/testing/test_kyc_api.conf
index 7a212623..b6bfdb05 100644
--- a/src/testing/test_kyc_api.conf
+++ b/src/testing/test_kyc_api.conf
@@ -15,7 +15,8 @@ KYC_OAUTH2_INFO_URL = http://localhost:6666/api/user/me
 KYC_OAUTH2_CLIENT_ID = taler-exchange
 KYC_OAUTH2_CLIENT_SECRET = exchange-secret
 KYC_OAUTH2_POST_URL = http://example.com/
-KYC_OAUTH2_ATTRIBUTE_TEMPLATE = "{"full_name":"{{last_name}}, {{first_name}}"}"
+KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-test-converter.sh
+# "{"full_name":"{{last_name}}, {{first_name}}"}"
 
 [kyc-legitimization-balance-high]
 OPERATION_TYPE = BALANCE

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]