gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: implement parser for taler_pay_u


From: gnunet
Subject: [taler-merchant] branch master updated: implement parser for taler_pay_uri
Date: Mon, 10 Aug 2020 05:29:07 +0200

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

jonathan-buchanan pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 119de8d  implement parser for taler_pay_uri
119de8d is described below

commit 119de8db9e317e46ebe800524b806809d2b435b0
Author: Jonathan Buchanan <jonathan.russ.buchanan@gmail.com>
AuthorDate: Sun Aug 9 23:28:56 2020 -0400

    implement parser for taler_pay_uri
---
 src/include/taler_merchant_service.h             |  67 +++++--
 src/lib/merchant_api_common.c                    | 220 +++++++++++++++++++++++
 src/testing/testing_api_cmd_merchant_get_order.c |  25 +++
 3 files changed, 296 insertions(+), 16 deletions(-)

diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index 19438f9..b33941a 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -136,29 +136,64 @@ TALER_MERCHANT_baseurl_add_instance (const char *base_url,
                                      const char *instance_id);
 
 
+/**
+ * Contains information gathered from parsing a taler://pay URI.
+ */
+struct TALER_MERCHANT_PayUriData
+{
+  /**
+   * Hostname (and possibly port) of the merchant.
+   */
+  char *merchant_host;
+
+  /**
+   * Prefix to the base url of the merchant backend. May be NULL.
+   */
+  char *merchant_prefix_path;
+
+  /**
+   * The id of the order to pay.
+   */
+  char *order_id;
+
+  /**
+   * Session id to use when paying the order. May be NULL.
+   */
+  char *session_id;
+
+  /**
+   * Claim token to use when claiming the order. May be NULL.
+   */
+  struct TALER_ClaimTokenP *claim_token;
+
+  /**
+   * A WLAN SSID that the wallet can use to connect to the internet in order to
+   * to pay. May be NULL.
+   */
+  char *ssid;
+};
+
+
 /**
  * Extracts information from a taler://pay URI.
  *
  * @param pay_uri the URI to parse.
- * @param[out] merchant_host the hostname of the merchant.
- * @param[out] merchant_prefix_path prefix of the base URL
- *             (NULL if not present).
- * @param[out] order_id the id of the order to pay.
- * @param[out] session_id the session id to use for payment
- *             (NULL if not present).
- * @param[out] claim_token the claim token needed to claim the order
- *             (zeroed if not present).
- * @param[out] ssid the ssid for internet connectivity (NULL if not present).
- * @return GNUNET_OK on success, GNUNET_SYSERR otherwise.
+ * @param[out] parse_data data extracted from the URI. Must be free'd.
+ * @return GNUNET_SYSERR if @e pay_uri is malformed, GNUNET_OK otherwise.
  */
 int
 TALER_MERCHANT_parse_pay_uri (const char *pay_uri,
-                              const char **merchant_host,
-                              const char **merchant_prefix_path,
-                              const char **order_id,
-                              const char **session_id,
-                              struct GNUNET_HashCode *claim_token,
-                              const char **ssid);
+                              struct TALER_MERCHANT_PayUriData *parse_data);
+
+
+/**
+ * Frees data contained in the result of parsing a taler://pay URI.
+ *
+ * @param parse_data the data to free.
+ */
+void
+TALER_MERCHANT_parse_pay_uri_free (
+  struct TALER_MERCHANT_PayUriData *parse_data);
 
 
 /**
diff --git a/src/lib/merchant_api_common.c b/src/lib/merchant_api_common.c
index 4d69e72..9745f77 100644
--- a/src/lib/merchant_api_common.c
+++ b/src/lib/merchant_api_common.c
@@ -150,3 +150,223 @@ TALER_MERCHANT_baseurl_add_instance (const char *base_url,
                    instance_id);
   return ret;
 }
+
+
+/**
+ * Parses the URI scheme and action of a URI. Ensures that the scheme is either
+ * 'taler' or 'taler+http'.
+ *
+ * @param uri the uri to parse.
+ * @param[out] action the action the URI is indicating.
+ * @param[out] rest the substring of the URI following the action.
+ * @return GNUNET_SYSERR if the URI is malformed, GNUNET_OK otherwise.
+ */
+static int
+parse_taler_uri_scheme_action (const char *uri,
+                               char **action,
+                               char **rest)
+{
+  char *scheme = GNUNET_strdup (uri);
+  /* Check that the uri starts with "taler://pay" or "taler+http://pay"; and
+     then remove it */
+  char *path = strchr (scheme, ':');
+  if ((NULL == path) ||
+      (strlen (path) < 3))
+  {
+    GNUNET_free (scheme);
+    return GNUNET_SYSERR;
+  }
+  path += 3;
+
+  {
+    char path_begin = *path;
+    *path = '\0';
+    if ((0 != strcmp ("taler://",
+                      scheme)) &&
+        (0 != strcmp ("taler+http://";,
+                      scheme)))
+    {
+      GNUNET_free (scheme);
+      return GNUNET_SYSERR;
+    }
+    *path = path_begin;
+  }
+
+  {
+    char *pqf = strchr (path, '/');
+    if (NULL == pqf)
+    {
+      GNUNET_free (scheme);
+      return GNUNET_SYSERR;
+    }
+    *pqf = '\0';
+    ++pqf;
+    *rest = GNUNET_strdup (pqf);
+  }
+  *action = GNUNET_strdup (path);
+
+  GNUNET_free (scheme);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Finds the last occurrence of @e c in the string @e str.
+ *
+ * @param str the string to search in.
+ * @param c the character to search for.
+ * @return pointer to the last occurrence of @e c in @e str, if it exists,
+ *         otherwise NULL.
+ */
+static char *
+strchr_last (char *str,
+             char c)
+{
+  for (size_t i = strlen (str) - 1; i >= 0; --i)
+  {
+    if (c == str[i])
+      return &str[i];
+  }
+  return NULL;
+}
+
+
+/**
+ * Extracts information from a taler://pay URI.
+ *
+ * @param pay_uri the URI to parse.
+ * @param[out] parse_data data extracted from the URI. Must be free'd.
+ * @return GNUNET_SYSERR if @e pay_uri is malformed, GNUNET_OK otherwise.
+ */
+int
+TALER_MERCHANT_parse_pay_uri (const char *pay_uri,
+                              struct TALER_MERCHANT_PayUriData *parse_data)
+{
+  char *path;
+  {
+    char *action;
+
+    if ((GNUNET_OK !=
+         parse_taler_uri_scheme_action (pay_uri,
+                                        &action,
+                                        &path)) ||
+        (0 != strcmp ("pay",
+                      action)))
+    {
+      GNUNET_free (action);
+      GNUNET_free (path);
+      return GNUNET_SYSERR;
+    }
+    GNUNET_free (action);
+  }
+
+  {
+    char *mpp;
+    char *order_id;
+    char *session_id = strchr_last (path,
+                                    '/');
+    struct TALER_ClaimTokenP *claim_token = NULL;
+    char *ssid;
+
+    if (NULL == session_id)
+    {
+      GNUNET_free (path);
+      return GNUNET_SYSERR;
+    }
+    *session_id = '\0';
+    ++session_id;
+
+    order_id = strchr_last (path,
+                            '/');
+    if (NULL == order_id)
+    {
+      GNUNET_free (path);
+      return GNUNET_SYSERR;
+    }
+    *order_id = '\0';
+    ++order_id;
+
+    {
+      char *ct_str = strchr (session_id,
+                             '?');
+      char *ct_data;
+      if (NULL != ct_str)
+      {
+        *ct_str = '\0';
+        ++ct_str;
+      }
+
+      ssid = strchr (session_id,
+                     '#');
+      if (NULL != ssid)
+      {
+        *ssid = '\0';
+        ++ssid;
+      }
+
+      if (NULL != ct_str)
+      {
+        ct_data = strchr (ct_str,
+                          '=');
+        if (NULL == ct_data)
+        {
+          GNUNET_free (order_id);
+          return GNUNET_SYSERR;
+        }
+        *ct_data = '\0';
+        ++ct_data;
+        claim_token = GNUNET_new (struct TALER_ClaimTokenP);
+        if ((0 != strcmp ("c",
+                          ct_str)) ||
+            (GNUNET_OK !=
+             GNUNET_STRINGS_string_to_data (ct_data,
+                                            strlen (ct_data),
+                                            claim_token,
+                                            sizeof (*claim_token))))
+        {
+          GNUNET_free (order_id);
+          GNUNET_free (claim_token);
+          return GNUNET_SYSERR;
+        }
+      }
+    }
+
+    mpp = strchr (path,
+                  '/');
+    if (NULL != mpp)
+    {
+      *mpp = '\0';
+      ++mpp;
+    }
+
+    parse_data->merchant_host = GNUNET_strdup (path);
+    parse_data->merchant_prefix_path =
+      (NULL == mpp) ? NULL : GNUNET_strdup (mpp);
+    parse_data->order_id = GNUNET_strdup (order_id);
+    parse_data->session_id =
+      (0 < strlen (session_id)) ? GNUNET_strdup (session_id) : NULL;
+    parse_data->claim_token = claim_token;
+    parse_data->ssid =
+      (NULL == ssid) ? NULL : GNUNET_strdup (ssid);
+  }
+  GNUNET_free (path);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Frees data contained in the result of parsing a taler://pay URI.
+ *
+ * @param parse_data the data to free.
+ */
+void
+TALER_MERCHANT_parse_pay_uri_free (
+  struct TALER_MERCHANT_PayUriData *parse_data)
+{
+  GNUNET_free (parse_data->merchant_host);
+  GNUNET_free (parse_data->merchant_prefix_path);
+  GNUNET_free (parse_data->order_id);
+  GNUNET_free (parse_data->session_id);
+  GNUNET_free (parse_data->claim_token);
+  GNUNET_free (parse_data->ssid);
+}
diff --git a/src/testing/testing_api_cmd_merchant_get_order.c 
b/src/testing/testing_api_cmd_merchant_get_order.c
index 4ae459a..1da6b7b 100644
--- a/src/testing/testing_api_cmd_merchant_get_order.c
+++ b/src/testing/testing_api_cmd_merchant_get_order.c
@@ -441,6 +441,31 @@ merchant_get_order_cb (
         return;
       }
     }
+    else
+    {
+      /* FIXME: Check all of the members of `pud` */
+      struct TALER_MERCHANT_PayUriData pud;
+      if (GNUNET_OK !=
+          TALER_MERCHANT_parse_pay_uri (osr->details.unpaid.taler_pay_uri,
+                                        &pud))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "Taler pay uri is malformed\n");
+        TALER_TESTING_interpreter_fail (gos->is);
+        return;
+      }
+
+      if ((0 != strcmp ("localhost:8080",
+                        pud.merchant_host)) ||
+          (NULL != pud.merchant_prefix_path))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "Taler pay uri is incorrect\n");
+        TALER_TESTING_interpreter_fail (gos->is);
+        TALER_MERCHANT_parse_pay_uri_free (&pud);
+        return;
+      }
+    }
     break;
   default:
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,

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