[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-anastasis] branch master updated: worked on api
From: |
gnunet |
Subject: |
[taler-anastasis] branch master updated: worked on api |
Date: |
Tue, 26 Nov 2019 15:00:59 +0100 |
This is an automated email from the git hooks/post-receive script.
dennis-neufeld pushed a commit to branch master
in repository anastasis.
The following commit(s) were added to refs/heads/master by this push:
new c72f9c2 worked on api
c72f9c2 is described below
commit c72f9c236e3c5ba9a92e263101aad1184b7d1339
Author: Dennis Neufeld <address@hidden>
AuthorDate: Tue Nov 26 14:00:49 2019 +0000
worked on api
---
src/include/anastasis_error_codes.h | 8 +-
src/include/anastasis_service.h | 173 ++++++++++++-
src/include/anastasis_testing_lib.h | 8 +-
src/lib/Makefile.am | 6 +-
src/lib/anastasis_api_policy_lookup.c | 267 ++++++++++++++++++++
src/lib/anastasis_api_policy_store.c | 424 ++++++++++++++++++++++++++++++++
src/lib/test_anastasis_api.c | 64 ++++-
src/lib/testing_api_cmd_policy_lookup.c | 63 +++++
src/lib/testing_api_cmd_policy_store.c | 247 +++++++++++++++++++
src/util/Makefile.am | 4 +-
10 files changed, 1234 insertions(+), 30 deletions(-)
diff --git a/src/include/anastasis_error_codes.h
b/src/include/anastasis_error_codes.h
index 0ad7f6c..114397e 100644
--- a/src/include/anastasis_error_codes.h
+++ b/src/include/anastasis_error_codes.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet
- Copyright (C) 2017 GNUnet e.V.
+ Copyright (C) 2019 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -44,6 +44,12 @@ enum ANASTASIS_ErrorCode
*/
ANASTASIS_EC_NONE = 6000,
+ /**
+ * Special code to indicate that a non-integer error code was
+ * returned in the JSON response.
+ */
+ ANASTASIS_EC_INVALID = 6001,
+
/**
* The specified User was unknown
*/
diff --git a/src/include/anastasis_service.h b/src/include/anastasis_service.h
index bdb5063..89e9664 100644
--- a/src/include/anastasis_service.h
+++ b/src/include/anastasis_service.h
@@ -17,17 +17,18 @@
* @file include/anastasis_service.h
* @brief C interface of libanastasisrest, a C library to use merchant's HTTP
API
* @author Christian Grothoff
- * @author Marcello Stanisci
* @author Dennis Neufeld
* @author Dominik Meister
*/
#ifndef _ANASTASIS_SERVICE_H
#define _ANASTASIS_SERVICE_H
+#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_curl_lib.h>
#include <jansson.h>
#include "anastasis_error_codes.h"
+GNUNET_NETWORK_STRUCT_BEGIN
/**
* An EdDSA public key that is used to identify a user's account.
@@ -37,6 +38,16 @@ struct ANASTASIS_AccountPubP
struct GNUNET_CRYPTO_EddsaPublicKey pub;
};
+
+/**
+ * An EdDSA private key that is used to sign upload data.
+ */
+struct ANASTASIS_AccountPrivP
+{
+ struct GNUNET_CRYPTO_EddsaPrivateKey priv;
+};
+
+
/**
* Random identifier used to later charge a payment.
*/
@@ -47,6 +58,43 @@ struct ANASTASIS_PaymentSecretP
struct ANASTASIS_SaltOperation;
+
+/**
+ * Data signed by the account public key of a sync client to
+ * authorize the upload of the backup.
+ */
+struct ANASTASIS_UploadSignaturePS
+{
+ /**
+ * Set to #TALER_SIGNATURE_ANASTASIS_BACKUP_UPLOAD.
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * Hash of the previous backup, all zeros for none.
+ */
+ struct GNUNET_HashCode old_recovery_data_hash GNUNET_PACKED;
+
+ /**
+ * Hash of the new backup.
+ */
+ struct GNUNET_HashCode new_recovery_data_hash GNUNET_PACKED;
+
+};
+
+
+/**
+ * Signature made with an account's public key.
+ */
+struct ANASTASIS_AccountSignatureP
+{
+ /**
+ * We use EdDSA.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature eddsa_sig;
+};
+
+
/**
* Salt value of an Anastasis service provider.
*/
@@ -58,6 +106,106 @@ struct ANASTASIS_Salt
uint32_t value[8];
};
+GNUNET_NETWORK_STRUCT_END
+
+
+
+/**
+ * High-level ways how an upload may conclude.
+ */
+enum ANASTASIS_UploadStatus
+{
+ /**
+ * Backup was successfully made.
+ */
+ ANASTASIS_US_SUCCESS = 0,
+
+ /**
+ * Account expired or payment was explicitly requested
+ * by the client.
+ */
+ ANASTASIS_US_PAYMENT_REQUIRED = 1,
+
+ /**
+ * Conflicting backup existed on server. Client should
+ * reconcile and try again with (using the provided
+ * recovered backup as the previous backup).
+ */
+ ANASTASIS_US_CONFLICTING_BACKUP = 2,
+
+ /**
+ * HTTP interaction failed, see HTTP status.
+ */
+ ANASTASIS_US_HTTP_ERROR = 3,
+
+ /**
+ * We had an internal error (not sure this can happen,
+ * but reserved for HTTP 400 status codes).
+ */
+ ANASTASIS_US_CLIENT_ERROR = 4,
+
+ /**
+ * Server had an internal error.
+ */
+ ANASTASIS_US_SERVER_ERROR = 5
+};
+
+
+/**
+ * Result of an upload.
+ */
+struct ANASTASIS_UploadDetails
+{
+ /**
+ * High level status of the upload operation.
+ */
+ enum ANASTASIS_UploadStatus us;
+
+ union
+ {
+
+ /**
+ * Hash of the stored recovery data, returned if
+ * @e us is #ANASTASIS_US_SUCCESS.
+ */
+ const struct GNUNET_HashCode *curr_backup_hash;
+
+ /**
+ * Previous backup. Returned if @e us is
+ * #ANASTASIS_US_CONFLICTING_BACKUP
+ */
+ struct
+ {
+ /**
+ * Hash over @e existing_backup.
+ */
+ struct GNUNET_HashCode existing_backup_hash;
+
+ /**
+ * Number of bytes in @e existing_backup.
+ */
+ size_t existing_backup_size;
+
+ /**
+ * The backup on the server, which does not match the
+ * "previous" backup expected by the client and thus
+ * needs to be decrypted, reconciled and re-uploaded.
+ */
+ const void *existing_backup;
+
+ } recovered_backup;
+
+ /**
+ * A taler://pay/-URI with a request to pay the annual fee for
+ * the service. Returned if @e us is #ANASTASIS_US_PAYMENT_REQUIRED.
+ */
+ const char *payment_request;
+
+ } details;
+
+};
+
+
typedef void
(ANASTASIS_SaltCallback)(void *cls,
@@ -158,28 +306,37 @@ struct ANASTASIS_PolicyStoreOperation;
*/
typedef void
(*ANASTASIS_PolicyStoreCallback) (void *cls,
- unsigned int http_status,
enum ANASTASIS_ErrorCode ec,
- const json_t *obj);
+ unsigned int http_status,
+ const struct ANASTASIS_UploadDetails *up);
/**
- * Store policies
+ * Store policies, does a POST /policy/$AccountPub
*
* @param ctx the CURL context used to connect to the backend
* @param backend_url backend's base URL, including final "/"
* @param anastasis_pub public key of the user's account
- * @param refund amount to which increase the refund
+ * @param anastasis_priv private key of the user's account
+ * @param prev_recovery_data_hash hash of the privious policy update, NULL for
the first upload ever
+ * @param recovery_data policy data to be stored
+ * @param recovery_data_size number of bytes in @a recovery_data
+ * @param payment_requested #GNUNET_YES if the client wants to pay more for
the account now
+ * @param paymentSecretP payment identifier of last payment
* @param cb callback processing the response from /policy
* @param cb_cls closure for cb
+ * @return handle for the operation
*/
struct ANASTASIS_PolicyStoreOperation *
ANASTASIS_policy_store (struct GNUNET_CURL_Context *ctx,
const char *backend_url,
const struct
- ANASTASIS_AccountPubP *anastasis_pub,
- const void *policy_data,
- size_t policy_data_size,
+ ANASTASIS_AccountPrivP *anastasis_priv,
+ const struct
+ GNUNET_HashCode *prev_recovery_data_hash,
+ const void *recovery_data,
+ size_t recovery_data_size,
+ int payment_requested,
const struct
ANASTASIS_PaymentSecretP *paymentSecretP,
ANASTASIS_PolicyStoreCallback cb,
diff --git a/src/include/anastasis_testing_lib.h
b/src/include/anastasis_testing_lib.h
index a6657b7..655b6cf 100644
--- a/src/include/anastasis_testing_lib.h
+++ b/src/include/anastasis_testing_lib.h
@@ -101,10 +101,11 @@ TALER_TESTING_prepare_anastasis (const char
*config_filename);
* @param anastasis_url base URL of the anastasis serving
* the policy store request.
* @param http_status expected HTTP status.
+ * @param priv private account identifier
* @param pub account identifier
* @param payment_id payment identifier
* @param policy_data recovery data to post
- *
+ * @param policy_data_size size of recovery/policy data
* @return the command
*/
struct TALER_TESTING_Command
@@ -112,10 +113,11 @@ ANASTASIS_TESTING_cmd_policy_store (const char *label,
const char *anastasis_url,
unsigned int http_status,
const struct
- ANASTASIS_AccountPubP *pub,
+ ANASTASIS_AccountPrivP *priv,
const struct
ANASTASIS_PaymentSecretP *payment_id,
- const void *policy_data);
+ const void *policy_data,
+ size_t policy_data_size);
/**
* Make a "policy lookup" command.
*
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 1f41ddf..9f3f37a 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -20,7 +20,8 @@ libanastasistesting_la_LDFLAGS = \
libanastasis_la_SOURCES = \
anastasis_api_salt.c \
- anastasis_api_policy.c
+ anastasis_api_policy_store.c \
+ anastasis_api_policy_lookup.c
libanastasis_la_LIBADD = \
-lmicrohttpd \
@@ -32,7 +33,8 @@ libanastasis_la_LIBADD = \
$(XLIB)
libanastasistesting_la_SOURCES = \
- testing_api_cmd_policy.c \
+ testing_api_cmd_policy_store.c \
+ testing_api_cmd_policy_lookup.c \
testing_api_helpers.c
libanastasistesting_la_LIBADD = \
diff --git a/src/lib/anastasis_api_policy_lookup.c
b/src/lib/anastasis_api_policy_lookup.c
new file mode 100644
index 0000000..449f5b3
--- /dev/null
+++ b/src/lib/anastasis_api_policy_lookup.c
@@ -0,0 +1,267 @@
+/*
+ This file is part of ANASTASIS
+ Copyright (C) 2014-2019 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_lookup.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_curl_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);
+}
+
+
+/**
+ * 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;
+ char *acc_pub_str;
+ char *path;
+
+ plo = GNUNET_new (struct ANASTASIS_PolicyLookupOperation);
+ plo->ctx = ctx;
+ plo->cb = cb;
+ plo->cb_cls = cb_cls;
+ acc_pub_str = GNUNET_CRYPTO_eddsa_public_key_to_string (&anastasis_pub->pub);
+ GNUNET_asprintf (&path,
+ "policy/%s",
+ acc_pub_str);
+ GNUNET_free (acc_pub_str);
+ plo->url = TALER_url_join (backend_url,
+ path,
+ NULL);
+ GNUNET_free (path);
+ 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;
+}
+
+
+/**
+ * Does a GET /policy for a specific version.
+ *
+ * @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
+ * @param version version of the policy to be requested
+ * @return handle for this operation, NULL upon errors
+ */
+struct ANASTASIS_PolicyLookupOperation *
+ANASTASIS_policy_lookup_version (struct GNUNET_CURL_Context *ctx,
+ const char *backend_url,
+ const struct
+ ANASTASIS_AccountPubP *anastasis_pub,
+ ANASTASIS_PolicyLookupCallback cb,
+ void *cb_cls,
+ uint32_t *version)
+{
+ struct ANASTASIS_PolicyLookupOperation *plo;
+ CURL *eh;
+ char *acc_pub_str;
+ char *path;
+
+ plo = GNUNET_new (struct ANASTASIS_PolicyLookupOperation);
+ plo->ctx = ctx;
+ plo->cb = cb;
+ plo->cb_cls = cb_cls;
+ acc_pub_str = GNUNET_CRYPTO_eddsa_public_key_to_string (&anastasis_pub->pub);
+ GNUNET_asprintf (&path,
+ "policy/%s",
+ acc_pub_str);
+ GNUNET_free (acc_pub_str);
+ plo->url = TALER_url_join (backend_url,
+ path,
+ "version",
+ version,
+ NULL);
+ GNUNET_free (path);
+ 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;
+}
diff --git a/src/lib/anastasis_api_policy_store.c
b/src/lib/anastasis_api_policy_store.c
new file mode 100644
index 0000000..4e5130d
--- /dev/null
+++ b/src/lib/anastasis_api_policy_store.c
@@ -0,0 +1,424 @@
+/*
+ This file is part of ANASTASIS
+ Copyright (C) 2014-2019 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_store.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_signatures.h>
+#include <taler/taler_json_lib.h>
+#include <taler/taler_curl_lib.h>
+#include <taler/taler_util.h>
+#include "anastasis_service.h"
+
+
+struct ANASTASIS_PolicyStoreOperation
+{
+ /**
+ * Complete URL where the backend offers /policy
+ */
+ char *url;
+
+ /**
+ * Handle for the request.
+ */
+ struct GNUNET_CURL_Job *job;
+
+ /**
+ * The CURL context to connect to the backend
+ */
+ struct GNUNET_CURL_Context *ctx;
+
+ /**
+ * The callback to pass the backend response to
+ */
+ ANASTASIS_PolicyStoreCallback cb;
+
+ /**
+ * Closure for @e cb.
+ */
+ void *cb_cls;
+
+ /**
+ * Payment URI we received from the service, or NULL.
+ */
+ char *pay_uri;
+
+ /**
+ * Hash of the data we are uploading.
+ */
+ struct GNUNET_HashCode new_recovery_data_hash;
+};
+
+
+/**
+ * Callback to process POST /policy response
+ *
+ * @param cls the `struct ANASTASIS_PolicyStoreOperation`
+ * @param response_code HTTP response code, 0 on error
+ * @param data
+ * @param data_size
+ */
+static void
+handle_policy_store_finished (void *cls,
+ long response_code,
+ const void *data,
+ size_t data_size)
+{
+ struct ANASTASIS_PolicyStoreOperation *pso = cls;
+ enum TALER_ErrorCode ec = TALER_EC_INVALID;
+ struct ANASTASIS_UploadDetails ud;
+ struct ANASTASIS_UploadDetails *udp;
+
+ pso->job = NULL;
+ udp = NULL;
+ memset (&ud, 0, sizeof (ud));
+ switch (response_code)
+ {
+ case 0:
+ break;
+ case MHD_HTTP_NO_CONTENT:
+ ud.us = ANASTASIS_US_SUCCESS;
+ ud.details.curr_backup_hash = &pso->new_recovery_data_hash;
+ udp = &ud;
+ ec = TALER_EC_NONE;
+ break;
+ case MHD_HTTP_NOT_MODIFIED:
+ ud.us = ANASTASIS_US_SUCCESS;
+ ud.details.curr_backup_hash = &pso->new_recovery_data_hash;
+ udp = &ud;
+ ec = TALER_EC_NONE;
+ break;
+ case MHD_HTTP_BAD_REQUEST:
+ GNUNET_break (0);
+ ec = TALER_JSON_get_error_code2 (data,
+ data_size);
+ break;
+ case MHD_HTTP_PAYMENT_REQUIRED:
+ ud.us = ANASTASIS_US_PAYMENT_REQUIRED;
+ ud.details.payment_request = pso->pay_uri;
+ udp = &ud;
+ ec = TALER_EC_NONE;
+ break;
+ case MHD_HTTP_FORBIDDEN:
+ GNUNET_break (0);
+ ec = TALER_JSON_get_error_code2 (data,
+ data_size);
+ break;
+ case MHD_HTTP_CONFLICT:
+ ud.us = ANASTASIS_US_CONFLICTING_BACKUP;
+ GNUNET_CRYPTO_hash (data,
+ data_size,
+ &ud.details.recovered_backup.existing_backup_hash);
+ ud.details.recovered_backup.existing_backup_size
+ = data_size;
+ ud.details.recovered_backup.existing_backup
+ = data;
+ udp = &ud;
+ ec = TALER_EC_NONE;
+ break;
+ case MHD_HTTP_GONE:
+ ec = TALER_JSON_get_error_code2 (data,
+ data_size);
+ break;
+ case MHD_HTTP_LENGTH_REQUIRED:
+ GNUNET_break (0);
+ break;
+ case MHD_HTTP_REQUEST_ENTITY_TOO_LARGE:
+ ec = TALER_JSON_get_error_code2 (data,
+ data_size);
+ break;
+ case MHD_HTTP_TOO_MANY_REQUESTS:
+ ec = TALER_JSON_get_error_code2 (data,
+ data_size);
+ break;
+ }
+ if (NULL != pso->cb)
+ {
+ pso->cb (pso->cb_cls,
+ ec,
+ response_code,
+ udp);
+ pso->cb = NULL;
+ }
+ ANASTASIS_policy_store_cancel (pso);
+}
+
+
+/**
+ * Cancel a POST /policy request.
+ *
+ * @param pso the policy store operation to cancel
+ */
+void
+ANASTASIS_policy_store_cancel (struct
+ ANASTASIS_PolicyStoreOperation *pso)
+{
+ if (NULL != pso->job)
+ {
+ GNUNET_CURL_job_cancel (pso->job);
+ pso->job = NULL;
+ }
+ GNUNET_free (pso->pay_uri);
+ GNUNET_free (pso->url);
+ GNUNET_free (pso);
+}
+
+
+/**
+ * Handle HTTP header received by curl.
+ *
+ * @param buffer one line of HTTP header data
+ * @param size size of an item
+ * @param nitems number of items passed
+ * @param userdata our `struct ANASTASIS_StorePolicyOperation *`
+ * @return `size * nitems`
+ */
+static size_t
+handle_header (char *buffer,
+ size_t size,
+ size_t nitems,
+ void *userdata)
+{
+ struct ANASTASIS_PolicyStoreOperation *pso = userdata;
+ size_t total = size * nitems;
+ char *ndup;
+ const char *hdr_type;
+ char *hdr_val;
+
+ ndup = GNUNET_strndup (buffer,
+ total);
+ hdr_type = strtok (ndup,
+ ":");
+ if (NULL == hdr_type)
+ {
+ GNUNET_free (ndup);
+ return total;
+ }
+ hdr_val = strtok (NULL,
+ "");
+ if (NULL == hdr_val)
+ {
+ GNUNET_free (ndup);
+ return total;
+ }
+ if (' ' == *hdr_val)
+ hdr_val++;
+ if (0 == strcasecmp (hdr_type,
+ "Taler"))
+ {
+ /* found payment URI we care about! */
+ pso->pay_uri = GNUNET_strdup (hdr_val);
+ }
+ GNUNET_free (ndup);
+ return total;
+}
+
+
+
+/**
+ * Store policies, does a POST /policy/$AccountPub
+ *
+ * @param ctx the CURL context used to connect to the backend
+ * @param backend_url backend's base URL, including final "/"
+ * @param anastasis_pub public key of the user's account
+ * @param anastasis_priv private key of the user's account
+ * @param prev_recovery_data_hash hash of the privious policy update, NULL for
the first upload ever
+ * @param recovery_data policy data to be stored
+ * @param recovery_data_size number of bytes in @a recovery_data
+ * @param payment_requested #GNUNET_YES if the client wants to pay more for
the account now
+ * @param paymentSecretP payment identifier of last payment
+ * @param cb callback processing the response from /policy
+ * @param cb_cls closure for cb
+ * @return handle for the operation
+ */
+struct ANASTASIS_PolicyStoreOperation *
+ANASTASIS_policy_store (struct GNUNET_CURL_Context *ctx,
+ const char *backend_url,
+ const struct
+ ANASTASIS_AccountPrivP *anastasis_priv,
+ const struct
+ GNUNET_HashCode *prev_recovery_data_hash,
+ const void *recovery_data,
+ size_t recovery_data_size,
+ int payment_requested,
+ const struct
+ ANASTASIS_PaymentSecretP *paymentSecretP,
+ ANASTASIS_PolicyStoreCallback cb,
+ void *cb_cls)
+{
+ struct ANASTASIS_PolicyStoreOperation *pso;
+ struct ANASTASIS_AccountSignatureP account_sig;
+ struct ANASTASIS_UploadSignaturePS usp;
+ CURL *eh;
+ struct curl_slist *job_headers;
+
+ memset (&usp, 0, sizeof (usp));
+ usp.purpose.purpose = htonl (TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD);
+ usp.purpose.size = htonl (sizeof (usp));
+ if (NULL != prev_recovery_data_hash)
+ usp.old_recovery_data_hash = *prev_recovery_data_hash;
+ GNUNET_CRYPTO_hash (recovery_data,
+ recovery_data_size,
+ &usp.new_recovery_data_hash);
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_sign (&anastasis_priv->priv,
+ &usp.purpose,
+ &account_sig.eddsa_sig))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+
+ /* setup our HTTP headers */
+ job_headers = NULL;
+ {
+ struct curl_slist *ext;
+ char *val;
+ char *hdr;
+
+ /* Set Sync-Signature header */
+ val = GNUNET_STRINGS_data_to_string_alloc (&account_sig,
+ sizeof (account_sig));
+ GNUNET_asprintf (&hdr,
+ "Anastasis-Policy-Signature: %s",
+ val);
+ GNUNET_free (val);
+ ext = curl_slist_append (job_headers,
+ hdr);
+ GNUNET_free (hdr);
+ if (NULL == ext)
+ {
+ GNUNET_break (0);
+ curl_slist_free_all (job_headers);
+ return NULL;
+ }
+ job_headers = ext;
+
+ /* set Etag header */
+ val = GNUNET_STRINGS_data_to_string_alloc (&usp.new_recovery_data_hash,
+ sizeof (struct
GNUNET_HashCode));
+ GNUNET_asprintf (&hdr,
+ "Etag: %s",
+ val);
+ GNUNET_free (val);
+ ext = curl_slist_append (job_headers,
+ hdr);
+ GNUNET_free (hdr);
+ if (NULL == ext)
+ {
+ GNUNET_break (0);
+ curl_slist_free_all (job_headers);
+ return NULL;
+ }
+ job_headers = ext;
+
+ /* Setup If-Match header */
+ if (NULL != prev_recovery_data_hash)
+ {
+ val = GNUNET_STRINGS_data_to_string_alloc (&usp.old_recovery_data_hash,
+ sizeof (struct
+ GNUNET_HashCode));
+ GNUNET_asprintf (&hdr,
+ "If-Match: %s",
+ val);
+ GNUNET_free (val);
+ ext = curl_slist_append (job_headers,
+ hdr);
+ GNUNET_free (hdr);
+ if (NULL == ext)
+ {
+ GNUNET_break (0);
+ curl_slist_free_all (job_headers);
+ return NULL;
+ }
+ job_headers = ext;
+ }
+ }
+ /* Finished setting up headers */
+
+ pso = GNUNET_new (struct ANASTASIS_PolicyStoreOperation);
+ pso->new_recovery_data_hash = usp.new_recovery_data_hash;
+ {
+ char *acc_pub_str;
+ char *path;
+ struct ANASTASIS_AccountPubP pub;
+
+ GNUNET_CRYPTO_eddsa_key_get_public (&anastasis_priv->priv,
+ &pub.pub);
+
+ acc_pub_str = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub.pub);
+ GNUNET_asprintf (&path,
+ "policy/%s",
+ acc_pub_str);
+ GNUNET_free (acc_pub_str);
+ pso->url = TALER_url_join (backend_url,
+ "policy",
+ pub);
+ GNUNET_free (path);
+ }
+ pso->ctx = ctx;
+ pso->cb = cb;
+ pso->cb_cls = cb_cls;
+ eh = curl_easy_init ();
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_URL,
+ pso->url));
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_FOLLOWLOCATION,
+ 1L));
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_TCP_FASTOPEN,
+ 1L));
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_POSTFIELDS,
+ recovery_data));
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_POSTFIELDSIZE,
+ (long) recovery_data_size));
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_HEADERFUNCTION,
+ &handle_header));
+ GNUNET_assert (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_HEADERDATA,
+ pso));
+ pso->job = GNUNET_CURL_job_add_raw (ctx,
+ eh,
+ job_headers,
+ &handle_policy_store_finished,
+ pso);
+ curl_slist_free_all (job_headers);
+ return pso;
+}
diff --git a/src/lib/test_anastasis_api.c b/src/lib/test_anastasis_api.c
index 82cefec..c1876fb 100644
--- a/src/lib/test_anastasis_api.c
+++ b/src/lib/test_anastasis_api.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2018 Taler Systems SA
+ Copyright (C) 2014-2019 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as
@@ -18,13 +18,12 @@
*/
/**
- * @file exchange/test_merchant_api_new.c
- * @brief testcase to test exchange's HTTP API interface
- * @author Sree Harsha Totakura <address@hidden>
+ * @file lib/test_anastasis_api.c
+ * @brief testcase to test anastasis' HTTP API interface
* @author Christian Grothoff
- * @author Marcello Stanisci
+ * @author Dennis Neufeld
+ * @author Dominik Meister
*/
-
#include "platform.h"
#include <taler/taler_util.h>
#include <taler/taler_signatures.h>
@@ -51,6 +50,26 @@
static const char *pickup_amounts_1[] = {"EUR:5", NULL};
+/**
+ * User private key, set to a random value
+ */
+static struct ANASTASIS_AccountPrivP accountPriv;
+
+/**
+ * User public key
+ */
+static struct ANASTASIS_AccountPubP accountPub;
+
+/**
+ * Payment Secret for the test, set to a random value
+ */
+static struct ANASTASIS_PaymentSecretP paymentSecret;
+
+/**
+ * Recoverydata which should be stored, set to a random value
+ */
+static void *recoveryData;
+
/**
* URL of the fakebank.
*/
@@ -221,6 +240,19 @@ static void
run (void *cls,
struct TALER_TESTING_Interpreter *is)
{
+
+ //fill data
+ const char *str = "AHV123456789";
+ GNUNET_CRYPTO_eddsa_private_key_from_string (str,
+ sizeof (str),
+ &accountPriv.priv);
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &recoveryData,
+ sizeof (recoveryData));
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &paymentSecret,
+ sizeof (paymentSecret));
+
struct TALER_TESTING_Command pay[] = {
/**
* Move money to the exchange's bank account.
@@ -245,7 +277,6 @@ run (void *cls,
"create-reserve-1",
"EUR:5",
MHD_HTTP_OK),
-
TALER_TESTING_cmd_withdraw_amount
("withdraw-coin-2",
"create-reserve-1",
@@ -265,6 +296,13 @@ run (void *cls,
struct TALER_TESTING_Command policy[] = {
// FIXME: Code for policy handling
+ ANASTASIS_TESTING_cmd_policy_store ("policy-store-1",
+ anastasis_url,
+ MHD_HTTP_OK,
+ &accountPriv,
+ &paymentSecret,
+ recoveryData,
+ sizeof (recoveryData)),
TALER_TESTING_cmd_end ()
};
@@ -284,12 +322,12 @@ run (void *cls,
policy),
TALER_TESTING_cmd_batch ("truth",
- truth),
+ truth),
/**
- * End the suite. Fixme: better to have a label for this
- * too, as it shows a "(null)" token on logs.
- */
+ * End the suite. Fixme: better to have a label for this
+ * too, as it shows a "(null)" token on logs.
+ */
TALER_TESTING_cmd_end ()
};
@@ -307,7 +345,7 @@ main (int argc,
unsetenv ("XDG_DATA_HOME");
unsetenv ("XDG_CONFIG_HOME");
- GNUNET_log_setup ("test-anastasis-api-new",
+ GNUNET_log_setup ("test-anastasis-api",
"DEBUG",
NULL);
if (NULL ==
@@ -368,4 +406,4 @@ main (int argc,
return 0;
}
-/* end of test_merchant_api_new.c */
+/* end of test_merchant_api.c */
diff --git a/src/lib/testing_api_cmd_policy_lookup.c
b/src/lib/testing_api_cmd_policy_lookup.c
new file mode 100644
index 0000000..8cb45a3
--- /dev/null
+++ b/src/lib/testing_api_cmd_policy_lookup.c
@@ -0,0 +1,63 @@
+/*
+ This file is part of ANASTASIS
+ Copyright (C) 2014-2019 Taler Systems SA
+
+ ANASTASIS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 3, 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with ANASTASIS; see the file COPYING. If not, see
+ <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file lib/testing_api_cmd_policy_lookup.c
+ * @brief command to execute the anastasis backend service.
+ * @author Dennis Neufeld
+ * @author Dominik Meister
+ */
+
+#include "platform.h"
+#include "anastasis_service.h"
+#include "anastasis_testing_lib.h"
+#include <taler/taler_util.h>
+#include <taler/taler_testing_lib.h>
+
+
+/**
+ * State for a "policy lookup" CMD.
+ */
+struct PolicyLookupState
+{
+ /**
+ * The interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+
+ /**
+ * Eddsa Publickey.
+ */
+ const struct ANASTASIS_AccountPubP anastasis_pub;
+
+ /**
+ * URL of the anastasis backend.
+ */
+ const char *anastasis_url;
+
+ /**
+ * Expected status code.
+ */
+ unsigned int http_status;
+
+ /**
+ * The /policy GET operation handle.
+ */
+ struct ANASTASIS_PolicyLookupOperation *plo;
+};
diff --git a/src/lib/testing_api_cmd_policy_store.c
b/src/lib/testing_api_cmd_policy_store.c
new file mode 100644
index 0000000..e04337f
--- /dev/null
+++ b/src/lib/testing_api_cmd_policy_store.c
@@ -0,0 +1,247 @@
+/*
+ This file is part of ANASTASIS
+ Copyright (C) 2014-2019 Taler Systems SA
+
+ ANASTASIS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 3, 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with ANASTASIS; see the file COPYING. If not, see
+ <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file lib/testing_api_cmd_policy_store.c
+ * @brief command to execute the anastasis backend service.
+ * @author Marcello Stanisci
+ */
+
+#include "platform.h"
+#include "anastasis_service.h"
+#include "anastasis_testing_lib.h"
+#include <taler/taler_util.h>
+#include <taler/taler_testing_lib.h>
+
+/**
+ * State for a "policy store" CMD.
+ */
+struct PolicyStoreState
+{
+
+ /**
+ * The policy data.
+ */
+ const void *recovery_data;
+
+ /**
+ * Number of bytes in @e recovery_data
+ */
+ size_t recovery_data_size;
+
+ /**
+ * Expected status code.
+ */
+ unsigned int http_status;
+
+ /**
+ * Eddsa Publickey.
+ */
+ const struct ANASTASIS_AccountPubP *anastasis_pub;
+
+ /**
+ * Eddsa Privatekey.
+ */
+ const struct ANASTASIS_AccountPrivP *anastasis_priv;
+
+ /**
+ * The /policy POST operation handle.
+ */
+ struct ANASTASIS_PolicyStoreOperation *pso;
+
+ /**
+ * The nonce.
+ */
+ struct GNUNET_CRYPTO_EddsaPublicKey nonce;
+
+ /**
+ * URL of the anastasis backend.
+ */
+ const char *anastasis_url;
+
+ /**
+ * The interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+
+ /**
+ * Payment identifier.
+ */
+ const struct ANASTASIS_PaymentSecretP *payment_id;
+};
+
+
+/**
+ * State for a "policy lookup" CMD.
+ */
+struct PolicyLookupState
+{
+ /**
+ * The interpreter state.
+ */
+ struct TALER_TESTING_Interpreter *is;
+
+ /**
+ * Eddsa Publickey.
+ */
+ const struct ANASTASIS_AccountPubP anastasis_pub;
+
+ /**
+ * URL of the anastasis backend.
+ */
+ const char *anastasis_url;
+
+ /**
+ * Expected status code.
+ */
+ unsigned int http_status;
+
+ /**
+ * The /policy GET operation handle.
+ */
+ struct ANASTASIS_PolicyLookupOperation *plo;
+};
+
+
+/**
+ * Function called with the results of a #policy_store().
+ *
+ * @param cls closure
+ * @param ec Taler error code
+ * @param http_status HTTP status of the request
+ * @param ud details about the upload operation
+ */
+static void
+policy_store_cb (void *cls,
+ enum ANASTASIS_ErrorCode ec,
+ unsigned int http_status,
+ const struct ANASTASIS_UploadDetails *ud)
+{
+ struct PolicyStoreState *pss = cls;
+
+ // FIXME: next!
+}
+
+
+/**
+ * Run a "policy store" CMD.
+ *
+ * @param cls closure.
+ * @param cmd command currently being run.
+ * @param is interpreter state.
+ */
+static void
+policy_store_run (void *cls,
+ const struct TALER_TESTING_Command *cmd,
+ struct TALER_TESTING_Interpreter *is)
+{
+ struct PolicyStoreState *pss = cls;
+
+ pss->is = is;
+
+ GNUNET_CRYPTO_random_block
+ (GNUNET_CRYPTO_QUALITY_WEAK,
+ &pss->nonce,
+ sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
+
+ pss->pso = ANASTASIS_policy_store (is->ctx,
+ pss->anastasis_url,
+ pss->anastasis_priv,
+ NULL /* pre_recovery_data_hash */,
+ pss->recovery_data,
+ pss->recovery_data_size,
+ GNUNET_NO /* payment req */,
+ pss->payment_id,
+ &policy_store_cb,
+ pss);
+ GNUNET_assert (NULL != pss->pso);
+}
+
+
+/**
+ * Free the state of a "policy sore" CMD, and possibly
+ * cancel it if it did not complete.
+ *
+ * @param cls closure.
+ * @param cmd command being freed.
+ */
+static void
+policy_store_cleanup (void *cls,
+ const struct TALER_TESTING_Command *cmd)
+{
+ struct PolicyStoreState *pss = cls;
+
+ if (NULL != pss->pso)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Command '%s' did not complete (policy post)\n",
+ cmd->label);
+ ANASTASIS_policy_store_cancel (pss->pso);
+ pss->pso = NULL;
+ }
+
+ // GNUNET_free_non_null ((void *) pss->order_id);
+ GNUNET_free (pss);
+}
+
+
+/**
+ * Make the "policy store" command.
+ *
+ * @param label command label
+ * @param anastasis_url base URL of the anastasis serving
+ * the policy store request.
+ * @param http_status expected HTTP status.
+ * @param priv private account identifier
+ * @param pub account identifier
+ * @param payment_id payment identifier
+ * @param recovery_data recovery data to post
+ * @param recovery_data_size size of recovery/policy data
+ * @return the command
+ */
+struct TALER_TESTING_Command
+ANASTASIS_TESTING_cmd_policy_store (const char *label,
+ const char *anastasis_url,
+ unsigned int http_status,
+ const struct
+ ANASTASIS_AccountPrivP *priv,
+ const struct
+ ANASTASIS_PaymentSecretP *payment_id,
+ const void *recovery_data,
+ size_t recovery_data_size)
+{
+ struct PolicyStoreState *pss;
+
+ pss = GNUNET_new (struct PolicyStoreState);
+ pss->anastasis_priv = priv;
+ pss->recovery_data = recovery_data;
+ pss->recovery_data_size = recovery_data_size;
+ pss->payment_id = payment_id;
+ pss->http_status = http_status;
+ pss->anastasis_url = anastasis_url;
+
+ struct TALER_TESTING_Command cmd = {
+ .cls = pss,
+ .label = label,
+ .run = &policy_store_run,
+ .cleanup = &policy_store_cleanup
+ };
+
+ return cmd;
+}
\ No newline at end of file
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 4736d81..677ad84 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -24,6 +24,4 @@ libanastasisutil_la_LIBADD = \
$(XLIB)
libanastasisutil_la_LDFLAGS = \
-version-info 0:0:0 \
- -export-dynamic -no-undefined
-
-
+ -export-dynamic -no-undefined
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
address@hidden.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-anastasis] branch master updated: worked on api,
gnunet <=