gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] 01/02: Initial work on client code


From: gnunet
Subject: [taler-anastasis] 01/02: Initial work on client code
Date: Sat, 16 Nov 2019 12:12:33 +0100

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

dennis-neufeld pushed a commit to branch master
in repository anastasis.

commit 97786f33b3fa233970cc9215aaf421a2c648f10d
Author: Dennis Neufeld <address@hidden>
AuthorDate: Sat Nov 16 10:58:57 2019 +0000

    Initial work on client code
---
 src/backend/anastasis-httpd.c        |   4 +-
 src/backend/anastasis-httpd_policy.c |  16 +-
 src/backend/anastasis-httpd_policy.h |   4 +-
 src/include/anastasis_error_codes.h  |  11 +-
 src/include/anastasis_service.h      |  67 ++++++++
 src/lib/Makefile.am                  |   4 +-
 src/lib/anastasis_api_policy.c       | 300 +++++++++++++++++++++++++++++++++++
 7 files changed, 390 insertions(+), 16 deletions(-)

diff --git a/src/backend/anastasis-httpd.c b/src/backend/anastasis-httpd.c
index fbd11a0..680e9c7 100644
--- a/src/backend/anastasis-httpd.c
+++ b/src/backend/anastasis-httpd.c
@@ -204,13 +204,13 @@ url_handler (void *cls,
     // return handle_policy (...);
     if (0 == strcmp (method, MHD_HTTP_METHOD_GET))
     {
-      return ANASTASIS_MHD_handler_policy_GET (connection,
+      return AH_handler_policy_GET (connection,
                                                url,
                                                con_cls);
     }
     if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
     {
-      return ANASTASIS_MHD_handler_policy_POST (connection,
+      return AH_handler_policy_POST (connection,
                                                 con_cls,
                                                 url,
                                                 upload_data,
diff --git a/src/backend/anastasis-httpd_policy.c 
b/src/backend/anastasis-httpd_policy.c
index 28d517f..1db1043 100644
--- a/src/backend/anastasis-httpd_policy.c
+++ b/src/backend/anastasis-httpd_policy.c
@@ -32,9 +32,9 @@
  * @return MHD result code
  */
 int
-ANASTASIS_MHD_handler_policy_GET (struct MHD_Connection *connection,
-                                  const char *url,
-                                  void **con_cls)
+AH_handler_policy_GET (struct MHD_Connection *connection,
+                       const char *url,
+                       void **con_cls)
 {
   struct ANASTASIS_AccountPubP accountPubP;
   const char *version_s;
@@ -117,11 +117,11 @@ ANASTASIS_MHD_handler_policy_GET (struct MHD_Connection 
*connection,
  * @return MHD result code
  */
 int
-ANASTASIS_MHD_handler_policy_POST (struct MHD_Connection *connection,
-                                   void **con_cls,
-                                   const char *url,
-                                   const char *upload_data,
-                                   size_t *upload_data_size)
+AH_handler_policy_POST (struct MHD_Connection *connection,
+                        void **con_cls,
+                        const char *url,
+                        const char *upload_data,
+                        size_t *upload_data_size)
 {
 
 
diff --git a/src/backend/anastasis-httpd_policy.h 
b/src/backend/anastasis-httpd_policy.h
index 8b4753a..07619fa 100644
--- a/src/backend/anastasis-httpd_policy.h
+++ b/src/backend/anastasis-httpd_policy.h
@@ -32,7 +32,7 @@
  * @return MHD result code
  */
 int
-ANASTASIS_MHD_handler_policy_GET (struct MHD_Connection *connection,
+AH_handler_policy_GET (struct MHD_Connection *connection,
                                   const char *url,
                                   void **con_cls);
 
@@ -44,7 +44,7 @@ ANASTASIS_MHD_handler_policy_GET (struct MHD_Connection 
*connection,
  * @return MHD result code
  */
 int
-ANASTASIS_MHD_handler_policy_POST (struct MHD_Connection *connection,
+AH_handler_policy_POST (struct MHD_Connection *connection,
                                    void **con_cls,
                                    const char *url,
                                    const char *upload_data,
diff --git a/src/include/anastasis_error_codes.h 
b/src/include/anastasis_error_codes.h
index a722ac9..0ad7f6c 100644
--- a/src/include/anastasis_error_codes.h
+++ b/src/include/anastasis_error_codes.h
@@ -39,20 +39,25 @@
 */
 enum ANASTASIS_ErrorCode
 {
+  /**
+   * Special code to indicate no error (or no "code" present).
+   */
+  ANASTASIS_EC_NONE = 6000,
+
   /**
    * The specified User was unknown
    */
-  ANASTASIS_EC_DB_STATUS_UNKNOWN_USER = 6000,
+  ANASTASIS_EC_DB_STATUS_UNKNOWN_USER = 6100,
 
   /**
   * The Users Payment had not sufficient posts left
   */
-  ANASTASIS_EC_DB_STATUS_NOT_SUFFICIENT_POSTS = 6001,
+  ANASTASIS_EC_DB_STATUS_NOT_SUFFICIENT_POSTS = 6201,
 
   /**
   * The Payment from the User has expired.
   */
-  ANASTASIS_EC_DB_STATUS_PAYMENT_EXPIRED = 6002
+  ANASTASIS_EC_DB_STATUS_PAYMENT_EXPIRED = 6202,
 };
 
 #endif
diff --git a/src/include/anastasis_service.h b/src/include/anastasis_service.h
index 7e65055..6efa6a7 100644
--- a/src/include/anastasis_service.h
+++ b/src/include/anastasis_service.h
@@ -26,6 +26,7 @@
 
 #include <gnunet/gnunet_curl_lib.h>
 #include <jansson.h>
+#include "anastasis_error_codes.h"
 
 
 /**
@@ -74,6 +75,72 @@ void
 ANASTASIS_salt_cancel (struct ANASTASIS_SaltOperation *so);
 
 
+/**
+ * Handle for a GET /policy operation.
+ */
+struct ANASTASIS_PolicyLookupOperation;
+
+
+/**
+ * Callback to process a GET /policy request
+ *
+ * @param cls closure
+ * @param http_status HTTP status code for this request
+ * @param ec anastasis-specific error code
+ * @param obj the response body
+ */
+typedef void
+(*ANASTASIS_PolicyLookupCallback) (void *cls,
+                                   unsigned int http_status,
+                                   enum ANASTASIS_ErrorCode ec,
+                                   const json_t *obj);
+
+/**
+ * Does a GET /policy.
+ *
+ * @param ctx execution context
+ * @param backend_url base URL of the merchant backend
+ * @param anastasis_pub public key of the user's account
+ * @param cb callback which will work the response gotten from the backend
+ * @param cb_cls closure to pass to the callback
+ * @return handle for this operation, NULL upon errors
+ */
+struct ANASTASIS_PolicyLookupOperation *
+ANASTASIS_policy_lookup (struct GNUNET_CURL_Context *ctx,
+                         const char *backend_url,
+                         const struct ANASTASIS_AccountPubP *anastasis_pub,
+                         ANASTASIS_PolicyLookupCallback cb,
+                         void *cb_cls);
+
+/**
+ * Cancel a GET /policy request.
+ *
+ * @param rlo cancel the policy lookup operation
+ */
+void
+ANASTASIS_policy_lookup_cancel (struct
+                                ANASTASIS_PolicyLookupOperation *plo);
+
+
+/**
+ * Handle for a POST /policy operation.
+ */
+struct ANASTASIS_PolicyStoreOperation;
+
+
+/**
+ * Callback to process a POST /policy request
+ *
+ * @param cls closure
+ * @param http_status HTTP status code for this request
+ * @param ec anastasis-specific error code
+ * @param obj the response body
+ */
+typedef void
+(*ANASTASIS_PolicyStoreCallback) (void *cls,
+                                  unsigned int http_status,
+                                  enum ANASTASIS_ErrorCode ec,
+                                  const json_t *obj);
 
 
 #endif  /* _ANASTASIS_MERCHANT_SERVICE_H */
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 477a0a5..1774696 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -14,7 +14,8 @@ libanastasis_la_LDFLAGS = \
   -no-undefined
 
 libanastasis_la_SOURCES = \
-  anastasis_api_salt.c
+  anastasis_api_salt.c \
+  anastasis_api_policy.c
 
 libanastasis_la_LIBADD = \
   -lmicrohttpd \
@@ -22,6 +23,7 @@ libanastasis_la_LIBADD = \
   -lgnunetjson \
   -lgnunetutil \
   -ljansson \
+  -ltalerutil
   $(XLIB)
 
 if HAVE_LIBCURL
diff --git a/src/lib/anastasis_api_policy.c b/src/lib/anastasis_api_policy.c
new file mode 100644
index 0000000..9572aa9
--- /dev/null
+++ b/src/lib/anastasis_api_policy.c
@@ -0,0 +1,300 @@
+/*
+  This file is part of ANASTASIS
+  Copyright (C) 2014-2017 GNUnet e.V. and INRIA
+
+  ANASTASIS is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1,
+  or (at your option) any later version.
+
+  ANASTASIS is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with ANASTASIS; see the file COPYING.LGPL.  If not,
+  see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file lib/anastasis_api_policy.c
+ * @brief Implementation of the /policy GET and POST
+ * @author Christian Grothoff
+ * @author Dennis Neufeld
+ * @author Dominik Meister
+ */
+#include "platform.h"
+#include <curl/curl.h>
+#include <jansson.h>
+#include <microhttpd.h> /* just for HTTP status codes */
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_curl_lib.h>
+#include <taler/taler_json_lib.h>
+#include <taler/taler_util.h>
+#include "anastasis_service.h"
+
+
+/**
+ * @brief A Contract Operation Handle
+ */
+struct ANASTASIS_PolicyLookupOperation
+{
+
+  /**
+   * The url for this request, including parameters.
+   */
+  char *url;
+
+  /**
+   * Handle for the request.
+   */
+  struct GNUNET_CURL_Job *job;
+
+  /**
+   * Function to call with the result.
+   */
+  ANASTASIS_PolicyLookupCallback cb;
+
+  /**
+   * Closure for @a cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Reference to the execution context.
+   */
+  struct GNUNET_CURL_Context *ctx;
+};
+
+
+/**
+ * Cancel a pending /policy GET request
+ *
+ * @param handle from the operation to cancel
+ */
+void
+ANASTASIS_policy_lookup_cancel (struct 
+                                ANASTASIS_PolicyLookupOperation *plo)
+{
+  if (NULL != plo->job)
+  {
+    GNUNET_CURL_job_cancel (plo->job);
+    plo->job = NULL;
+  }
+  GNUNET_free (plo->url);
+  GNUNET_free (plo);
+}
+
+
+/**
+ * Process GET /policy response
+ */
+static void
+handle_policy_lookup_finished (void *cls,
+                               long response_code,
+                               const void *response)
+{
+  struct ANASTASIS_PolicyLookupOperation *plo = cls;
+  char *error;
+  enum ANASTASIS_ErrorCode code;
+  const json_t *json = response;
+
+  plo->job = NULL;
+  switch (response_code)
+  {
+  case 0:
+    /* Hard error */
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Backend didn't even return from GET /policy\n");
+    return;
+
+  case MHD_HTTP_OK:
+  case MHD_HTTP_NOT_FOUND:
+    plo->cb (plo->cb_cls,
+             response_code,
+             ANASTASIS_EC_NONE,
+             json);
+    break;
+  default:
+    /**
+     * The backend gave response, but it's error, log it.
+     * NOTE that json must be a ANASTASIS-specific error object (FIXME,
+     * need a link to error objects at docs)
+     */
+    if (-1 == json_unpack ((json_t *) json,
+                           "{s:s, s:I, s:s}",
+                           "error", &error,
+                           "code", &code))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Failed GET /policy, error: %s, code: %d\n",
+                  error,
+                  code);
+      break;
+    }
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed /policy lookup, backend did not give"
+                " a valid error object, HTTP code was %lu\n",
+                response_code);
+  }
+
+  ANASTASIS_policy_lookup_cancel (plo);
+}
+
+
+/**
+ * Make an absolute URL with query parameters.
+ *
+ * @param base_url absolute base URL to use
+ * @param path path of the url
+ * @param account_pub anastasis account pub (eddsa)
+ * @param ... NULL-terminated key-value pairs (char *) for query parameters,
+ *        the value will be url-encoded
+ * @returns the URL (must be freed with #GNUNET_free) or
+ *          NULL if an error occured.
+ */
+char *
+ANASTASIS_url_join (const char *base_url,
+                const char *path,
+                const struct ANASTASIS_AccountPubP *anastasis_pub,
+                ...)
+{
+  unsigned int iparam = 0;
+  va_list args;
+  struct TALER_Buffer buf = { 0 };
+  size_t len = 0;
+
+  GNUNET_assert (NULL != base_url);
+  GNUNET_assert (NULL != path);
+  GNUNET_assert (NULL != anastasis_pub);
+
+  if (strlen (base_url) == 0)
+  {
+    /* base URL can't be empty */
+    GNUNET_break (0);
+    return NULL;
+  }
+
+  if ('/' != base_url[strlen (base_url) - 1])
+  {
+    /* Must be an actual base URL! */
+    GNUNET_break (0);
+    return NULL;
+  }
+
+  if ('/' == path[0])
+  {
+    /* The path must be relative. */
+    GNUNET_break (0);
+    return NULL;
+  }
+
+  // Path should be relative to existing path of base URL
+  GNUNET_break ('/' != path[0]);
+
+  if ('/' == path[0])
+    GNUNET_break (0);
+
+  // Convert account pub to base32 encoded string
+  const char *acc_pub_str = GNUNET_CRYPTO_eddsa_public_key_to_string 
(&anastasis_pub->pub);
+
+  /* 1st pass: compute length */
+  len += strlen (base_url) + strlen (path) + strlen (acc_pub_str);
+
+  va_start (args, anastasis_pub);
+  while (1)
+  {
+    char *key;
+    char *value;
+    key = va_arg (args, char *);
+    if (NULL == key)
+      break;
+    value = va_arg (args, char *);
+    if (NULL == value)
+      continue;
+    len += urlencode_len (value) + strlen (key) + 2;
+  }
+  va_end (args);
+
+  TALER_buffer_prealloc (&buf, len);
+
+  TALER_buffer_write_str (&buf, base_url);
+  TALER_buffer_write_str (&buf, path);
+  TALER_buffer_write_str (&buf, acc_pub_str);
+
+  va_start (args, anastasis_pub);
+  while (1)
+  {
+    char *key;
+    char *value;
+    key = va_arg (args, char *);
+    if (NULL == key)
+      break;
+    value = va_arg (args, char *);
+    if (NULL == value)
+      continue;
+    TALER_buffer_write_str (&buf, (0 == iparam) ? "?" : "&");
+    iparam++;
+    TALER_buffer_write_str (&buf, key);
+    TALER_buffer_write_str (&buf, "=");
+    buffer_write_urlencode (&buf, value);
+  }
+  va_end (args);
+
+  return TALER_buffer_reap_str (&buf);
+}
+
+
+/**
+ * Does a GET /policy.
+ *
+ * @param ctx execution context
+ * @param backend_url base URL of the merchant backend
+ * @param anastasis_pub public key of the user's account
+ * @param cb callback which will work the response gotten from the backend
+ * @param cb_cls closure to pass to the callback
+ * @return handle for this operation, NULL upon errors
+ */
+struct ANASTASIS_PolicyLookupOperation *
+ANASTASIS_policy_lookup (struct GNUNET_CURL_Context *ctx,
+                         const char *backend_url,
+                         const struct ANASTASIS_AccountPubP *anastasis_pub,
+                         ANASTASIS_PolicyLookupCallback cb,
+                         void *cb_cls)
+{
+  struct ANASTASIS_PolicyLookupOperation *plo;
+  CURL *eh;
+
+  plo = GNUNET_new (struct ANASTASIS_PolicyLookupOperation);
+  plo->ctx = ctx;
+  plo->cb = cb;
+  plo->cb_cls = cb_cls;
+
+  //plo->url = TALER_url_join (backend_url, "policy", "order_id", order_id, 
NULL);
+  plo->url = TALER_url_join (backend_url,
+                             "policy",
+                             anastasis_pub);
+  
+  eh = curl_easy_init ();
+  if (CURLE_OK != curl_easy_setopt (eh,
+                                    CURLOPT_URL,
+                                    plo->url))
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+
+  if (NULL == (plo->job = GNUNET_CURL_job_add (ctx,
+                                               eh,
+                                               GNUNET_NO,
+                                               handle_policy_lookup_finished,
+                                               plo)))
+  {
+    GNUNET_break (0);
+    return NULL;
+
+  }
+
+  return plo;
+}

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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