From 19c368fc47192f44d1cf9e651d9360c4546b2807 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 8 Mar 2024 22:53:35 +0100 Subject: implement protocol v19 in taler-exchange-httpd (for #8000); note that taler-exchange-offline support is still missing --- README | 2 +- configure.ac | 9 ++-- src/exchange/taler-exchange-httpd_keys.c | 11 ++++- .../taler-exchange-httpd_management_wire_disable.c | 2 + .../taler-exchange-httpd_management_wire_enable.c | 54 ++++++++++++++++------ src/exchangedb/Makefile.am | 11 ++++- src/exchangedb/pg_get_wire_accounts.c | 16 ++++++- src/exchangedb/pg_insert_wire.c | 14 ++++-- src/exchangedb/pg_insert_wire.h | 7 ++- src/exchangedb/pg_update_wire.c | 10 +++- src/exchangedb/pg_update_wire.h | 4 ++ src/include/taler_exchange_service.h | 10 ++++ src/include/taler_exchangedb_plugin.h | 16 ++++++- src/lib/exchange_api_common.c | 16 ++++++- src/lib/exchange_api_handle.c | 5 ++ 15 files changed, 154 insertions(+), 33 deletions(-) diff --git a/README b/README index 797253a3b..7b092e0f1 100644 --- a/README +++ b/README @@ -42,7 +42,7 @@ Dependencies: These are the direct dependencies for running a Taler exchange: -- GNUnet >= 0.21.0 +- GNUnet >= 0.21.1 - GNU libmicrohttpd >= 0.9.71 - PostgreSQL >= 15.0 diff --git a/configure.ac b/configure.ac index dc9b00a5c..e5675a732 100644 --- a/configure.ac +++ b/configure.ac @@ -182,7 +182,7 @@ AC_CHECK_HEADERS([gnunet/gnunet_util_lib.h], AS_IF([test $libgnunetutil != 1], [AC_MSG_ERROR([[ *** -*** You need libgnunetutil >= 0.21.0 to build this program. +*** You need libgnunetutil >= 0.21.1 to build this program. *** This library is part of GNUnet, available at *** https://gnunet.org *** ]])]) @@ -300,14 +300,13 @@ AS_CASE([$with_gnunet], CPPFLAGS="-I$with_gnunet/include ${CPPFLAGS}"]) CPPFLAGS="${CPPFLAGS} ${POSTGRESQL_CPPFLAGS}" AC_CHECK_HEADERS([gnunet/gnunet_pq_lib.h], - [AC_CHECK_LIB([gnunetpq], [GNUNET_PQ_get_event_notify_channel], libgnunetpq=1)]) + [AC_CHECK_LIB([gnunetpq], [GNUNET_PQ_query_param_int64], libgnunetpq=1)]) AS_IF([test $libgnunetpq != 1], [AC_MSG_ERROR([[ *** -*** You need libgnunetpq version >= 5:0:0 to build this program. +*** You need libgnunetpq version >= 6:0:1 to build this program. *** Make sure you have Postgres installed while -*** building GNUnet (and that your GNUnet version -*** is recent!) +*** building GNUnet (and that your GNUnet version is recent!) *** ]])]) CFLAGS_SAVE=$CFLAGS diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c index 92892cb6d..05fb685e0 100644 --- a/src/exchange/taler-exchange-httpd_keys.c +++ b/src/exchange/taler-exchange-httpd_keys.c @@ -670,6 +670,8 @@ TEH_wire_done () * @param credit_restrictions JSON array with credit restrictions on the account * @param master_sig master key signature affirming that this is a bank * account of the exchange (of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS) + * @param bank_label label the wallet should use to display the account, can be NULL + * @param priority priority for ordering bank account labels */ static void add_wire_account (void *cls, @@ -677,7 +679,9 @@ add_wire_account (void *cls, const char *conversion_url, const json_t *debit_restrictions, const json_t *credit_restrictions, - const struct TALER_MasterSignatureP *master_sig) + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority) { json_t *a = cls; @@ -703,6 +707,11 @@ add_wire_account (void *cls, GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("conversion_url", conversion_url)), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("bank_label", + bank_label)), + GNUNET_JSON_pack_int64 ("priority", + priority), GNUNET_JSON_pack_array_incref ("debit_restrictions", (json_t *) debit_restrictions), GNUNET_JSON_pack_array_incref ("credit_restrictions", diff --git a/src/exchange/taler-exchange-httpd_management_wire_disable.c b/src/exchange/taler-exchange-httpd_management_wire_disable.c index 53bece61c..e0b8a3de8 100644 --- a/src/exchange/taler-exchange-httpd_management_wire_disable.c +++ b/src/exchange/taler-exchange-httpd_management_wire_disable.c @@ -119,6 +119,8 @@ del_wire (void *cls, NULL, awc->validity_end, NULL, + NULL, + 0, false); if (qs < 0) { diff --git a/src/exchange/taler-exchange-httpd_management_wire_enable.c b/src/exchange/taler-exchange-httpd_management_wire_enable.c index e7c771cc2..472e19d3e 100644 --- a/src/exchange/taler-exchange-httpd_management_wire_enable.c +++ b/src/exchange/taler-exchange-httpd_management_wire_enable.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2020-2023 Taler Systems SA + Copyright (C) 2020-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software @@ -74,6 +74,16 @@ struct AddWireContext */ struct GNUNET_TIME_Timestamp validity_start; + /** + * Label to use for this bank. Default is empty. + */ + const char *bank_label; + + /** + * Priority of the bank in the list. Default 0. + */ + int64_t priority; + }; @@ -133,7 +143,9 @@ add_wire (void *cls, awc->debit_restrictions, awc->credit_restrictions, awc->validity_start, - &awc->master_sig_wire); + &awc->master_sig_wire, + awc->bank_label, + awc->priority); else qs = TEH_plugin->update_wire (TEH_plugin->cls, awc->payto_uri, @@ -142,6 +154,8 @@ add_wire (void *cls, awc->credit_restrictions, awc->validity_start, &awc->master_sig_wire, + awc->bank_label, + awc->priority, true); if (qs < 0) { @@ -183,6 +197,14 @@ TEH_handler_management_post_wire ( &awc.debit_restrictions), GNUNET_JSON_spec_timestamp ("validity_start", &awc.validity_start), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("bank_label", + &awc.bank_label), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_int64 ("priority", + &awc.priority), + NULL), GNUNET_JSON_spec_end () }; @@ -217,13 +239,14 @@ TEH_handler_management_post_wire ( } } if (GNUNET_OK != - TALER_exchange_offline_wire_add_verify (awc.payto_uri, - awc.conversion_url, - awc.debit_restrictions, - awc.credit_restrictions, - awc.validity_start, - &TEH_master_public_key, - &awc.master_sig_add)) + TALER_exchange_offline_wire_add_verify ( + awc.payto_uri, + awc.conversion_url, + awc.debit_restrictions, + awc.credit_restrictions, + awc.validity_start, + &TEH_master_public_key, + &awc.master_sig_add)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); @@ -235,12 +258,13 @@ TEH_handler_management_post_wire ( } TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++; if (GNUNET_OK != - TALER_exchange_wire_signature_check (awc.payto_uri, - awc.conversion_url, - awc.debit_restrictions, - awc.credit_restrictions, - &TEH_master_public_key, - &awc.master_sig_wire)) + TALER_exchange_wire_signature_check ( + awc.payto_uri, + awc.conversion_url, + awc.debit_restrictions, + awc.credit_restrictions, + &TEH_master_public_key, + &awc.master_sig_wire)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index af6e2166b..45070ac08 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -18,7 +18,9 @@ sqlinputs = \ exchange_do_*.sql \ procedures.sql.in \ 0002-*.sql \ - exchange-0002.sql.in + 0003-*.sql \ + exchange-0002.sql.in \ + exchange-0003.sql.in sql_DATA = \ benchmark-0001.sql \ @@ -26,6 +28,7 @@ sql_DATA = \ auditor-triggers-0001.sql \ exchange-0001.sql \ exchange-0002.sql \ + exchange-0003.sql \ drop.sql \ procedures.sql @@ -37,6 +40,7 @@ BUILT_SOURCES = \ CLEANFILES = \ exchange-0002.sql \ + exchange-0003.sql \ procedures.sql procedures.sql: procedures.sql.in exchange_do_*.sql @@ -49,6 +53,11 @@ exchange-0002.sql: exchange-0002.sql.in 0002-*.sql gcc -E -P -undef - < exchange-0002.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@ chmod ugo-w $@ +exchange-0003.sql: exchange-0003.sql.in 0003-*.sql + chmod +w $@ || true + gcc -E -P -undef - < exchange-0003.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@ + chmod ugo-w $@ + check_SCRIPTS = \ test_idempotency.sh diff --git a/src/exchangedb/pg_get_wire_accounts.c b/src/exchangedb/pg_get_wire_accounts.c index 23b939046..9770be719 100644 --- a/src/exchangedb/pg_get_wire_accounts.c +++ b/src/exchangedb/pg_get_wire_accounts.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022 Taler Systems SA + Copyright (C) 2022, 2024 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 published by the Free Software @@ -70,6 +70,8 @@ get_wire_accounts_cb (void *cls, json_t *debit_restrictions = NULL; json_t *credit_restrictions = NULL; struct TALER_MasterSignatureP master_sig; + char *bank_label = NULL; + int64_t priority; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_string ("payto_uri", &payto_uri), @@ -77,6 +79,12 @@ get_wire_accounts_cb (void *cls, GNUNET_PQ_result_spec_string ("conversion_url", &conversion_url), NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("bank_label", + &bank_label), + NULL), + GNUNET_PQ_result_spec_int64 ("priority", + &priority), GNUNET_PQ_result_spec_allow_null ( TALER_PQ_result_spec_json ("debit_restrictions", &debit_restrictions), @@ -114,7 +122,9 @@ get_wire_accounts_cb (void *cls, conversion_url, debit_restrictions, credit_restrictions, - &master_sig); + &master_sig, + bank_label, + priority); GNUNET_PQ_cleanup_result (rs); } } @@ -144,6 +154,8 @@ TEH_PG_get_wire_accounts (void *cls, ",debit_restrictions" ",credit_restrictions" ",master_sig" + ",bank_label" + ",priority" " FROM wire_accounts" " WHERE is_active"); qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, diff --git a/src/exchangedb/pg_insert_wire.c b/src/exchangedb/pg_insert_wire.c index 066143b92..b1364cbb3 100644 --- a/src/exchangedb/pg_insert_wire.c +++ b/src/exchangedb/pg_insert_wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022, 2023 Taler Systems SA + Copyright (C) 2022, 2023, 2024 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 published by the Free Software @@ -33,7 +33,9 @@ TEH_PG_insert_wire (void *cls, const json_t *debit_restrictions, const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp start_date, - const struct TALER_MasterSignatureP *master_sig) + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { @@ -45,6 +47,10 @@ TEH_PG_insert_wire (void *cls, TALER_PQ_query_param_json (credit_restrictions), GNUNET_PQ_query_param_auto_from_type (master_sig), GNUNET_PQ_query_param_timestamp (&start_date), + NULL == bank_label + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (bank_label), + GNUNET_PQ_query_param_int64 (&priority), GNUNET_PQ_query_param_end }; @@ -58,8 +64,10 @@ TEH_PG_insert_wire (void *cls, ",master_sig" ",is_active" ",last_change" + ",bank_label" + ",priority" ") VALUES " - "($1, $2, $3, $4, $5, true, $6);"); + "($1, $2, $3, $4, $5, true, $6, $7, $8);"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "insert_wire", params); diff --git a/src/exchangedb/pg_insert_wire.h b/src/exchangedb/pg_insert_wire.h index 358946719..7a5e4caca 100644 --- a/src/exchangedb/pg_insert_wire.h +++ b/src/exchangedb/pg_insert_wire.h @@ -36,6 +36,8 @@ * (only to be used for replay detection) * @param master_sig public signature affirming the existence of the account, * must be of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS + * @param bank_label label to show this entry under in the UI, can be NULL + * @param priority determines order in which entries are shown in the UI * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -45,6 +47,9 @@ TEH_PG_insert_wire (void *cls, const json_t *debit_restrictions, const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp start_date, - const struct TALER_MasterSignatureP *master_sig); + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority); + #endif diff --git a/src/exchangedb/pg_update_wire.c b/src/exchangedb/pg_update_wire.c index 439c92d4f..5c4bb9045 100644 --- a/src/exchangedb/pg_update_wire.c +++ b/src/exchangedb/pg_update_wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2022, 2023 Taler Systems SA + Copyright (C) 2022, 2023, 2024 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 published by the Free Software @@ -34,6 +34,8 @@ TEH_PG_update_wire (void *cls, const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp change_date, const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority, bool enabled) { struct PostgresClosure *pg = cls; @@ -53,6 +55,10 @@ TEH_PG_update_wire (void *cls, NULL == master_sig ? GNUNET_PQ_query_param_null () : GNUNET_PQ_query_param_auto_from_type (master_sig), + NULL == bank_label + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (bank_label), + GNUNET_PQ_query_param_int64 (&priority), GNUNET_PQ_query_param_end }; @@ -66,6 +72,8 @@ TEH_PG_update_wire (void *cls, " ,credit_restrictions=$5" " ,last_change=$6" " ,master_sig=$7" + " ,bank_label=$8" + " ,priority=$9" " WHERE payto_uri=$1"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, "update_wire", diff --git a/src/exchangedb/pg_update_wire.h b/src/exchangedb/pg_update_wire.h index 9c30816e6..a596a0802 100644 --- a/src/exchangedb/pg_update_wire.h +++ b/src/exchangedb/pg_update_wire.h @@ -37,6 +37,8 @@ * @param change_date date when the account status was last changed * (only to be used for replay detection) * @param master_sig master signature to store, can be NULL (if @a enabled is false) + * @param bank_label label to show this entry under in the UI, can be NULL + * @param priority determines order in which entries are shown in the UI * @param enabled true to enable, false to disable (the actual change) * @return transaction status code */ @@ -48,6 +50,8 @@ TEH_PG_update_wire (void *cls, const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp change_date, const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority, bool enabled); #endif diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 465c54ae5..00a382705 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -408,6 +408,16 @@ struct TALER_EXCHANGE_WireAccount */ struct TALER_MasterSignatureP master_sig; + /** + * Display label for the account, can be NULL. + */ + char *bank_label; + + /** + * Priority for ordering the account in the display. + */ + int64_t priority; + }; diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index ccfacafc4..985664c43 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -3059,6 +3059,8 @@ typedef enum GNUNET_GenericReturnValue * @param credit_restrictions JSON array with credit restrictions on the account * @param master_sig master key signature affirming that this is a bank * account of the exchange (of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS) + * @param bank_label label the wallet should use to display the account, can be NULL + * @param priority priority for ordering bank account labels */ typedef void (*TALER_EXCHANGEDB_WireAccountCallback)( @@ -3067,7 +3069,9 @@ typedef void const char *conversion_url, const json_t *debit_restrictions, const json_t *credit_restrictions, - const struct TALER_MasterSignatureP *master_sig); + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority); /** @@ -5763,6 +5767,8 @@ struct TALER_EXCHANGEDB_Plugin * (only to be used for replay detection) * @param master_sig public signature affirming the existence of the account, * must be of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS + * @param bank_label label to show this entry under in the UI, can be NULL + * @param priority determines order in which entries are shown in the UI * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -5772,7 +5778,9 @@ struct TALER_EXCHANGEDB_Plugin const json_t *debit_restrictions, const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp start_date, - const struct TALER_MasterSignatureP *master_sig); + const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority); /** @@ -5786,6 +5794,8 @@ struct TALER_EXCHANGEDB_Plugin * @param change_date date when the account status was last changed * (only to be used for replay detection) * @param master_sig master signature to store, can be NULL (if @a enabled is false) + * @param bank_label label to show this entry under in the UI, can be NULL + * @param priority determines order in which entries are shown in the UI * @param enabled true to enable, false to disable (the actual change) * @return transaction status code */ @@ -5797,6 +5807,8 @@ struct TALER_EXCHANGEDB_Plugin const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp change_date, const struct TALER_MasterSignatureP *master_sig, + const char *bank_label, + int64_t priority, bool enabled); diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c index 417fdf357..bd731ad37 100644 --- a/src/lib/exchange_api_common.c +++ b/src/lib/exchange_api_common.c @@ -515,7 +515,9 @@ TALER_EXCHANGE_parse_accounts ( { struct TALER_EXCHANGE_WireAccount *wa = &was[i]; const char *payto_uri; - const char *conversion_url; + const char *conversion_url = NULL; + const char *bank_label = NULL; + int64_t priority = 0; const json_t *credit_restrictions; const json_t *debit_restrictions; struct GNUNET_JSON_Specification spec_account[] = { @@ -525,6 +527,14 @@ TALER_EXCHANGE_parse_accounts ( TALER_JSON_spec_web_url ("conversion_url", &conversion_url), NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_int64 ("priority", + &priority), + NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_string ("bank_label", + &bank_label), + NULL), GNUNET_JSON_spec_array_const ("credit_restrictions", &credit_restrictions), GNUNET_JSON_spec_array_const ("debit_restrictions", @@ -574,8 +584,11 @@ TALER_EXCHANGE_parse_accounts ( return GNUNET_SYSERR; } wa->payto_uri = GNUNET_strdup (payto_uri); + wa->priority = priority; if (NULL != conversion_url) wa->conversion_url = GNUNET_strdup (conversion_url); + if (NULL != bank_label) + wa->bank_label = GNUNET_strdup (bank_label); } /* end 'for all accounts */ return GNUNET_OK; } @@ -622,6 +635,7 @@ TALER_EXCHANGE_free_accounts ( GNUNET_free (wa->payto_uri); GNUNET_free (wa->conversion_url); + GNUNET_free (wa->bank_label); free_restrictions (wa->credit_restrictions_length, wa->credit_restrictions); GNUNET_array_grow (wa->credit_restrictions, diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index 306d2f261..bce3f2876 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -2320,6 +2320,11 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd) GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_string ("conversion_url", acc->conversion_url)), + GNUNET_JSON_pack_int64 ("priority", + acc->priority), + GNUNET_JSON_pack_allow_null ( + GNUNET_JSON_pack_string ("bank_label", + acc->bank_label)), GNUNET_JSON_pack_array_steal ("debit_restrictions", debit_restrictions), GNUNET_JSON_pack_array_steal ("credit_restrictions", -- cgit v1.2.3