diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-08-19 15:27:16 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-08-19 15:27:16 +0200 |
commit | 989f86701c5880e5f462d9bed70071894beb8dae (patch) | |
tree | e5bc2cfcf85bc295bb35e70743414684509766e0 | |
parent | b16606b8f06a6c45c85382145b536c8a468270c4 (diff) | |
download | sync-989f86701c5880e5f462d9bed70071894beb8dae.tar.gz sync-989f86701c5880e5f462d9bed70071894beb8dae.tar.bz2 sync-989f86701c5880e5f462d9bed70071894beb8dae.zip |
adjust sync to API changes and to work with claim tokens
-rw-r--r-- | src/include/sync_database_plugin.h | 4 | ||||
-rw-r--r-- | src/sync/sync-httpd.c | 1 | ||||
-rw-r--r-- | src/sync/sync-httpd_backup_post.c | 91 | ||||
-rw-r--r-- | src/syncdb/plugin_syncdb_postgres.c | 21 | ||||
-rw-r--r-- | src/syncdb/test_sync_db.c | 6 | ||||
-rw-r--r-- | src/testing/test_sync_api.c | 3 | ||||
-rw-r--r-- | src/testing/testing_api_cmd_backup_upload.c | 77 |
7 files changed, 151 insertions, 52 deletions
diff --git a/src/include/sync_database_plugin.h b/src/include/sync_database_plugin.h index e35ce11..421f157 100644 --- a/src/include/sync_database_plugin.h +++ b/src/include/sync_database_plugin.h @@ -76,12 +76,14 @@ enum SYNC_DB_QueryStatus * @param cls closure * @param timestamp for how long have we been waiting * @param order_id order id in the backend + * @param token claim token, or NULL for none * @param amount how much is the order for */ typedef void (*SYNC_DB_PaymentPendingIterator)(void *cls, struct GNUNET_TIME_Absolute timestamp, const char *order_id, + const struct TALER_ClaimTokenP *token, const struct TALER_Amount *amount); @@ -166,6 +168,7 @@ struct SYNC_DatabasePlugin * @param cls closure * @param account_pub account to store @a backup under * @param order_id order we created + * @param token claim token, or NULL for none * @param amount how much we asked for * @return transaction status */ @@ -173,6 +176,7 @@ struct SYNC_DatabasePlugin (*store_payment_TR)(void *cls, const struct SYNC_AccountPublicKeyP *account_pub, const char *order_id, + const struct TALER_ClaimTokenP *token, const struct TALER_Amount *amount); diff --git a/src/sync/sync-httpd.c b/src/sync/sync-httpd.c index 02c47dc..f466c94 100644 --- a/src/sync/sync-httpd.c +++ b/src/sync/sync-httpd.c @@ -171,7 +171,6 @@ url_handler (void *cls, (void) cls; (void) version; hc = *con_cls; - if (NULL == hc) { GNUNET_async_scope_fresh (&aid); diff --git a/src/sync/sync-httpd_backup_post.c b/src/sync/sync-httpd_backup_post.c index 86327cb..3c7fe57 100644 --- a/src/sync/sync-httpd_backup_post.c +++ b/src/sync/sync-httpd_backup_post.c @@ -68,6 +68,11 @@ struct BackupContext struct GNUNET_HashCode new_backup_hash; /** + * Claim token, all zeros if not known. Only set if @e existing_order_id is non-NULL. + */ + struct TALER_ClaimTokenP token; + + /** * Hash context for the upload. */ struct GNUNET_HashContext *hash_ctx; @@ -207,10 +212,13 @@ cleanup_ctx (struct TM_HandlerContext *hc) * * @param connection MHD connection * @param order_id our backend's order ID + * @param token the claim token generated by the merchant (NULL if + * it wasn't generated). * @return MHD response to use */ static struct MHD_Response * -make_payment_request (const char *order_id) +make_payment_request (const char *order_id, + const struct TALER_ClaimTokenP *token) { struct MHD_Response *resp; @@ -224,12 +232,63 @@ make_payment_request (const char *order_id) TALER_MHD_add_global_headers (resp); { char *hdr; + char *pfx; + char *hn; - /* TODO: support instances? */ - GNUNET_asprintf (&hdr, - "taler://pay/%s/-/-/%s", - SH_backend_url, - order_id); + if (0 == strncasecmp ("https://", + SH_backend_url, + strlen ("https://"))) + { + pfx = "taler://"; + hn = &SH_backend_url[strlen ("https://")]; + } + else if (0 == strncasecmp ("http://", + SH_backend_url, + strlen ("http://"))) + { + pfx = "taler+http://"; + hn = &SH_backend_url[strlen ("http://")]; + } + else + { + GNUNET_break (0); + MHD_destroy_response (resp); + return NULL; + } + if (0 == strlen (hn)) + { + GNUNET_break (0); + MHD_destroy_response (resp); + return NULL; + } + // FIXME: support instances? + if (NULL != token) + { + char tok[256]; + + GNUNET_assert (NULL != + GNUNET_STRINGS_data_to_string (token, + sizeof (*token), + tok, + sizeof (tok))); + GNUNET_asprintf (&hdr, + "%spay/%s%s%s/?c=%s", + pfx, + hn, + ('/' == hn[strlen (hn) - 1]) + ? "" + : "/", + order_id, + tok); + } + else + { + GNUNET_asprintf (&hdr, + "%spay/%s/%s/", + pfx, + hn, + order_id); + } GNUNET_break (MHD_YES == MHD_add_response_header (resp, "Taler", @@ -247,11 +306,14 @@ make_payment_request (const char *order_id) * @param cls our `struct BackupContext` * @param hr HTTP response details * @param order_id order id of the newly created order + * @param token the claim token generated by the merchant (NULL if + * it wasn't generated). */ static void proposal_cb (void *cls, const struct TALER_MERCHANT_HttpResponse *hr, - const char *order_id) + const char *order_id, + const struct TALER_ClaimTokenP *token) { struct BackupContext *bc = cls; enum SYNC_DB_QueryStatus qs; @@ -294,6 +356,7 @@ proposal_cb (void *cls, qs = db->store_payment_TR (db->cls, &bc->account, order_id, + token, &SH_annual_fee); if (0 >= qs) { @@ -307,7 +370,8 @@ proposal_cb (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Obtained fresh order `%s'\n", order_id); - bc->resp = make_payment_request (order_id); + bc->resp = make_payment_request (order_id, + token); GNUNET_assert (NULL != bc->resp); bc->response_code = MHD_HTTP_PAYMENT_REQUIRED; } @@ -320,12 +384,14 @@ proposal_cb (void *cls, * @param cls closure, our `struct BackupContext` * @param timestamp for how long have we been waiting * @param order_id order id in the backend + * @param token claim token to use (or NULL for none) * @param amount how much is the order for */ static void ongoing_payment_cb (void *cls, struct GNUNET_TIME_Absolute timestamp, const char *order_id, + const struct TALER_ClaimTokenP *token, const struct TALER_Amount *amount) { struct BackupContext *bc = cls; @@ -340,6 +406,8 @@ ongoing_payment_cb (void *cls, GNUNET_free (bc->existing_order_id); bc->existing_order_id = GNUNET_strdup (order_id); bc->existing_order_timestamp = timestamp; + if (NULL != token) + bc->token = *token; } } @@ -390,7 +458,10 @@ check_payment_cb (void *cls, /* repeat payment request */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Repeating payment request\n"); - bc->resp = make_payment_request (bc->existing_order_id); + bc->resp = make_payment_request (bc->existing_order_id, + (GNUNET_YES == GNUNET_is_zero (&bc->token)) + ? NULL + : &bc->token); GNUNET_assert (NULL != bc->resp); bc->response_code = MHD_HTTP_PAYMENT_REQUIRED; return; @@ -853,7 +924,7 @@ SH_backup_post (struct MHD_Connection *connection, { enum SYNC_DB_QueryStatus qs; - if (0 == GNUNET_is_zero (&bc->old_backup_hash)) + if (GNUNET_YES == GNUNET_is_zero (&bc->old_backup_hash)) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Uploading first backup to account\n"); diff --git a/src/syncdb/plugin_syncdb_postgres.c b/src/syncdb/plugin_syncdb_postgres.c index 8431ed3..2538070 100644 --- a/src/syncdb/plugin_syncdb_postgres.c +++ b/src/syncdb/plugin_syncdb_postgres.c @@ -258,7 +258,8 @@ postgres_gc (void *cls, * * @param cls closure * @param account_pub account to store @a backup under - * @param order_id order we created + * @param order_id order we create + * @param token claim token to use, NULL for none * @param amount how much we asked for * @return transaction status */ @@ -266,19 +267,26 @@ static enum SYNC_DB_QueryStatus postgres_store_payment (void *cls, const struct SYNC_AccountPublicKeyP *account_pub, const char *order_id, + const struct TALER_ClaimTokenP *token, const struct TALER_Amount *amount) { struct PostgresClosure *pg = cls; enum GNUNET_DB_QueryStatus qs; + struct TALER_ClaimTokenP tok; struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (account_pub), GNUNET_PQ_query_param_string (order_id), + GNUNET_PQ_query_param_auto_from_type (&tok), GNUNET_PQ_query_param_absolute_time (&now), TALER_PQ_query_param_amount (amount), GNUNET_PQ_query_param_end }; + if (NULL == token) + memset (&tok, 0, sizeof (tok)); + else + tok = *token; check_connection (pg); postgres_preflight (pg); qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, @@ -353,11 +361,14 @@ payment_by_account_cb (void *cls, struct GNUNET_TIME_Absolute timestamp; char *order_id; struct TALER_Amount amount; + struct TALER_ClaimTokenP token; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_absolute_time ("timestamp", ×tamp), GNUNET_PQ_result_spec_string ("order_id", &order_id), + GNUNET_PQ_result_spec_auto_from_type ("token", + &token), TALER_PQ_result_spec_amount ("amount", pic->pg->currency, &amount), @@ -377,6 +388,7 @@ payment_by_account_cb (void *cls, pic->it (pic->it_cls, timestamp, order_id, + &token, &amount); GNUNET_PQ_cleanup_result (rs); } @@ -1025,6 +1037,7 @@ libsync_plugin_db_postgres_init (void *cls) GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS payments" "(account_pub BYTEA CHECK (length(account_pub)=32)" ",order_id VARCHAR PRIMARY KEY" + ",token BYTEA CHECK (length(token)=16)" ",timestamp INT8 NOT NULL" ",amount_val INT8 NOT NULL" /* amount we were paid */ ",amount_frac INT4 NOT NULL" @@ -1058,12 +1071,13 @@ libsync_plugin_db_postgres_init (void *cls) "INSERT INTO payments " "(account_pub" ",order_id" + ",token" ",timestamp" ",amount_val" ",amount_frac" ") VALUES " - "($1,$2,$3,$4,$5);", - 5), + "($1,$2,$3,$4,$5,$6);", + 6), GNUNET_PQ_make_prepare ("payment_done", "UPDATE payments " "SET" @@ -1103,6 +1117,7 @@ libsync_plugin_db_postgres_init (void *cls) "SELECT" " timestamp" ",order_id" + ",token" ",amount_val" ",amount_frac" " FROM payments" diff --git a/src/syncdb/test_sync_db.c b/src/syncdb/test_sync_db.c index 51ef58b..09c7501 100644 --- a/src/syncdb/test_sync_db.c +++ b/src/syncdb/test_sync_db.c @@ -54,12 +54,14 @@ static struct SYNC_DatabasePlugin *plugin; * @param cls closure * @param timestamp for how long have we been waiting * @param order_id order id in the backend + * @param token claim token, or NULL for none * @param amount how much is the order for */ static void payment_it (void *cls, struct GNUNET_TIME_Absolute timestamp, const char *order_id, + const struct TALER_ClaimTokenP *token, const struct TALER_Amount *amount) { GNUNET_assert (NULL == cls); @@ -87,6 +89,7 @@ run (void *cls) struct GNUNET_HashCode r; struct GNUNET_HashCode r2; struct GNUNET_TIME_Absolute ts; + struct TALER_ClaimTokenP token; size_t bs; void *b = NULL; @@ -110,6 +113,7 @@ run (void *cls) } memset (&account_pub, 1, sizeof (account_pub)); memset (&account_sig, 2, sizeof (account_sig)); + memset (&token, 3, sizeof (token)); GNUNET_CRYPTO_hash ("data", 4, &h); GNUNET_CRYPTO_hash ("DATA", 4, &h2); GNUNET_CRYPTO_hash ("ATAD", 4, &h3); @@ -120,6 +124,7 @@ run (void *cls) plugin->store_payment_TR (plugin->cls, &account_pub, "fake-order", + &token, &amount)); FAILIF (SYNC_DB_ONE_RESULT != plugin->increment_lifetime_TR (plugin->cls, @@ -200,6 +205,7 @@ run (void *cls) plugin->store_payment_TR (plugin->cls, &account_pub, "fake-order-2", + &token, &amount)); FAILIF (1 != plugin->lookup_pending_payments_by_account_TR (plugin->cls, diff --git a/src/testing/test_sync_api.c b/src/testing/test_sync_api.c index 3ff0215..8c38a44 100644 --- a/src/testing/test_sync_api.c +++ b/src/testing/test_sync_api.c @@ -202,7 +202,8 @@ run (void *cls, "fetch-proposal", "withdraw-coin-1", "EUR:5", - "EUR:4.99"), /* must match ANNUAL_FEE in config! */ + "EUR:4.99", /* must match ANNUAL_FEE in config! */ + "session-id"), /* now upload should succeed */ SYNC_TESTING_cmd_backup_upload ("backup-upload-2", sync_url, diff --git a/src/testing/testing_api_cmd_backup_upload.c b/src/testing/testing_api_cmd_backup_upload.c index 1b9f9a8..7c87306 100644 --- a/src/testing/testing_api_cmd_backup_upload.c +++ b/src/testing/testing_api_cmd_backup_upload.c @@ -26,6 +26,7 @@ #include "sync_testing_lib.h" #include <taler/taler_util.h> #include <taler/taler_testing_lib.h> +#include <taler/taler_merchant_service.h> #include "sync_testing_lib.h" /** @@ -84,6 +85,11 @@ struct BackupUploadState char *payment_order_id; /** + * Claim token we got back, if any. Otherwise all zeros. + */ + struct TALER_ClaimTokenP token; + + /** * Payment order ID we are to provide in the request, may be NULL. */ const char *payment_order_req; @@ -159,37 +165,20 @@ backup_upload_cb (void *cls, break; case SYNC_US_PAYMENT_REQUIRED: { - const char *m; + struct TALER_MERCHANT_PayUriData pd; - if (0 != strncmp (ud->details.payment_request, - "taler://pay/http", - strlen ("taler://pay/http"))) + if (GNUNET_OK != + TALER_MERCHANT_parse_pay_uri (ud->details.payment_request, + &pd)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Did not find `%s' in `%s'\n", - "/-/-/", - ud->details.payment_request); + GNUNET_break (0); TALER_TESTING_interpreter_fail (bus->is); return; } - m = strstr (ud->details.payment_request, "/-/-/"); - if (NULL == m) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Did not find `%s' in `%s'\n", - "/-/-/", - ud->details.payment_request); - TALER_TESTING_interpreter_fail (bus->is); - /* NOTE: The above is a simplifying assumption for the - test-logic, hitting this code merely means that - the assumptions for the test (i.e. no instance) are - not satisfied, it is not inherently the case that - the above token must appear in the payment request! - - So if you hit this, you might just want to modify - the code here to handle this better! */return; - } - bus->payment_order_id = GNUNET_strdup (&m[strlen ("/-/-/")]); + bus->payment_order_id = GNUNET_strdup (pd.order_id); + if (NULL != pd.claim_token) + bus->token = *pd.claim_token; + TALER_MERCHANT_parse_pay_uri_free (&pd); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Order ID from Sync service is `%s'\n", bus->payment_order_id); @@ -255,9 +244,9 @@ backup_upload_run (void *cls, { const struct TALER_TESTING_Command *ref; - ref = TALER_TESTING_interpreter_lookup_command - (is, - bus->prev_upload); + ref = TALER_TESTING_interpreter_lookup_command ( + is, + bus->prev_upload); if (NULL == ref) { GNUNET_break (0); @@ -267,16 +256,13 @@ backup_upload_run (void *cls, { const struct GNUNET_HashCode *h; - if (GNUNET_OK != + if (GNUNET_OK == SYNC_TESTING_get_trait_hash (ref, SYNC_TESTING_TRAIT_HASH_CURRENT, &h)) { - GNUNET_break (0); - TALER_TESTING_interpreter_fail (bus->is); - return; + bus->prev_hash = *h; } - bus->prev_hash = *h; } { const struct SYNC_AccountPrivateKeyP *priv; @@ -345,7 +331,8 @@ backup_upload_run (void *cls, bus->sync_url, &bus->sync_priv, ( ( (NULL != bus->prev_upload) && - (0 != GNUNET_is_zero (&bus->prev_hash)) ) || + (GNUNET_YES != GNUNET_is_zero ( + &bus->prev_hash)) ) || (0 != (SYNC_TESTING_UO_PREV_HASH_WRONG & bus->uopt)) ) ? &bus->prev_hash @@ -407,11 +394,24 @@ backup_upload_traits (void *cls, unsigned int index) { struct BackupUploadState *bus = cls; - struct TALER_TESTING_Trait traits[] = { + struct TALER_TESTING_Trait straits[] = { SYNC_TESTING_make_trait_hash (SYNC_TESTING_TRAIT_HASH_CURRENT, &bus->curr_hash), SYNC_TESTING_make_trait_hash (SYNC_TESTING_TRAIT_HASH_PREVIOUS, &bus->prev_hash), + TALER_TESTING_make_trait_claim_token (0, + &bus->token), + SYNC_TESTING_make_trait_account_pub (0, + &bus->sync_pub), + SYNC_TESTING_make_trait_account_priv (0, + &bus->sync_priv), + TALER_TESTING_make_trait_order_id (0, + bus->payment_order_id), + TALER_TESTING_trait_end () + }; + struct TALER_TESTING_Trait ftraits[] = { + TALER_TESTING_make_trait_claim_token (0, + &bus->token), SYNC_TESTING_make_trait_account_pub (0, &bus->sync_pub), SYNC_TESTING_make_trait_account_priv (0, @@ -421,7 +421,10 @@ backup_upload_traits (void *cls, TALER_TESTING_trait_end () }; - return TALER_TESTING_get_trait (traits, + + return TALER_TESTING_get_trait ((NULL != bus->payment_order_req) + ? ftraits + : straits, ret, trait, index); |