gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 16/51: pay: fetch and parse choices from db


From: gnunet
Subject: [taler-merchant] 16/51: pay: fetch and parse choices from db
Date: Thu, 13 Jun 2024 17:03:25 +0200

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

christian-blaettler pushed a commit to branch master
in repository merchant.

commit e3965464791470843660ccf2f54fced53ffffcdf
Author: Christian Blättler <blatc2@bfh.ch>
AuthorDate: Sun Apr 21 12:23:04 2024 +0200

    pay: fetch and parse choices from db
---
 src/backend/taler-merchant-httpd_contract.c        | 229 ++++++++++++++++++++-
 src/backend/taler-merchant-httpd_contract.h        |  26 ++-
 .../taler-merchant-httpd_post-orders-ID-pay.c      |  21 +-
 3 files changed, 269 insertions(+), 7 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_contract.c 
b/src/backend/taler-merchant-httpd_contract.c
index 38c82e70..60f45776 100644
--- a/src/backend/taler-merchant-httpd_contract.c
+++ b/src/backend/taler-merchant-httpd_contract.c
@@ -23,7 +23,7 @@
 #include "taler-merchant-httpd_contract.h"
 
 enum TALER_MerchantContractInputType
-TMH_string_to_contract_input_type (const char *str)
+TMH_contract_input_type_from_string (const char *str)
 {
   /* For now, only 'token' is the only supported option. */
   if (0 == strcmp("token", str))
@@ -35,7 +35,7 @@ TMH_string_to_contract_input_type (const char *str)
 }
 
 enum TALER_MerchantContractOutputType
-TMH_string_to_contract_output_type (const char *str)
+TMH_contract_output_type_from_string (const char *str)
 {
   /* For now, only 'token' is the only supported option. */
   if (0 == strcmp("token", str))
@@ -45,3 +45,228 @@ TMH_string_to_contract_output_type (const char *str)
 
   return TALER_MCOT_INVALID;
 }
+
+const char *
+TMH_string_from_contract_input_type (enum TALER_MerchantContractInputType t)
+{
+  switch (t) {
+  case TALER_MCIT_TOKEN:
+    return "token";
+  case TALER_MCIT_COIN:
+    return "coin";
+  default:
+    return "invalid";
+  }
+}
+
+const char *
+TMH_string_from_contract_output_type (enum TALER_MerchantContractOutputType t)
+{
+  switch (t) {
+  case TALER_MCOT_TOKEN:
+    return "token";
+  case TALER_MCOT_COIN:
+    return "coin";
+  case TALER_MCOT_TAX_RECEIPT:
+    return "tax_receipt";
+  default:
+    return "invalid";
+  }
+}
+
+/**
+ * Parse given JSON object to choices array.
+ *
+ * @param cls closure, pointer to array length
+ * @param root the json array representing the choices
+ * @param[out] spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static enum GNUNET_GenericReturnValue
+parse_choice (void *cls,
+              json_t *root,
+              struct GNUNET_JSON_Specification *spec)
+{
+  struct TALER_MerchantContractChoice **choices = spec->ptr;
+  unsigned int *choices_len = cls;
+  if (!json_is_array (root))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+
+  GNUNET_array_grow (*choices,
+                     *choices_len,
+                     json_array_size (root));
+
+  for (unsigned int i = 0; i<*choices_len; i++)
+  {
+    const json_t *jinputs;
+    const json_t *joutputs;
+    struct GNUNET_JSON_Specification spec[] = {
+      GNUNET_JSON_spec_array_const ("inputs",
+                                    &jinputs),
+      GNUNET_JSON_spec_array_const ("outputs",
+                                    &joutputs),
+      GNUNET_JSON_spec_end ()
+    };
+    const char *error_name;
+    unsigned int error_line;
+    struct TALER_MerchantContractChoice *choice = &(*choices)[i];
+
+    if (GNUNET_OK !=
+        GNUNET_JSON_parse (json_array_get (root, i),
+                          spec,
+                          &error_name,
+                          &error_line))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Failed to parse %s at %u: %s\n",
+                  spec[error_line].field,
+                  error_line,
+                  error_name);
+      GNUNET_break_op (0);
+      return GNUNET_SYSERR;
+    }
+
+    {
+      const json_t *jinput;
+      size_t idx;
+      json_array_foreach ((json_t *) jinputs, idx, jinput)
+      {
+        struct TALER_MerchantContractInput input = {.details.token.count = 1};
+        const char *kind;
+        struct GNUNET_JSON_Specification ispec[] = {
+          GNUNET_JSON_spec_string ("kind",
+                                    &kind),
+          GNUNET_JSON_spec_string ("token_family_slug",
+                                    &input.details.token.token_family_slug),
+          GNUNET_JSON_spec_timestamp ("valid_after",
+                                      &input.details.token.valid_after),
+          GNUNET_JSON_spec_mark_optional (
+            GNUNET_JSON_spec_uint32 ("count",
+                                      &input.details.token.count),
+            NULL),
+          GNUNET_JSON_spec_end()
+        };
+        const char *ierror_name;
+        unsigned int ierror_line;
+
+        if (GNUNET_OK !=
+            GNUNET_JSON_parse (jinput,
+                                ispec,
+                                &ierror_name,
+                                &ierror_line))
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                      "Failed to parse %s at %u: %s\n",
+                      spec[ierror_line].field,
+                      ierror_line,
+                      ierror_name);
+          GNUNET_break_op (0);
+          return GNUNET_SYSERR;
+        }
+
+        input.type = TMH_contract_input_type_from_string (kind);
+
+        if (TALER_MCIT_INVALID == input.type)
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                      "Field 'kind' invalid in input #%u\n",
+                      (unsigned int) idx);
+          GNUNET_break_op (0);
+          return GNUNET_SYSERR;
+        }
+
+        if (0 == input.details.token.count)
+        {
+          /* Ignore inputs with 'number' field set to 0 */
+          continue;
+        }
+
+        GNUNET_array_append (choice->inputs,
+                             choice->inputs_len,
+                             input);
+      }
+    }
+
+    {
+      const json_t *joutput;
+      size_t idx;
+      json_array_foreach ((json_t *) joutputs, idx, joutput)
+      {
+        struct TALER_MerchantContractOutput output = {.details.token.count = 
1};
+        const char *kind;
+        struct GNUNET_JSON_Specification ispec[] = {
+          GNUNET_JSON_spec_string ("kind",
+                                    &kind),
+          GNUNET_JSON_spec_string ("token_family_slug",
+                                    &output.details.token.token_family_slug),
+          GNUNET_JSON_spec_timestamp ("valid_after",
+                                      &output.details.token.valid_after),
+          GNUNET_JSON_spec_mark_optional (
+            GNUNET_JSON_spec_uint32 ("count",
+                                      &output.details.token.count),
+            NULL),
+          GNUNET_JSON_spec_end()
+        };
+        const char *ierror_name;
+        unsigned int ierror_line;
+
+        if (GNUNET_OK !=
+            GNUNET_JSON_parse (joutput,
+                                ispec,
+                                &ierror_name,
+                                &ierror_line))
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                      "Failed to parse %s at %u: %s\n",
+                      spec[ierror_line].field,
+                      ierror_line,
+                      ierror_name);
+          GNUNET_break_op (0);
+          return GNUNET_SYSERR;
+        }
+
+        output.type = TMH_contract_output_type_from_string (kind);
+
+        if (TALER_MCOT_INVALID == output.type)
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                      "Field 'kind' invalid in output #%u\n",
+                      (unsigned int) idx);
+          GNUNET_break_op (0);
+          return GNUNET_SYSERR;
+        }
+
+        if (0 == output.details.token.count)
+        {
+          /* Ignore outputs with 'number' field set to 0 */
+          continue;
+        }
+
+        GNUNET_array_append (choice->outputs,
+                             choice->outputs_len,
+                             output);
+      }
+    }
+  }
+
+  return GNUNET_OK;
+}
+
+
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_choices (const char *name,
+                         struct TALER_MerchantContractChoice **choices,
+                         unsigned int *choices_len)
+{
+  struct GNUNET_JSON_Specification ret = {
+    .cls = (void *) choices_len,
+    .parser = &parse_choice,
+    .field = name,
+    .ptr = choices,
+  };
+
+  return ret;
+}
\ No newline at end of file
diff --git a/src/backend/taler-merchant-httpd_contract.h 
b/src/backend/taler-merchant-httpd_contract.h
index b231d732..ee77b4c1 100644
--- a/src/backend/taler-merchant-httpd_contract.h
+++ b/src/backend/taler-merchant-httpd_contract.h
@@ -551,10 +551,16 @@ struct TALER_MerchantContract
 };
 
 enum TALER_MerchantContractInputType
-TMH_string_to_contract_input_type (const char *str);
+TMH_contract_input_type_from_string (const char *str);
 
 enum TALER_MerchantContractOutputType
-TMH_string_to_contract_output_type (const char *str);
+TMH_contract_output_type_from_string (const char *str);
+
+const char *
+TMH_string_from_contract_input_type (enum TALER_MerchantContractInputType t);
+
+const char *
+TMH_string_from_contract_output_type (enum TALER_MerchantContractOutputType t);
 
 /**
  * Serialize @a contract to a JSON object, ready to be stored in the database.
@@ -584,4 +590,18 @@ enum GNUNET_GenericReturnValue
 TMH_serialize_contract_v1 (const struct TALER_MerchantContract *contract,
                            const struct TMH_MerchantInstance *instance,
                            json_t *exchanges,
-                           json_t **out);
\ No newline at end of file
+                           json_t **out);
+
+/**
+ * Provide specification to parse given JSON array to an array
+ * of contract choices.
+ *
+ * @param name name of the choices field in the JSON
+ * @param[out] choices pointer to the first element of the array
+ * @param[out] choices_len pointer to the length of the array
+ * @return spec for parsing a choices array
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_choices (const char *name,
+                         struct TALER_MerchantContractChoice **choices,
+                         unsigned int *choices_len);
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c 
b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index 2bdf891f..5532f1ab 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -26,12 +26,14 @@
  */
 #include "platform.h"
 #include <gnunet/gnunet_json_lib.h>
+#include <jansson.h>
 #include <stdint.h>
 #include <taler/taler_dbevents.h>
 #include <taler/taler_signatures.h>
 #include <taler/taler_json_lib.h>
 #include <taler/taler_exchange_service.h>
 #include "taler-merchant-httpd_exchanges.h"
+#include "taler-merchant-httpd_contract.h"
 #include "taler-merchant-httpd_helper.h"
 #include "taler-merchant-httpd_post-orders-ID-pay.h"
 #include "taler-merchant-httpd_private-get-orders.h"
@@ -316,6 +318,11 @@ struct PayContext
    */
   struct TokenUseConfirmation *tokens;
 
+  /**
+   * Array with @e choices_cnt choices from the contract terms.
+   */
+  struct TALER_MerchantContractChoice *choices;
+
   /**
    * MHD connection to return to
    */
@@ -474,6 +481,11 @@ struct PayContext
    */
   size_t tokens_cnt;
 
+  /**
+   * Length of the @e choices array.
+   */
+  unsigned int choices_len;
+
   /**
    * Number of exchanges involved in the payment. Length
    * of the @e eg array.
@@ -2342,6 +2354,11 @@ phase_check_contract (struct PayContext *pc)
                                   &pc->pay_deadline),
       GNUNET_JSON_spec_timestamp ("wire_transfer_deadline",
                                   &pc->wire_transfer_deadline),
+      GNUNET_JSON_spec_mark_optional (
+        TALER_JSON_spec_choices ("choices",
+                                 &pc->choices,
+                                 &pc->choices_len),
+        NULL),
       GNUNET_JSON_spec_fixed_auto ("h_wire",
                                    &pc->h_wire),
       GNUNET_JSON_spec_mark_optional (
@@ -2667,8 +2684,8 @@ phase_parse_pay (struct PayContext *pc)
                                      &tuc->sig),
         GNUNET_JSON_spec_fixed_auto ("token_pub",
                                      &tuc->pub),
-        // TALER_JSON_spec_denom_sig ("ub_sig",
-        //                            &tuc->unblinded_sig),
+        TALER_JSON_spec_token_issue_sig ("ub_sig",
+                                         &tuc->unblinded_sig),
         GNUNET_JSON_spec_fixed_auto ("h_issue",
                                      &tuc->h_issue),
         GNUNET_JSON_spec_end ()

-- 
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]