diff options
author | Christian Blättler <blatc2@bfh.ch> | 2023-12-10 14:42:02 +0100 |
---|---|---|
committer | Christian Blättler <blatc2@bfh.ch> | 2023-12-10 14:42:02 +0100 |
commit | 62448125fbffb3bdd50fb5b5abc0d25e2449f8c6 (patch) | |
tree | 96a9381533384b1498eb642c5a9cbece52a385ce | |
parent | f99262923121d5c0e1b995e325d97830110f5ce5 (diff) | |
parent | cfdbc9a3c3fba99982beaf156794cb51494e0c3f (diff) | |
download | exchange-62448125fbffb3bdd50fb5b5abc0d25e2449f8c6.tar.xz |
Merge branch 'master' into feature/tokens
22 files changed, 291 insertions, 78 deletions
diff --git a/contrib/taler-exchange-dbconfig b/contrib/taler-exchange-dbconfig index c4790f823..eb90ee721 100755 --- a/contrib/taler-exchange-dbconfig +++ b/contrib/taler-exchange-dbconfig @@ -24,35 +24,25 @@ SKIP_DBINIT=0 FORCE_PERMS=0 DBUSER="taler-exchange-httpd" DBGROUP="taler-exchange-db" -DBNAME="exchange" CFGFILE="/etc/taler/taler.conf" -DBCFGFILE="/etc/taler/secrets/exchange-db.secret.conf" # Parse command-line options -while getopts 'c:d:g:hn:prsu:' OPTION; do +while getopts 'c:g:hprsu:' OPTION; do case "$OPTION" in c) CFGFILE="$OPTARG" ;; - d) - DBCFGFILE="$OPTARG" - ;; h) echo 'Supported options:' - echo " -c FILENAME -- write configuration to FILENAME (default: $CFGFILE)" - echo " -d FILENAME -- write database access configuration to FILENAME (default: $DBCFGFILE)" + echo " -c FILENAME -- use configuration FILENAME (default: $CFGFILE)" echo " -g GROUP -- taler-exchange to be run by GROUP (default: $DBGROUP)" echo " -h -- print this help text" - echo " -n NAME -- user NAME for database name (default: $DBNAME)" echo " -r -- reset database (dangerous)" echo " -p -- force permission setup even without database initialization" echo " -s -- skip database initialization" echo " -u USER -- taler-exchange to be run by USER (default: $DBUSER)" exit 0 ;; - n) - DBNAME="$OPTARG" - ;; p) FORCE_PERMS="1" ;; @@ -100,19 +90,6 @@ then exit 1 fi -if sudo -i -u postgres psql "$DBNAME" < /dev/null 2> /dev/null -then - if [ 1 = "$RESET_DB" ] - then - echo "Deleting existing database '$DBNAME'." 1>&2 - sudo -i -u postgres dropdb "$DBNAME" - else - echo "Database '$DBNAME' already exists, refusing to setup again." - echo "Use -r to delete the existing database first (dangerous!)." - exit 77 - fi -fi - echo "Setting up database user '$DBUSER'." 1>&2 if ! sudo -i -u postgres createuser "$DBUSER" 2> /dev/null @@ -120,32 +97,60 @@ then echo "Database user '$DBUSER' already existed. Continuing anyway." 1>&2 fi -echo "Creating database '$DBNAME'." 1>&2 +DBPATH=$(taler-config \ + -c "$CFGFILE" \ + -s exchangedb-postgres \ + -o CONFIG) -if ! sudo -i -u postgres createdb -O "$DBUSER" "$DBNAME" +if ! echo "$DBPATH" | grep "postgres://" > /dev/null then - echo "Failed to create database '$DBNAME'" + echo "Invalid database configuration value '$DBPATH'." 1>&2 exit 1 fi -if [ -f "$DBCFGFILE" ] +DBNAME=$(echo "$DBPATH" \ + | sed \ + -e "s/postgres:\/\/.*\///" \ + -e "s/?.*//") + +if sudo -i -u postgres psql "$DBNAME" < /dev/null 2> /dev/null then - echo "Adding database configuration to '$DBCFGFILE'." 1>&2 - echo -e "[exchangedb-postgres]\nCONFIG=postgres:///$DBNAME\n" >> "$DBCFGFILE" - chown root:"$DBGROUP" "$DBCFGFILE" - chmod 640 "$CFGFILE" + if [ 1 = "$RESET_DB" ] + then + echo "Deleting existing database '$DBNAME'." 1>&2 + if ! sudo -i -u postgres dropdb "$DBNAME" + then + echo "Failed to delete existing database '$DBNAME'" + exit 1 + fi + DO_CREATE=1 + else + echo "Database '$DBNAME' already exists, continuing anyway." + DO_CREATE=0 + fi else - echo "Configuration '$DBCFGFILE' does not yet exist, creating it." 1>&2 - mkdir -p "$(dirname "$DBCFGFILE")" - echo -e "[exchangedb-postgres]\nCONFIG=postgres:///$DBNAME\n" >> "$CFGFILE" - chown root:"$DBGROUP" "$DBCFGFILE" - chmod 640 "$DBCFGFILE" + DO_CREATE=1 +fi + +if [ 1 = "$DO_CREATE" ] +then + echo "Creating database '$DBNAME'." 1>&2 + + if ! sudo -i -u postgres createdb -O "$DBUSER" "$DBNAME" + then + echo "Failed to create database '$DBNAME'" + exit 1 + fi fi if [ 0 = "$SKIP_DBINIT" ] then echo "Initializing database '$DBNAME'." 1>&2 - sudo -u "$DBUSER" "$DBINIT" -c "$CFGFILE" + if ! sudo -u "$DBUSER" "$DBINIT" -c "$CFGFILE" + then + echo "Failed to initialize database schema" + exit 1 + fi fi if [ 0 = "$SKIP_DBINIT" ] || [ 1 = "$FORCE_PERMS" ] @@ -156,16 +161,26 @@ then do if [ "$GROUPIE" != "$DBUSER" ] then - sudo -u "$DBUSER" \ - echo -e 'GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA exchange TO "'"$GROUPIE"'";\n' \ - 'GRANT USAGE ON ALL SEQUENCES IN SCHEMA exchange TO "'"$GROUPIE"'";\n' \ - | psql taler-exchange + if ! sudo -i -u postgres createuser "$GROUPIE" 2> /dev/null + then + echo "Database user '$GROUPIE' already existed. Continuing anyway." 1>&2 + fi + echo -e 'GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA exchange TO "'"$GROUPIE"'";\n' \ + 'GRANT USAGE ON ALL SEQUENCES IN SCHEMA exchange TO "'"$GROUPIE"'";\n' \ + | sudo -u "$DBUSER" psql "$DBNAME" + echo -e 'GRANT USAGE ON SCHEMA exchange TO "'"$GROUPIE"'"' \ + | sudo -u "$DBUSER" psql "$DBNAME" + # FIXME: double-check the following GRANTs + echo -e 'GRANT USAGE ON SCHEMA _v TO "'"$GROUPIE"'"' \ + | sudo -u "$DBUSER" psql "$DBNAME" + echo -e 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA _v TO "'"$GROUPIE"'"' \ + | sudo -u "$DBUSER" psql "$DBNAME" + + fi done fi - - echo "Database configuration finished." 1>&2 exit 0 diff --git a/debian/changelog b/debian/changelog index c147a0d52..264e99bfc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +taler-exchange (0.9.3-5) unstable; urgency=low + + * More fixes to the database setup automation scripts. + * Implement latest /config API in fakebank. + + -- Christian Grothoff <grothoff@gnu.org> Thu, 7 Dec 2023 00:50:12 -0800 + taler-exchange (0.9.3-4) unstable; urgency=low * Minor hot-fixes to the database setup automation script. diff --git a/debian/control b/debian/control index 80ebebe69..fe80f9cf8 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,7 @@ Build-Depends: gcc-12, debhelper-compat (= 12), gettext, - libgnunet-dev (>=0.20), + libgnunet-dev (>=0.21), libcurl4-gnutls-dev (>=7.35.0) | libcurl4-openssl-dev (>= 7.35.0), libgcrypt20-dev (>=1.8), libgnutls28-dev (>=3.2.12), @@ -146,7 +146,7 @@ Section: libdevel Architecture: any Depends: libtalerexchange (= ${binary:Version}), - libgnunet-dev (>=0.20), + libgnunet-dev (>=0.21), libgcrypt20-dev (>=1.8), libmicrohttpd-dev (>=0.9.71), ${misc:Depends}, diff --git a/debian/libtalerexchange.postinst b/debian/libtalerexchange.postinst new file mode 100644 index 000000000..40b4be061 --- /dev/null +++ b/debian/libtalerexchange.postinst @@ -0,0 +1,28 @@ +#!/bin/bash + +set -e + +. /usr/share/debconf/confmodule + +case "${1}" in +configure) + + if ! dpkg-statoverride --list /etc/taler/taler.conf >/dev/null 2>&1; then + dpkg-statoverride --add --update \ + root root 644 \ + /etc/taler/taler.conf + fi + + ;; + +abort-upgrade | abort-remove | abort-deconfigure) ;; + +*) + echo "postinst called with unknown argument \`${1}'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/src/bank-lib/fakebank_tbi.c b/src/bank-lib/fakebank_tbi.c index 27b930d9f..95e3a8c2e 100644 --- a/src/bank-lib/fakebank_tbi.c +++ b/src/bank-lib/fakebank_tbi.c @@ -49,6 +49,11 @@ TALER_FAKEBANK_tbi_main_ (struct TALER_FAKEBANK_Handle *h, (0 == strcasecmp (method, MHD_HTTP_METHOD_GET)) ) { + struct TALER_Amount zero; + + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (h->currency, + &zero)); return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_OK, @@ -56,6 +61,40 @@ TALER_FAKEBANK_tbi_main_ (struct TALER_FAKEBANK_Handle *h, "0:0:0"), GNUNET_JSON_pack_string ("currency", h->currency), + GNUNET_JSON_pack_bool ("allow_conversion", + false), + GNUNET_JSON_pack_bool ("allow_registrations", + true), + GNUNET_JSON_pack_bool ("allow_deletions", + false), + GNUNET_JSON_pack_bool ("allow_edit_name", + false), + GNUNET_JSON_pack_bool ("allow_edit_cashout_payto_uri", + false), + TALER_JSON_pack_amount ("default_debit_threshold", + &zero), + GNUNET_JSON_pack_array_steal ("supported_tan_channels", + json_array ()), + GNUNET_JSON_pack_object_steal ( + "currency_specification", + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("name", + h->currency), + GNUNET_JSON_pack_string ("currency", + h->currency), + GNUNET_JSON_pack_uint64 ("num_fractional_input_digits", + 2), + GNUNET_JSON_pack_uint64 ("num_fractional_normal_digits", + 2), + GNUNET_JSON_pack_uint64 ("num_fractional_trailing_zero_digits", + 2), + GNUNET_JSON_pack_object_steal ( + "alt_unit_names", + GNUNET_JSON_PACK ( + GNUNET_JSON_pack_string ("0", + h->currency))), + GNUNET_JSON_pack_string ("name", + h->currency))), GNUNET_JSON_pack_string ("name", "taler-bank-integration")); } diff --git a/src/bank-lib/fakebank_tbr_get_history.c b/src/bank-lib/fakebank_tbr_get_history.c index e81e00894..79678636a 100644 --- a/src/bank-lib/fakebank_tbr_get_history.c +++ b/src/bank-lib/fakebank_tbr_get_history.c @@ -149,6 +149,7 @@ TALER_FAKEBANK_tbr_get_history_incoming ( if (GNUNET_TIME_relative_is_zero (hc->ha.lp_timeout) && (0 < hc->ha.delta)) { + acc_payto_uri = hc->acc->payto_uri; GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); if (overflow) @@ -160,6 +161,7 @@ TALER_FAKEBANK_tbr_get_history_incoming ( } if (h->in_shutdown) { + acc_payto_uri = hc->acc->payto_uri; GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); goto finish; diff --git a/src/bank-lib/fakebank_twg_history.c b/src/bank-lib/fakebank_twg_history.c index 1d70ed127..35cc6587f 100644 --- a/src/bank-lib/fakebank_twg_history.c +++ b/src/bank-lib/fakebank_twg_history.c @@ -147,6 +147,7 @@ TALER_FAKEBANK_twg_get_debit_history_ ( if ( (GNUNET_TIME_relative_is_zero (hc->ha.lp_timeout)) && (0 < hc->ha.delta)) { + acc_payto_uri = hc->acc->payto_uri; GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); if (overflow) @@ -160,6 +161,7 @@ TALER_FAKEBANK_twg_get_debit_history_ ( } if (h->in_shutdown) { + acc_payto_uri = hc->acc->payto_uri; GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); goto finish; @@ -400,6 +402,7 @@ TALER_FAKEBANK_twg_get_credit_history_ ( if (GNUNET_TIME_relative_is_zero (hc->ha.lp_timeout) && (0 < hc->ha.delta)) { + acc_payto_uri = hc->acc->payto_uri; GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); if (overflow) @@ -411,6 +414,7 @@ TALER_FAKEBANK_twg_get_credit_history_ ( } if (h->in_shutdown) { + acc_payto_uri = hc->acc->payto_uri; GNUNET_assert (0 == pthread_mutex_unlock (&h->big_lock)); goto finish; diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c index 9f66a99a4..835a974fc 100644 --- a/src/exchange/taler-exchange-httpd_batch-deposit.c +++ b/src/exchange/taler-exchange-httpd_batch-deposit.c @@ -60,16 +60,24 @@ struct BatchDepositContext */ struct TALER_EXCHANGEDB_BatchDeposit bd; + /** - * Additional details for policy extension relevant for this - * deposit operation, possibly NULL! + * Total amount that is accumulated with this deposit, + * without fee. */ - json_t *policy_json; + struct TALER_Amount accumulated_total_without_fee; /** - * Hash over the merchant's payto://-URI with the wire salt. + * True, if no policy was present in the request. Then + * @e policy_json is NULL and @e h_policy will be all zero. */ - struct TALER_MerchantWireHashP h_wire; + bool has_no_policy; + + /** + * Additional details for policy extension relevant for this + * deposit operation, possibly NULL! + */ + json_t *policy_json; /** * If @e policy_json was present, the corresponding policy extension @@ -84,6 +92,11 @@ struct BatchDepositContext struct TALER_ExtensionPolicyHashP h_policy; /** + * Hash over the merchant's payto://-URI with the wire salt. + */ + struct TALER_MerchantWireHashP h_wire; + + /** * When @e policy_details are persisted, this contains the id of the record * in the policy_details table. */ @@ -121,11 +134,11 @@ reply_batch_deposit_success ( &TEH_keys_exchange_sign_, &bd->h_contract_terms, &dc->h_wire, - NULL != dc->policy_json ? &dc->h_policy : NULL, + dc->has_no_policy ? NULL : &dc->h_policy, dc->exchange_timestamp, bd->wire_deadline, bd->refund_deadline, - &dc->policy_details.accumulated_total, /* excludes fees */ + &dc->accumulated_total_without_fee, bd->num_cdis, csigs, &dc->bd.merchant_pub, @@ -176,13 +189,13 @@ batch_deposit_transaction (void *cls, /* If the deposit has a policy associated to it, persist it. This will * insert or update the record. */ - if (NULL != dc->policy_json) + if (! dc->has_no_policy) { qs = TEH_plugin->persist_policy_details ( TEH_plugin->cls, &dc->policy_details, &dc->bd.policy_details_serial_id, - &dc->policy_details.accumulated_total, + &dc->accumulated_total_without_fee, &dc->policy_details.fulfillment_state); if (qs < 0) return qs; @@ -237,13 +250,13 @@ batch_deposit_transaction (void *cls, in_conflict ? "in conflict" : "no conflict"); if (in_conflict) { - /* FIXME: #7267 conflicting contract != insufficient funds */ + /* FIXME: #8002 conflicting contract != insufficient funds */ *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds ( connection, TALER_EC_EXCHANGE_DEPOSIT_CONFLICTING_CONTRACT, - &bd->cdis[0 /* SEE FIXME-#7267 Oec above! */].coin.denom_pub_hash, - &bd->cdis[0 /* SEE FIXME-#7267 Oec above! */].coin.coin_pub); + &bd->cdis[0 /* SEE FIXME-#8002 Oec above! */].coin.denom_pub_hash, + &bd->cdis[0 /* SEE FIXME-#8002 Oec above! */].coin.coin_pub); return GNUNET_DB_STATUS_HARD_ERROR; } if (! balance_ok) @@ -495,7 +508,7 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_json ("policy", &dc.policy_json), - NULL), + &dc.has_no_policy), GNUNET_JSON_spec_timestamp ("timestamp", &bd->wallet_timestamp), GNUNET_JSON_spec_mark_optional ( @@ -571,8 +584,12 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, &bd->wire_salt, &dc.h_wire); + GNUNET_assert (GNUNET_OK == + TALER_amount_set_zero (TEH_currency, + &dc.accumulated_total_without_fee)); + /* handle policy, if present */ - if (NULL != dc.policy_json) + if (! dc.has_no_policy) { const char *error_hint = NULL; @@ -641,10 +658,11 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, &amount_without_fee, &cdis[i].amount_with_fee, &deposit_fees[i])); + GNUNET_assert (0 <= TALER_amount_add ( - &dc.policy_details.accumulated_total, - &dc.policy_details.accumulated_total, + &dc.accumulated_total_without_fee, + &dc.accumulated_total_without_fee, &amount_without_fee)); } if (GNUNET_OK != res) diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 5660074ee..a00a97856 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -37,14 +37,14 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin, { enum TALER_EXCHANGEDB_CoinKnownStatus cks; struct TALER_DenominationHashP h_denom_pub; - struct TALER_AgeCommitmentHash age_hash; + struct TALER_AgeCommitmentHash h_age_commitment; /* make sure coin is 'known' in database */ cks = TEH_plugin->ensure_coin_known (TEH_plugin->cls, coin, known_coin_id, &h_denom_pub, - &age_hash); + &h_age_commitment); switch (cks) { case TALER_EXCHANGEDB_CKS_ADDED: @@ -70,13 +70,12 @@ TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin, &coin->coin_pub); return GNUNET_DB_STATUS_HARD_ERROR; case TALER_EXCHANGEDB_CKS_AGE_CONFLICT: - /* FIXME: insufficient_funds != Age conflict! See issue #7267, need new - * strategy for evidence gathering */ - *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds ( + *mhd_ret = TEH_RESPONSE_reply_coin_age_commitment_conflict ( connection, TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_AGE_HASH, &h_denom_pub, - &coin->coin_pub); + &coin->coin_pub, + &h_age_commitment); return GNUNET_DB_STATUS_HARD_ERROR; } GNUNET_assert (0); diff --git a/src/exchange/taler-exchange-httpd_extensions.c b/src/exchange/taler-exchange-httpd_extensions.c index dd0fada76..d62a618ae 100644 --- a/src/exchange/taler-exchange-httpd_extensions.c +++ b/src/exchange/taler-exchange-httpd_extensions.c @@ -23,6 +23,7 @@ #include "taler-exchange-httpd_keys.h" #include "taler-exchange-httpd_responses.h" #include "taler-exchange-httpd_extensions.h" +#include "taler_extensions_policy.h" #include "taler_json_lib.h" #include "taler_mhd_lib.h" #include "taler_extensions.h" @@ -256,11 +257,16 @@ policy_fulfillment_transaction ( { struct TALER_PolicyFulfillmentTransactionData *fulfillment = cls; + /* FIXME[oec]: use connection and mhd_ret? */ + (void) connection; + (void) mhd_ret; + return TEH_plugin->add_policy_fulfillment_proof (TEH_plugin->cls, fulfillment); } +/* FIXME[oec]-#7999: In this handler: do we transition correctly between states? */ MHD_RESULT TEH_extensions_post_handler ( struct TEH_RequestContext *rc, @@ -338,14 +344,48 @@ TEH_extensions_post_handler ( qs = TEH_plugin->get_policy_details (TEH_plugin->cls, &hcs[idx], &policy_details[idx]); - if (qs < 0) + if (0 > qs) + { + GNUNET_free (hcs); + GNUNET_free (policy_details); + return TALER_MHD_reply_with_error (rc->connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN, + "a policy_hash_code couldn't be found"); + } + + /* We proceed according to the state of fulfillment */ + switch (policy_details[idx].fulfillment_state) { - error_msg = "a policy_hash_code couldn't be found"; + case TALER_PolicyFulfillmentReady: + break; + case TALER_PolicyFulfillmentInsufficient: + error_msg = "a policy is not yet fully funded"; + ret = GNUNET_SYSERR; + break; + case TALER_PolicyFulfillmentTimeout: + error_msg = "a policy is has already timed out"; + ret = GNUNET_SYSERR; break; + case TALER_PolicyFulfillmentSuccess: + /* FIXME[oec]-#8001: Idempotency handling. */ + GNUNET_break (0); + break; + case TALER_PolicyFulfillmentFailure: + /* FIXME[oec]-#7999: What to do in the failure case? */ + GNUNET_break (0); + break; + default: + /* Unknown state */ + GNUNET_assert (0); } + + if (GNUNET_OK != ret) + break; } GNUNET_free (hcs); + if (GNUNET_OK != ret) { GNUNET_free (policy_details); diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 322da3877..c1aa9db6f 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -178,6 +178,28 @@ TEH_RESPONSE_reply_coin_insufficient_funds ( MHD_RESULT +TEH_RESPONSE_reply_coin_age_commitment_conflict ( + struct MHD_Connection *connection, + enum TALER_ErrorCode ec, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_AgeCommitmentHash *h_age_commitment_hash) +{ + return TALER_MHD_REPLY_JSON_PACK ( + connection, + TALER_ErrorCode_get_http_status_safe (ec), + TALER_JSON_pack_ec (ec), + GNUNET_JSON_pack_data_auto ("coin_pub", + coin_pub), + GNUNET_JSON_pack_data_auto ("h_denom_pub", + h_denom_pub), + GNUNET_JSON_pack_data_auto ("h_age_commitment_hash", + h_age_commitment_hash) + ); +} + + +MHD_RESULT TEH_RESPONSE_reply_reserve_insufficient_balance ( struct MHD_Connection *connection, enum TALER_ErrorCode ec, diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h index 8adf1136b..5fe106e17 100644 --- a/src/exchange/taler-exchange-httpd_responses.h +++ b/src/exchange/taler-exchange-httpd_responses.h @@ -160,6 +160,27 @@ TEH_RESPONSE_reply_coin_insufficient_funds ( const struct TALER_CoinSpendPublicKeyP *coin_pub); /** + * Send proof that a request is invalid to client because of + * a conflicting value for the age commitment hash of a coin. + * This function will create a message with the conflicting + * hash value for the age commitment of the given coin. + * + * @param connection connection to the client + * @param ec error code to return + * @param h_denom_pub hash of the denomination of the coin + * @param coin_pub public key of the coin + * @param h_age_commitment hash of the age commitment as found in the database + * @return MHD result code + */ +MHD_RESULT +TEH_RESPONSE_reply_coin_age_commitment_conflict ( + struct MHD_Connection *connection, + enum TALER_ErrorCode ec, + const struct TALER_DenominationHashP *h_denom_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_AgeCommitmentHash *h_age_commitment); + +/** * Fundamental details about a purse. */ struct TEH_PurseDetails diff --git a/src/exchangedb/exchange_do_deposit.sql b/src/exchangedb/exchange_do_deposit.sql index 1156c7de5..7116117ff 100644 --- a/src/exchangedb/exchange_do_deposit.sql +++ b/src/exchangedb/exchange_do_deposit.sql @@ -142,6 +142,7 @@ THEN IF NOT FOUND THEN -- Deposit exists, but with *strange* differences. Not allowed. + -- FIXME #8002: Surely we need to provide the client more data in this case. out_conflict=TRUE; RETURN; END IF; diff --git a/src/exchangedb/exchange_do_insert_or_update_policy_details.sql b/src/exchangedb/exchange_do_insert_or_update_policy_details.sql index 53cd2989e..85e52d3d3 100644 --- a/src/exchangedb/exchange_do_insert_or_update_policy_details.sql +++ b/src/exchangedb/exchange_do_insert_or_update_policy_details.sql @@ -93,14 +93,14 @@ BEGIN -- Set the fulfillment_state according to the values. -- For now, we only update the state when it was INSUFFICIENT. - -- FIXME: What to do in case of Failure or other state? - IF (out_fullfillment_state = 1) -- INSUFFICIENT + -- FIXME[oec] #7999: What to do in case of Failure or other state? + IF (out_fullfillment_state = 2) -- INSUFFICIENT THEN IF (out_accumulated_total.val >= cur_commitment.val OR (out_accumulated_total.val = cur_commitment.val AND out_accumulated_total.frac >= cur_commitment.frac)) THEN - out_fulfillment_state = 2; -- READY + out_fulfillment_state = 3; -- READY END IF; END IF; diff --git a/src/exchangedb/pg_add_policy_fulfillment_proof.c b/src/exchangedb/pg_add_policy_fulfillment_proof.c index 0fd6b1c92..93d070712 100644 --- a/src/exchangedb/pg_add_policy_fulfillment_proof.c +++ b/src/exchangedb/pg_add_policy_fulfillment_proof.c @@ -55,6 +55,7 @@ TEH_PG_add_policy_fulfillment_proof ( enum GNUNET_DB_QueryStatus qs; struct PostgresClosure *pg = cls; size_t count = fulfillment->details_count; + /* FIXME: this seems to be prone to VLA attacks */ struct GNUNET_HashCode hcs[count]; /* Create the sorted policy_hash_codes */ @@ -84,8 +85,7 @@ TEH_PG_add_policy_fulfillment_proof ( GNUNET_PQ_query_param_timestamp (&fulfillment->timestamp), TALER_PQ_query_param_json (fulfillment->proof), GNUNET_PQ_query_param_auto_from_type (&fulfillment->h_proof), - GNUNET_PQ_query_param_fixed_size (hcs, - count * sizeof(struct GNUNET_HashCode)), + TALER_PQ_query_param_array_hash_code (count, hcs, pg->conn), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { @@ -132,7 +132,6 @@ TEH_PG_add_policy_fulfillment_proof ( GNUNET_PQ_query_param_end }; - // FIXME-Oec: review if this is the intended logic here! PREPARE (pg, "update_policy_details", "UPDATE policy_details SET" @@ -151,5 +150,10 @@ TEH_PG_add_policy_fulfillment_proof ( } } + /* + * FIXME[oec]-#7999: When all policies of a deposit are fulfilled, + * unblock it and trigger a wire-transfer. + */ + return qs; } diff --git a/src/exchangedb/pg_do_deposit.c b/src/exchangedb/pg_do_deposit.c index 0ba45b628..64e7886a7 100644 --- a/src/exchangedb/pg_do_deposit.c +++ b/src/exchangedb/pg_do_deposit.c @@ -83,6 +83,7 @@ TEH_PG_do_deposit ( GNUNET_PQ_result_spec_uint32 ("insufficient_balance_coin_index", bad_balance_index), balance_ok), + /* FIXME #8002: We need more data to communicate the conflict to the client */ GNUNET_PQ_result_spec_bool ("conflicted", ctr_conflict), GNUNET_PQ_result_spec_end diff --git a/src/include/taler_extensions_policy.h b/src/include/taler_extensions_policy.h index 7750f58f1..b10c0d8a2 100644 --- a/src/include/taler_extensions_policy.h +++ b/src/include/taler_extensions_policy.h @@ -28,6 +28,8 @@ /* * @brief Describes the states of fulfillment of a policy bound to a deposit + * NOTE: These values must be in sync with their use in stored procedures, f.e. + * exchange_do_insert_or_update_policy_details. */ enum TALER_PolicyFulfillmentState { diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am index d43d4a6c1..fae865bad 100644 --- a/src/kyclogic/Makefile.am +++ b/src/kyclogic/Makefile.am @@ -78,6 +78,7 @@ libtaler_plugin_kyclogic_template_la_LIBADD = \ $(LTLIBINTL) libtaler_plugin_kyclogic_template_la_LDFLAGS = \ $(TALER_PLUGIN_LDFLAGS) \ + -lgnunetcurl \ -lgnunetutil \ $(XLIB) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 230dfba21..1291fd3a4 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -87,6 +87,7 @@ libtalerexchange_la_LIBADD = \ -lgnunetjson \ -lgnunetutil \ -ljansson \ + -lm \ $(LIBGNURLCURL_LIBS) \ $(XLIB) diff --git a/src/testing/taler-unified-setup.sh b/src/testing/taler-unified-setup.sh index 479a125fa..958421666 100755 --- a/src/testing/taler-unified-setup.sh +++ b/src/testing/taler-unified-setup.sh @@ -329,6 +329,12 @@ then -c "$CONF" \ "$AUSER" "$APASS" \ &> libeufin-bank-passwd.log + libeufin-bank \ + edit-account \ + -c "$CONF" \ + --debit_threshold="$CURRENCY:1000000" \ + "$AUSER" \ + &> libeufin-bank-debit-threshold.log echo " OK" fi diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 4ebd6397c..2a0304e03 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -115,6 +115,7 @@ libtalerutil_la_LIBADD = \ -ljansson \ $(LIBGCRYPT_LIBS) \ -lmicrohttpd $(XLIB) \ + -lunistring \ -lz \ -lm diff --git a/src/util/exchange_signatures.c b/src/util/exchange_signatures.c index bc5fe439f..aaefb5cec 100644 --- a/src/util/exchange_signatures.c +++ b/src/util/exchange_signatures.c @@ -120,7 +120,8 @@ TALER_exchange_online_deposit_confirmation_sign ( .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp), .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline), .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline), - .merchant_pub = *merchant_pub + .merchant_pub = *merchant_pub, + .h_policy = {{{0}}} }; struct GNUNET_HashContext *hc; |