[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-anastasis] branch master updated: worked on api/testing
From: |
gnunet |
Subject: |
[taler-anastasis] branch master updated: worked on api/testing |
Date: |
Wed, 27 Nov 2019 21:00:23 +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 b654890 worked on api/testing
b654890 is described below
commit b6548900da185445247c2ef09fc00c0d82537e8d
Author: Dennis Neufeld <address@hidden>
AuthorDate: Tue Nov 26 16:04:21 2019 +0000
worked on api/testing
---
src/backend/Makefile.am | 3 +
src/backend/anastasis-httpd.c | 17 +
src/backend/anastasis-httpd.h | 5 +
src/backend/anastasis-httpd_policy.c | 686 ++++++++++++++++++++++++++++----
src/include/anastasis_database_lib.h | 10 +
src/include/anastasis_database_plugin.h | 11 +
src/include/anastasis_service.h | 2 +-
src/lib/anastasis_api_policy_store.c | 12 +-
src/lib/test_anastasis_api.c | 4 +-
src/lib/testing_api_cmd_policy_store.c | 2 +-
src/stasis/plugin_anastasis_postgres.c | 32 ++
src/stasis/test_anastasis_db.c | 4 +
12 files changed, 696 insertions(+), 92 deletions(-)
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 4198a5a..f0bdbb8 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -22,7 +22,10 @@ anastasis_httpd_LDADD = \
$(top_builddir)/src/stasis/libanastasisdb.la \
-lmicrohttpd \
-ljansson \
+ -ltalermerchant \
-ltalermhd \
+ -ltalerjson \
+ -ltalerutil \
-lgnunetcurl \
-lgnunetrest \
-lgnunetjson \
diff --git a/src/backend/anastasis-httpd.c b/src/backend/anastasis-httpd.c
index 15b5a09..3c900ad 100644
--- a/src/backend/anastasis-httpd.c
+++ b/src/backend/anastasis-httpd.c
@@ -33,6 +33,11 @@
*/
#define UNIX_BACKLOG 500
+/**
+ * Upload limit to the service, in megabytes.
+ */
+unsigned long long int SH_upload_limit_mb;
+
/**
* Should a "Connection: close" header be added to each HTTP response?
*/
@@ -456,6 +461,18 @@ run (void *cls,
GNUNET_log_setup ("anastasis-httpd",
"WARNING",
NULL));
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_number (config,
+ "anastasis",
+ "UPLOAD_LIMIT_MB",
+ &SH_upload_limit_mb))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "anastasis",
+ "UPLOAD_LIMIT_MB");
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
if (NULL ==
(db = ANASTASIS_DB_plugin_load (config)))
{
diff --git a/src/backend/anastasis-httpd.h b/src/backend/anastasis-httpd.h
index f8f2b18..06083ba 100644
--- a/src/backend/anastasis-httpd.h
+++ b/src/backend/anastasis-httpd.h
@@ -132,6 +132,11 @@ struct TM_HandlerContext
*/
extern struct ANASTASIS_DatabasePlugin *db;
+/**
+ * Upload limit to the service, in megabytes.
+ */
+extern unsigned long long SH_upload_limit_mb;
+
/**
* Kick MHD to run now, to be called after MHD_resume_connection().
* Basically, we need to explicitly resume MHD's event loop whenever
diff --git a/src/backend/anastasis-httpd_policy.c
b/src/backend/anastasis-httpd_policy.c
index de04f0b..d21b34f 100644
--- a/src/backend/anastasis-httpd_policy.c
+++ b/src/backend/anastasis-httpd_policy.c
@@ -22,8 +22,612 @@
*/
#include "platform.h"
#include "anastasis-httpd.h"
+#include "anastasis-httpd_policy.h"
+#include "anastasis_service.h"
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_rest_lib.h>
+#include <taler/taler_json_lib.h>
+#include <taler/taler_merchant_service.h>
+#include <taler/taler_signatures.h>
+
+/**
+ * How long do we hold an HTTP client connection if
+ * we are awaiting payment before giving up?
+ */
+#define CHECK_PAYMENT_TIMEOUT GNUNET_TIME_relative_multiply ( \
+ GNUNET_TIME_UNIT_MINUTES, 30)
+
+
+/**
+ * Context for an upload operation.
+ */
+struct PolicyUploadContext
+{
+
+ /**
+ * Context for cleanup logic.
+ */
+ struct TM_HandlerContext hc;
+
+ /**
+ * Signature of the account holder.
+ */
+ struct ANASTASIS_AccountSignatureP account_sig;
+
+ /**
+ * Public key of the account holder.
+ */
+ struct ANASTASIS_AccountPubP account;
+
+ /**
+ * Hash of the previous upload, or zeros if first upload.
+ */
+ struct GNUNET_HashCode old_policy_upload_hash;
+
+ /**
+ * Hash of the upload we are receiving right now (as promised
+ * by the client, to be verified!).
+ */
+ struct GNUNET_HashCode new_policy_upload_hash;
+
+ /**
+ * Hash context for the upload.
+ */
+ struct GNUNET_HashContext *hash_ctx;
+
+ /**
+ * Kept in DLL for shutdown handling while suspended.
+ */
+ struct PolicyUploadContext *next;
+
+ /**
+ * Kept in DLL for shutdown handling while suspended.
+ */
+ struct PolicyUploadContext *prev;
+
+ /**
+ * Used while suspended for resumption.
+ */
+ struct MHD_Connection *con;
+
+ /**
+ * Upload, with as many bytes as we have received so far.
+ */
+ char *upload;
+
+ /**
+ * Used while we are awaiting proposal creation.
+ */
+ struct TALER_MERCHANT_ProposalOperation *po;
+
+ /**
+ * Used while we are waiting payment.
+ */
+ struct TALER_MERCHANT_CheckPaymentOperation *cpo;
+
+ /**
+ * HTTP response code to use on resume, if non-NULL.
+ */
+ struct MHD_Response *resp;
+
+ /**
+ * Order under which the client promised payment, or NULL.
+ */
+ const char *order_id;
+
+ /**
+ * Order ID for the client that we found in our database.
+ */
+ char *existing_order_id;
+
+ /**
+ * Timestamp of the order in @e existing_order_id. Used to
+ * select the most recent unpaid offer.
+ */
+ struct GNUNET_TIME_Absolute existing_order_timestamp;
+
+ /**
+ * Expected total upload size.
+ */
+ size_t upload_size;
+
+ /**
+ * Current offset for the upload.
+ */
+ size_t upload_off;
+
+ /**
+ * HTTP response code to use on resume, if resp is set.
+ */
+ unsigned int response_code;
+
+};
+
+
+/**
+ * Kept in DLL for shutdown handling while suspended.
+ */
+static struct PolicyUploadContext *puc_head;
+
+/**
+ * Kept in DLL for shutdown handling while suspended.
+ */
+static struct PolicyUploadContext *puc_tail;
+
+
+/**
+ * Function called to clean up a backup context.
+ *
+ * @param hc a `struct PolicyUploadContext`
+ */
+static void
+cleanup_ctx (struct TM_HandlerContext *hc)
+{
+ struct PolicyUploadContext *puc = (struct PolicyUploadContext *) hc;
+
+ if (NULL != puc->po)
+ TALER_MERCHANT_proposal_cancel (puc->po);
+ if (NULL != puc->hash_ctx)
+ GNUNET_CRYPTO_hash_context_abort (puc->hash_ctx);
+ if (NULL != puc->resp)
+ MHD_destroy_response (puc->resp);
+ GNUNET_free_non_null (puc->existing_order_id);
+ GNUNET_free_non_null (puc->upload);
+ GNUNET_free (puc);
+}
+
+
+/**
+ * We got some query status from the DB. Handle the error cases.
+ * May perform asynchronous operations by suspending the connection
+ * if required.
+ *
+ * @param puc connection to handle status for
+ * @param qs query status to handle
+ * @return #MHD_YES or #MHD_NO
+ */
+static int
+handle_database_error (struct PolicyUploadContext *puc,
+ enum ANASTASIS_DB_QueryStatus qs)
+{
+ switch (qs)
+ {
+ case ANASTASIS_DB_STATUS_OLD_RECOVERY_UPLOAD_MISSMATCH:
+ /* FIXME handle missmatch
+
+ return SH_return_backup (puc->con,
+ &puc->account,
+ MHD_HTTP_CONFLICT);
+ */
+ return MHD_YES; //FIXME
+ case ANASTASIS_DB_STATUS_PAYMENT_REQUIRED:
+ /* FIXME: payment handling
+
+ {
+ const char *order_id;
+
+ order_id = MHD_lookup_connection_value (puc->con,
+ MHD_GET_ARGUMENT_KIND,
+ "paying");
+ if (NULL == order_id)
+ {
+ return begin_payment (puc,
+ GNUNET_NO);
+ }
+ await_payment (puc,
+ CHECK_PAYMENT_TIMEOUT,
+ order_id);
+ }
+ */
+ return MHD_YES;
+ case ANASTASIS_DB_STATUS_HARD_ERROR:
+ case ANASTASIS_DB_STATUS_SOFT_ERROR:
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (puc->con,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_SYNC_DATABASE_FETCH_ERROR,
+ "failed to fetch existing record from
database");
+ case ANASTASIS_DB_STATUS_SUCCESS_NO_RESULTS:
+ GNUNET_assert (0);
+ return MHD_NO;
+ /* intentional fall-through! */
+ case ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT:
+ GNUNET_assert (0);
+ return MHD_NO;
+ }
+ GNUNET_break (0);
+ return MHD_NO;
+}
+
+
+/**
+ * @param connection the MHD connection to handle
+ * @param con_cls the connection's closure
+ * @param url handles a URL of the format "/policy/$ACCOUNT_PUB"
+ * @param recovery_data upload data
+ * @param recovery_data_size number of bytes (left) in @a recovery_data
+ * @return MHD result code
+ */
+int
+AH_handler_policy_POST (struct MHD_Connection *connection,
+ void **con_cls,
+ const char *url,
+ const char *recovery_data,
+ size_t *recovery_data_size)
+{
+ struct PolicyUploadContext *puc;
+ struct ANASTASIS_AccountPubP accountPubP;
+
+ puc = *con_cls;
+ if (NULL == puc)
+ {
+ /* first call, setup internals */
+ puc = GNUNET_new (struct PolicyUploadContext);
+ puc->hc.cc = &cleanup_ctx;
+ puc->con = connection;
+
+ /* extract publickey from url */
+ GNUNET_assert (0 == strncmp (url,
+ "/policy/",
+ strlen ("/policy/")));
+ {
+ const char *account;
+
+ account = &url[strlen ("/policy/")];
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_public_key_from_string (account,
+ strlen (account),
+ &accountPubP.pub))
+ {
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ 42 /*FIXME */,
+ "account public key malformed");
+ }
+ }
+ puc->account = accountPubP;
+ *con_cls = puc;
+
+ /* no setup 'puc' */
+ {
+ const char *lens;
+ unsigned long len;
+
+ lens = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_CONTENT_LENGTH);
+ if ( (NULL == lens) ||
+ (1 !=
+ sscanf (lens,
+ "%lu",
+ &len)) )
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ //FIXME: ANASTASIS error c
+ TALER_EC_SYNC_BAD_CONTENT_LENGTH,
+ (NULL == lens)
+ ? "Content-length value missing"
+ : "Content-length value malformed");
+ }
+ if (len / 1024 / 1024 >= SH_upload_limit_mb)
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_PAYLOAD_TOO_LARGE,
+ TALER_EC_SYNC_BAD_CONTENT_LENGTH,
+ "Content-length value not
acceptable");
+ }
+ puc->upload = GNUNET_malloc_large (len);
+ if (NULL == puc->upload)
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "malloc");
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_PAYLOAD_TOO_LARGE,
+
TALER_EC_SYNC_OUT_OF_MEMORY_ON_CONTENT_LENGTH,
+ "Server out of memory, try again
later");
+ }
+ puc->upload_size = (size_t) len;
+ }
+ {
+ // Check if header contains if-match
+ const char *im;
+
+ im = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_IF_MATCH);
+ if ( (NULL != im) &&
+ (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (im,
+ strlen (im),
+ &puc->old_policy_upload_hash,
+ sizeof
(&puc->old_policy_upload_hash))) )
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_SYNC_BAD_IF_MATCH,
+ "If-Match does not include a
base32-encoded SHA-512 hash");
+ }
+ }
+ {
+ // Check if header contains Anastasis-Policy-Signature
+ const char *sig_s;
+
+ sig_s = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ "Anastasis-Policy-Signature");
+ if ( (NULL == sig_s) ||
+ (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (sig_s,
+ strlen (sig_s),
+ &puc->account_sig,
+ sizeof (&puc->account_sig))) )
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_SYNC_BAD_SYNC_SIGNATURE,
+ "Anastasis-Policy-Signature does
not include a base32-encoded EdDSA signature");
+ }
+ }
+ {
+ // Check if header contains an ETAG
+ const char *etag;
+
+ etag = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ MHD_HTTP_HEADER_ETAG);
+ if ( (NULL == etag) ||
+ (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (etag,
+ strlen (etag),
+ &puc->new_policy_upload_hash,
+ sizeof
(&puc->new_policy_upload_hash))) )
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_SYNC_BAD_ETAG,
+ "Etag does not include a
base32-encoded SHA-512 hash");
+ }
+ }
+ /* validate signature */
+ {
+ struct ANASTASIS_UploadSignaturePS usp;
+
+ usp.purpose.size = htonl (sizeof (struct ANASTASIS_UploadSignaturePS));
+ usp.purpose.purpose = htonl (TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD);
+ usp.old_recovery_data_hash = puc->old_policy_upload_hash;
+ usp.new_recovery_data_hash = puc->new_policy_upload_hash;
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD,
+ &usp.purpose,
+ &puc->account_sig.eddsa_sig,
+ &accountPubP.pub))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_FORBIDDEN,
+ TALER_EC_SYNC_INVALID_SIGNATURE,
+ "Account signature does not match
upload");
+ }
+ }
+ /* get ready to hash (done here as we may go aANASTASIS for payments next)
*/
+ puc->hash_ctx = GNUNET_CRYPTO_hash_context_start ();
+
+ /* Check database to see if the transaction is permissable */
+ {
+ struct GNUNET_HashCode hc;
+ enum ANASTASIS_DB_QueryStatus qs;
+
+ qs = db->lookup_account (db->cls,
+ &accountPubP);
+ if (qs < 0)
+ return handle_database_error (puc,
+ qs);
+ if (ANASTASIS_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ memset (&hc, 0, sizeof (hc));
+ if (0 == GNUNET_memcmp (&hc,
+ &puc->new_policy_upload_hash))
+ {
+ /* Refuse upload: we already have that backup! */
+ struct MHD_Response *resp;
+ int ret;
+
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+
MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
+ "*"));
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NOT_MODIFIED,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+ }
+ if (0 != GNUNET_memcmp (&hc,
+ &puc->old_policy_upload_hash))
+ {
+ /* Refuse upload: if-none-match failed! */
+ return SH_return_backup (connection,
+ accountPubP,
+ MHD_HTTP_CONFLICT);
+ }
+ }
+ /* check if the client insists on paying */
+ { /* FIXME handle paying
+ const char *order_req;
+
+ order_req = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "pay");
+ if (NULL != order_req)
+ return begin_payment (puc,
+ GNUNET_YES);
+ } */
+ /* ready to begin! */
+ return MHD_YES;
+ }
+ /* handle upload */
+ // FIXME adapt upload handling
+ if (0 != recovery_data_size)
+ {
+ /* check MHD invariant */
+ GNUNET_assert (puc->upload_off + *recovery_data_size <= puc->upload_size);
+ memcpy (&puc->upload[puc->upload_off],
+ recovery_data,
+ *recovery_data_size);
+ puc->upload_off += *recovery_data_size;
+ GNUNET_CRYPTO_hash_context_read (puc->hash_ctx,
+ recovery_data,
+ *recovery_data_size);
+ *recovery_data_size = 0;
+ return MHD_YES;
+ }
+ if (NULL != bc->resp)
+ {
+ /* We generated a response asynchronously, queue that */
+ return MHD_queue_response (connection,
+ bc->response_code,
+ bc->resp);
+ }
+
+ /* finished with upload, check hash */
+ {
+ struct GNUNET_HashCode our_hash;
+
+ GNUNET_CRYPTO_hash_context_finish (bc->hash_ctx,
+ &our_hash);
+ bc->hash_ctx = NULL;
+ if (0 != GNUNET_memcmp (&our_hash,
+ &bc->new_backup_hash))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_SYNC_INVALID_UPLOAD,
+ "Data uploaded does not match Etag
promise");
+ }
+ }
+
+ /* store backup to database */
+ {
+ enum SYNC_DB_QueryStatus qs;
+
+ if (GNUNET_is_zero (&bc->old_backup_hash))
+ qs = db->store_backup_TR (db->cls,
+ account,
+ &bc->account_sig,
+ &bc->new_backup_hash,
+ bc->upload_size,
+ bc->upload);
+ else
+ qs = db->update_backup_TR (db->cls,
+ account,
+ &bc->old_backup_hash,
+ &bc->account_sig,
+ &bc->new_backup_hash,
+ bc->upload_size,
+ bc->upload);
+ if (qs < 0)
+ return handle_database_error (bc,
+ qs);
+ if (0 == qs)
+ {
+ /* database says nothing actually changed, 304 (could
+ theoretically happen if another equivalent upload succeeded
+ since we last checked!) */
+ struct MHD_Response *resp;
+ int ret;
+
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+
MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
+ "*"));
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NOT_MODIFIED,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+ }
+ }
+
+ /* generate main (204) standard success reply */
+ {
+ struct MHD_Response *resp;
+ int ret;
+
+ resp = MHD_create_response_from_buffer (0,
+ NULL,
+ MHD_RESPMEM_PERSISTENT);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (resp,
+
MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
+ "*"));
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_NO_CONTENT,
+ resp);
+ MHD_destroy_response (resp);
+ return ret;
+ }
+
+ void *recovery_data;
+ const char *paymentIdentifier_str;
+ const struct ANASTASIS_PaymentSecretP *paymentIdentifier;
+ unsigned int version;
+ int ret;
+
+ GNUNET_STRINGS_string_to_data (recovery_data,
+ strlen (recovery_data),
+ &recovery_data,
+ sizeof (recovery_data));
+
+
+
+ paymentIdentifier_str = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ "Payment-Identifier");
+
+ memcpy (&paymentIdentifier,
+ paymentIdentifier_str,
+ strlen (paymentIdentifier_str) + 1);
+
+ db->store_recovery_document (db->cls,
+ &accountPubP,
+ recovery_data,
+ sizeof (recovery_data),
+ paymentIdentifier,
+ &version);
+
+ }
+
+ // BUILD reply
+ {
+ struct MHD_Response *response;
+
+ // FIXME: find correct create response
+ response = GNUNET_REST_create_response ("Irgendwas");
+
+ TALER_MHD_add_global_headers (response);
+ GNUNET_break (MHD_YES ==
+ MHD_add_response_header (response,
+ "Anastasis-Version",
+ version + ""));
+ ret = MHD_queue_response (connection,
+ MHD_HTTP_OK,
+ response);
+ MHD_destroy_response (response);
+ }
+ return ret;
+}
/**
@@ -146,85 +750,3 @@ AH_handler_policy_GET (struct MHD_Connection *connection,
return ret;
}
-/**
- * @param connection the MHD connection to handle
- * @param con_cls the connection's closure
- * @param url handles a URL of the format "/policy/$ACCOUNT_PUB"
- * @param upload_data upload data
- * @param upload_data_size number of bytes (left) in @a upload_data
- * @return MHD result code
- */
-int
-AH_handler_policy_POST (struct MHD_Connection *connection,
- void **con_cls,
- const char *url,
- const char *upload_data,
- size_t *upload_data_size)
-{
-
- struct ANASTASIS_AccountPubP accountPubP;
- void *recovery_data;
- const char *paymentIdentifier_str;
- const struct ANASTASIS_PaymentSecretP *paymentIdentifier;
- unsigned int version;
- int ret;
-
- GNUNET_STRINGS_string_to_data (upload_data,
- strlen (upload_data),
- &recovery_data,
- sizeof (recovery_data));
-
- GNUNET_assert (0 == strncmp (url,
- "/policy/",
- strlen ("/policy/")));
- {
- const char *account;
-
- account = &url[strlen ("/policy/")];
- if (GNUNET_OK !=
- GNUNET_CRYPTO_eddsa_public_key_from_string (account,
- strlen (account),
- &accountPubP.pub))
- {
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- 42 /*FIXME */,
- "account public key malformed");
- }
-
- paymentIdentifier_str = MHD_lookup_connection_value (connection,
- MHD_HEADER_KIND,
- "Payment-Identifier");
-
- memcpy (&paymentIdentifier,
- paymentIdentifier_str,
- strlen (paymentIdentifier_str) + 1);
-
- db->store_recovery_document (db->cls,
- &accountPubP,
- recovery_data,
- sizeof (recovery_data),
- paymentIdentifier,
- &version);
-
- }
-
- // BUILD reply
- {
- struct MHD_Response *response;
-
- // FIXME: find correct create response
- response = GNUNET_REST_create_response ("Irgendwas");
-
- TALER_MHD_add_global_headers (response);
- GNUNET_break (MHD_YES ==
- MHD_add_response_header (response,
- "Anastasis-Version",
- version + ""));
- ret = MHD_queue_response (connection,
- MHD_HTTP_OK,
- response);
- MHD_destroy_response (response);
- }
- return ret;
-}
diff --git a/src/include/anastasis_database_lib.h
b/src/include/anastasis_database_lib.h
index 39a4b54..9a6f253 100644
--- a/src/include/anastasis_database_lib.h
+++ b/src/include/anastasis_database_lib.h
@@ -47,6 +47,16 @@ ANASTASIS_DB_plugin_unload (struct ANASTASIS_DatabasePlugin
*plugin);
*/
enum ANASTASIS_DB_QueryStatus
{
+ /**
+ * Update failed because the old recovery data hash does not match what we
previously had in the DB.
+ */
+ ANASTASIS_DB_STATUS_OLD_RECOVERY_UPLOAD_MISSMATCH = -4,
+
+ /**
+ * Account is unpaid / does not exist.
+ */
+ ANASTASIS_DB_STATUS_PAYMENT_REQUIRED = -3,
+
/**
* A hard error occurred, retrying will not help.
*/
diff --git a/src/include/anastasis_database_plugin.h
b/src/include/anastasis_database_plugin.h
index e4d59ac..3529ae2 100644
--- a/src/include/anastasis_database_plugin.h
+++ b/src/include/anastasis_database_plugin.h
@@ -28,6 +28,7 @@
#include <taler/taler_util.h>
#include <uuid/uuid.h>
+
/**
* Handle to interact with the database.
*
@@ -249,5 +250,15 @@ struct ANASTASIS_DatabasePlugin
const uuid_t *uuid,
void **key_share,
size_t *key_share_size);
+
+ /**
+* @param cls closure
+* @param anastasis_pub account identifier
+* @return transaction status
+*/
+enum ANASTASIS_DB_QueryStatus
+(*lookup_account)(void *cls,
+ const struct
+ ANASTASIS_AccountPubP *anastasis_pub);
};
#endif
diff --git a/src/include/anastasis_service.h b/src/include/anastasis_service.h
index 89e9664..3a79bdc 100644
--- a/src/include/anastasis_service.h
+++ b/src/include/anastasis_service.h
@@ -332,7 +332,7 @@ ANASTASIS_policy_store (struct GNUNET_CURL_Context *ctx,
const char *backend_url,
const struct
ANASTASIS_AccountPrivP *anastasis_priv,
- const struct
+ const struct
GNUNET_HashCode *prev_recovery_data_hash,
const void *recovery_data,
size_t recovery_data_size,
diff --git a/src/lib/anastasis_api_policy_store.c
b/src/lib/anastasis_api_policy_store.c
index 4e5130d..701a18a 100644
--- a/src/lib/anastasis_api_policy_store.c
+++ b/src/lib/anastasis_api_policy_store.c
@@ -262,7 +262,7 @@ ANASTASIS_policy_store (struct GNUNET_CURL_Context *ctx,
const char *backend_url,
const struct
ANASTASIS_AccountPrivP *anastasis_priv,
- const struct
+ const struct
GNUNET_HashCode *prev_recovery_data_hash,
const void *recovery_data,
size_t recovery_data_size,
@@ -371,15 +371,15 @@ ANASTASIS_policy_store (struct GNUNET_CURL_Context *ctx,
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);
+ "policy/%s",
+ acc_pub_str);
GNUNET_free (acc_pub_str);
pso->url = TALER_url_join (backend_url,
- "policy",
- pub);
+ "policy",
+ pub);
GNUNET_free (path);
}
pso->ctx = ctx;
diff --git a/src/lib/test_anastasis_api.c b/src/lib/test_anastasis_api.c
index c1876fb..9a24054 100644
--- a/src/lib/test_anastasis_api.c
+++ b/src/lib/test_anastasis_api.c
@@ -240,8 +240,8 @@ static void
run (void *cls,
struct TALER_TESTING_Interpreter *is)
{
-
- //fill data
+
+ // fill data
const char *str = "AHV123456789";
GNUNET_CRYPTO_eddsa_private_key_from_string (str,
sizeof (str),
diff --git a/src/lib/testing_api_cmd_policy_store.c
b/src/lib/testing_api_cmd_policy_store.c
index e04337f..e8cc863 100644
--- a/src/lib/testing_api_cmd_policy_store.c
+++ b/src/lib/testing_api_cmd_policy_store.c
@@ -40,7 +40,7 @@ struct PolicyStoreState
*/
const void *recovery_data;
- /**
+ /**
* Number of bytes in @e recovery_data
*/
size_t recovery_data_size;
diff --git a/src/stasis/plugin_anastasis_postgres.c
b/src/stasis/plugin_anastasis_postgres.c
index e034a0a..66d79b4 100644
--- a/src/stasis/plugin_anastasis_postgres.c
+++ b/src/stasis/plugin_anastasis_postgres.c
@@ -757,6 +757,37 @@ postgres_get_key_share (void *cls,
rs);
}
+
+/**
+* @param cls closure
+* @param anastasis_pub account identifier
+* @return transaction status
+*/
+enum ANASTASIS_DB_QueryStatus
+postgres_lookup_account (void *cls,
+ const struct
+ ANASTASIS_AccountPubP *anastasis_pub)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_TIME_Absolute paid_until;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (anastasis_pub),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_absolute_time ("paid_until",
+ &paid_until),
+ GNUNET_PQ_result_spec_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "user_select",
+ params,
+ rs);
+}
+
+
/**
* Fetch latest recovery document for user.
*
@@ -1006,6 +1037,7 @@ libanastasis_plugin_db_postgres_init (void *cls)
plugin->get_key_share = &postgres_get_key_share;
plugin->get_latest_recovery_document =
&postgres_get_latest_recovery_document;
plugin->get_recovery_document = &postgres_get_recovery_document;
+ plugin->lookup_account = &postgres_lookup_account;
plugin->start = &begin_transaction;
plugin->check_connection = &check_connection;
diff --git a/src/stasis/test_anastasis_db.c b/src/stasis/test_anastasis_db.c
index 704b1e2..da458fb 100644
--- a/src/stasis/test_anastasis_db.c
+++ b/src/stasis/test_anastasis_db.c
@@ -186,6 +186,10 @@ run (void *cls)
rel_time,
&paymentSecretP));
+ FAILIF (ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT !=
+ plugin->lookup_account (plugin->cls,
+ &accountPubP));
+
FAILIF (ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT !=
plugin->store_truth (plugin->cls,
&uuid,
--
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/testing,
gnunet <=