[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.