From 6b434c626f6335f8174e0164ead61b3874752c4a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 29 Nov 2020 16:21:10 +0100 Subject: work on DB logic, add auditor_name to /management/auditors API --- .../taler-exchange-httpd_management_auditors.c | 13 +- ...exchange-httpd_management_auditors_AP_disable.c | 13 +- src/exchangedb/exchange-0002.sql | 1 - src/exchangedb/plugin_exchangedb_postgres.c | 469 ++++++++++++++++++++- src/include/taler_exchange_service.h | 2 + src/include/taler_exchangedb_plugin.h | 10 +- src/lib/exchange_api_management_auditor_enable.c | 7 +- src/testing/testing_api_cmd_auditor_add.c | 1 + 8 files changed, 496 insertions(+), 20 deletions(-) diff --git a/src/exchange/taler-exchange-httpd_management_auditors.c b/src/exchange/taler-exchange-httpd_management_auditors.c index adfe94d91..c794c9879 100644 --- a/src/exchange/taler-exchange-httpd_management_auditors.c +++ b/src/exchange/taler-exchange-httpd_management_auditors.c @@ -50,6 +50,11 @@ struct AddAuditorContext */ const char *auditor_url; + /** + * Human readable name of the auditor. + */ + const char *auditor_name; + /** * Timestamp for checking against replay attacks. */ @@ -112,15 +117,15 @@ add_auditor (void *cls, session, &aac->auditor_pub, aac->auditor_url, - aac->validity_start, - &aac->master_sig); + aac->auditor_name, + aac->validity_start); else qs = TEH_plugin->update_auditor (TEH_plugin->cls, session, &aac->auditor_pub, aac->auditor_url, + aac->auditor_name, aac->validity_start, - &aac->master_sig, true); if (qs < 0) { @@ -159,6 +164,8 @@ TEH_handler_management_auditors ( &aac.auditor_pub), GNUNET_JSON_spec_string ("auditor_url", &aac.auditor_url), + GNUNET_JSON_spec_string ("auditor_name", + &aac.auditor_name), TALER_JSON_spec_absolute_time ("validity_start", &aac.validity_start), GNUNET_JSON_spec_end () diff --git a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c index 60f0f5398..0a1d2c54d 100644 --- a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c +++ b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c @@ -35,10 +35,6 @@ */ struct DelAuditorContext { - /** - * Master signature to store. - */ - struct TALER_MasterSignatureP master_sig; /** * Auditor public key this is about. @@ -119,9 +115,9 @@ del_auditor (void *cls, qs = TEH_plugin->update_auditor (TEH_plugin->cls, session, &dac->auditor_pub, - "", + "", /* auditor URL */ + "", /* auditor name */ dac->validity_end, - &dac->master_sig, false); if (qs < 0) { @@ -152,10 +148,11 @@ TEH_handler_management_auditors_AP_disable ( const struct GNUNET_HashCode *h_denom_pub, const json_t *root) { + struct TALER_MasterSignatureP master_sig; struct DelAuditorContext dac; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("master_sig", - &dac.master_sig), + &master_sig), GNUNET_JSON_spec_fixed_auto ("auditor_pub", &dac.auditor_pub), TALER_JSON_spec_absolute_time ("validity_end", @@ -189,7 +186,7 @@ TEH_handler_management_auditors_AP_disable ( GNUNET_CRYPTO_eddsa_verify ( TALER_SIGNATURE_MASTER_DEL_AUDITOR, &da, - &dac.master_sig.eddsa_signature, + &master_sig.eddsa_signature, &TEH_master_public_key.eddsa_pub)) { GNUNET_break_op (0); diff --git a/src/exchangedb/exchange-0002.sql b/src/exchangedb/exchange-0002.sql index 21b8adc7a..2162c45ef 100644 --- a/src/exchangedb/exchange-0002.sql +++ b/src/exchangedb/exchange-0002.sql @@ -132,7 +132,6 @@ COMMENT ON COLUMN exchange_sign_keys.legal_end CREATE TABLE IF NOT EXISTS wire_accounts (payto_uri VARCHAR PRIMARY KEY - ,master_pub BYTEA NOT NULL CHECK (LENGTH(master_pub)=32) ,master_sig BYTEA CHECK (LENGTH(master_sig)=64) ,is_active BOOLEAN NOT NULL ,last_change INT8 NOT NULL diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 74d4f92ae..843d3901e 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -1397,6 +1397,68 @@ postgres_get_session (void *cls) " WHERE h_coin_ev=$1" " LIMIT 1;", 1), + /* Used in #postgres_lookup_auditor_timestamp() */ + GNUNET_PQ_make_prepare ("lookup_auditor_timestamp", + "SELECT" + " last_change" + " FROM auditors" + " WHERE auditor_pub=$1;", + 1), + /* Used in #postgres_lookup_auditor_status() */ + GNUNET_PQ_make_prepare ("lookup_auditor_status", + "SELECT" + " auditor_url" + ",is_active" + " FROM auditors" + " WHERE auditor_pub=$1;", + 1), + + /* Used in #postgres_lookup_wire_timestamp() */ + GNUNET_PQ_make_prepare ("lookup_wire_timestamp", + "SELECT" + " last_change" + " FROM wire_accounts" + " WHERE payto_uri=$1;", + 1), + /* used in #postgres_insert_auditor() */ + GNUNET_PQ_make_prepare ("insert_auditor", + "INSERT INTO auditors " + "(auditor_pub" + ",auditor_name" + ",auditor_url" + ",is_active" + ",last_change" + ") VALUES " + "($1, $2, $3, true, $4);", + 4), + /* used in #postgres_update_auditor() */ + GNUNET_PQ_make_prepare ("update_auditor", + "UPDATE auditors" + " SET" + " auditor_url=$2" + " ,auditor_name=$3" + " ,is_active=$4" + " ,last_change=$5" + " WHERE auditor_pub=$1", + 5), + /* used in #postgres_insert_wire() */ + GNUNET_PQ_make_prepare ("insert_wire", + "INSERT INTO wire_accounts " + "(payto_uri" + ",master_sig" + ",is_active" + ",last_change" + ") VALUES " + "($1, $2, true, $3);", + 3), + /* used in #postgres_update_wire() */ + GNUNET_PQ_make_prepare ("update_wire", + "UPDATE wire_accounts" + " SET" + " is_active=$2" + " ,last_change=$3" + " WHERE payto_uri=$1", + 3), /* used in #postgres_commit */ GNUNET_PQ_make_prepare ("do_commit", "COMMIT", @@ -7301,6 +7363,398 @@ postgres_select_deposits_missing_wire (void *cls, } +/** + * Check the last date an auditor was modified. + * + * @param cls closure + * @param session a session + * @param auditor_pub key to look up information for + * @param[out] last_date last modification date to auditor status + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_lookup_auditor_timestamp ( + void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct TALER_AuditorPublicKeyP *auditor_pub, + struct GNUNET_TIME_Absolute *last_date) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (auditor_pub), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_absolute_time ("last_change", + last_date), + GNUNET_PQ_result_spec_end + }; + + (void) cls; + return GNUNET_PQ_eval_prepared_singleton_select (session->conn, + "lookup_auditor_timestamp", + params, + rs); +} + + +/** + * Lookup current state of an auditor. + * + * @param cls closure + * @param session a session + * @param auditor_pub key to look up information for + * @param[out] set to the base URL of the auditor's REST API; memory to be + * released by the caller! + * @param[out] enabled set if the auditor is currently in use + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_lookup_auditor_status (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct + TALER_AuditorPublicKeyP *auditor_pub, + char **auditor_url, + bool *enabled) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (auditor_pub), + GNUNET_PQ_query_param_end + }; + uint8_t enabled8 = 0; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_string ("auditor_url", + auditor_url), + GNUNET_PQ_result_spec_auto_from_type ("is_active", + &enabled8), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + (void) cls; + qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn, + "lookup_auditor_status", + params, + rs); + *enabled = (0 != enabled8); + return qs; +} + + +/** + * Insert information about an auditor that will audit this exchange. + * + * @param cls closure + * @param session a session + * @param auditor_pub key of the auditor + * @param auditor_url base URL of the auditor's REST service + * @param auditor_name name of the auditor (for humans) + * @param start_date date when the auditor was added by the offline system + * (only to be used for replay detection) + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_insert_auditor (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const char *auditor_url, + const char *auditor_name, + struct GNUNET_TIME_Absolute start_date) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (auditor_pub), + GNUNET_PQ_query_param_string (auditor_url), + GNUNET_PQ_query_param_string (auditor_name), + GNUNET_PQ_query_param_absolute_time (&start_date), + GNUNET_PQ_query_param_end + }; + + (void) cls; + return GNUNET_PQ_eval_prepared_non_select (session->conn, + "insert_auditor", + params); +} + + +/** + * Update information about an auditor that will audit this exchange. + * + * @param cls closure + * @param session a session + * @param auditor_pub key of the auditor (primary key for the existing record) + * @param auditor_url base URL of the auditor's REST service, to be updated + * @param auditor_name name of the auditor (for humans) + * @param change_date date when the auditor status was last changed + * (only to be used for replay detection) + * @param enabled true to enable, false to disable + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_update_auditor (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const char *auditor_url, + const char *auditor_name, + struct GNUNET_TIME_Absolute change_date, + bool enabled) +{ + uint8_t enabled8 = enabled ? 1 : 0; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (auditor_pub), + GNUNET_PQ_query_param_string (auditor_url), + GNUNET_PQ_query_param_string (auditor_name), + GNUNET_PQ_query_param_auto_from_type (&enabled8), + GNUNET_PQ_query_param_absolute_time (&change_date), + GNUNET_PQ_query_param_end + }; + + (void) cls; + return GNUNET_PQ_eval_prepared_non_select (session->conn, + "update_auditor", + params); +} + + +/** + * Check the last date an exchange wire account was modified. + * + * @param cls closure + * @param session a session + * @param payto_uri key to look up information for + * @param[out] last_date last modification date to auditor status + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_lookup_wire_timestamp (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const char *payto_uri, + struct GNUNET_TIME_Absolute *last_date) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (payto_uri), + GNUNET_PQ_query_param_end + }; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_absolute_time ("last_change", + last_date), + GNUNET_PQ_result_spec_end + }; + + (void) cls; + return GNUNET_PQ_eval_prepared_singleton_select (session->conn, + "lookup_wire_timestamp", + params, + rs); +} + + +/** + * Insert information about an wire account used by this exchange. + * + * @param cls closure + * @param session a session + * @param payto_uri wire account of the exchange + * @param start_date date when the account was added by the offline system + * (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 + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_insert_wire (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const char *payto_uri, + struct GNUNET_TIME_Absolute start_date, + const struct TALER_MasterSignatureP *master_sig) +{ + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (payto_uri), + GNUNET_PQ_query_param_absolute_time (&start_date), + GNUNET_PQ_query_param_auto_from_type (master_sig), + GNUNET_PQ_query_param_end + }; + + (void) cls; + return GNUNET_PQ_eval_prepared_non_select (session->conn, + "insert_wire", + params); +} + + +/** + * Update information about a wire account of the exchange. + * + * @param cls closure + * @param session a session + * @param payto_uri account the update is about + * @param change_date date when the account status was last changed + * (only to be used for replay detection) + * @param enabled true to enable, false to disable (the actual change) + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_update_wire (void *cls, + struct TALER_EXCHANGEDB_Session *session, + const char *payto_uri, + struct GNUNET_TIME_Absolute change_date, + bool enabled) +{ + uint8_t enabled8 = enabled ? 1 : 0; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (payto_uri), + GNUNET_PQ_query_param_auto_from_type (&enabled8), + GNUNET_PQ_query_param_absolute_time (&change_date), + GNUNET_PQ_query_param_end + }; + + (void) cls; + return GNUNET_PQ_eval_prepared_non_select (session->conn, + "update_wire", + params); +} + + +/** + * Store information about a revoked online signing key. + * + * @param cls closure + * @param session a session (can be NULL) + * @param exchange_pub exchange online signing key that was revoked + * @param master_sig signature affirming the revocation + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_insert_signkey_revocation ( + void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct TALER_ExchangePublicKeyP *exchange_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + GNUNET_break (0); // FIXME: not implemented + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Lookup information about a future denomination key. + * + * @param cls closure + * @param session a session + * @param h_denom_pub hash of the denomination public key + * @param[out] meta set to various meta data about the key + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_lookup_future_denomination_key ( + void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct GNUNET_HashCode *h_denom_pub, + const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta) +{ + GNUNET_break (0); // FIXME: not implemented + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Lookup information about current denomination key. + * + * @param cls closure + * @param session a session + * @param h_denom_pub hash of the denomination public key + * @param[out] meta set to various meta data about the key + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_lookup_denomination_key ( + void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct GNUNET_HashCode *h_denom_pub, + const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta) +{ + GNUNET_break (0); // FIXME: not implemented + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Activate future denomination key, turning it into a "current" or "valid" + * denomination key by adding the master signature. Deletes the + * denomination key from the 'future' table an inserts the data into the + * main denominations table. Because this function will trigger multiple SQL + * statements, it must be run within a transaction. + * + * @param cls closure + * @param session a session + * @param h_denom_pub hash of the denomination public key + * @param master_sig master signature to add + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_activate_denomination_key ( + void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct GNUNET_HashCode *h_denom_pub, + const struct TALER_MasterSignatureP *master_sig) +{ + GNUNET_break (0); // FIXME: not implemented + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Insert information about an auditor auditing a denomination key. + * + * @param cls closure + * @param session a session + * @param h_denom_pub the audited denomination + * @param auditor_pub the auditor's key + * @param auditor_sig signature affirming the auditor's audit activity + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_insert_auditor_denom_sig ( + void *cls, + struct TALER_EXCHANGEDB_Session *session, + const struct GNUNET_HashCode *h_denom_pub, + const struct TALER_AuditorPublicKeyP *auditor_pub, + const struct TALER_AuditorSignatureP *auditor_sig) +{ + GNUNET_break (0); // FIXME: not implemented + return GNUNET_DB_STATUS_HARD_ERROR; +} + + +/** + * Lookup information about known wire fees. + * + * @param cls closure + * @param session a session + * @param wire_method the wire method to lookup fees for + * @param start_time starting time of fee + * @param end_time end time of fee + * @param[out] wire_fee wire fee for that time period; if + * different wire fee exists within this time + * period, an 'invalid' amount is returned. + * @param[out] closing_fee wire fee for that time period; if + * different wire fee exists within this time + * period, an 'invalid' amount is returned. + * @return transaction status code + */ +static enum GNUNET_DB_QueryStatus +postgres_lookup_wire_fee_by_time ( + void *cls, + struct TALER_EXCHANGEDB_Session *session, + const char *wire_method, + struct GNUNET_TIME_Absolute start_time, + struct GNUNET_TIME_Absolute end_time, + struct TALER_Amount *wire_fee, + struct TALER_Amount *closing_fee) +{ + GNUNET_break (0); // FIXME: not implemented + return GNUNET_DB_STATUS_HARD_ERROR; +} + + /** * Initialize Postgres database subsystem. * @@ -7458,7 +7912,20 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &postgres_get_denomination_revocation; plugin->select_deposits_missing_wire = &postgres_select_deposits_missing_wire; - + plugin->lookup_auditor_timestamp + = &postgres_lookup_auditor_timestamp; + plugin->lookup_auditor_status + = &postgres_lookup_auditor_status; + plugin->insert_auditor + = &postgres_insert_auditor; + plugin->update_auditor + = &postgres_update_auditor; + plugin->lookup_wire_timestamp + = &postgres_lookup_wire_timestamp; + plugin->insert_wire + = &postgres_insert_wire; + plugin->update_wire + = &postgres_update_wire; return plugin; } diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 4ad05a688..19017eac1 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -2346,6 +2346,7 @@ struct TALER_EXCHANGE_ManagementAuditorEnableHandle; * @param url HTTP base URL for the exchange * @param auditor_pub the public signing key of the auditor * @param auditor_url base URL of the auditor + * @param auditor_name human readable name for the auditor * @param validity_start when was this decided? * @param master_sig signature affirming the auditor addition * @param cb function to call with the exchange's result @@ -2358,6 +2359,7 @@ TALER_EXCHANGE_management_enable_auditor ( const char *url, const struct TALER_AuditorPublicKeyP *auditor_pub, const char *auditor_url, + const char *auditor_name, struct GNUNET_TIME_Absolute validity_start, const struct TALER_MasterSignatureP *master_sig, TALER_EXCHANGE_ManagementAuditorEnableCallback cb, diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 400d6a723..0f5e693d5 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -2997,9 +2997,9 @@ struct TALER_EXCHANGEDB_Plugin * @param session a session * @param auditor_pub key of the auditor * @param auditor_url base URL of the auditor's REST service + * @param auditor_name name of the auditor (for humans) * @param start_date date when the auditor was added by the offline system * (only to be used for replay detection) - * @param master_sig signature affirming the addition of the auditor * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -3007,8 +3007,8 @@ struct TALER_EXCHANGEDB_Plugin struct TALER_EXCHANGEDB_Session *session, const struct TALER_AuditorPublicKeyP *auditor_pub, const char *auditor_url, - struct GNUNET_TIME_Absolute start_date, - const struct TALER_MasterSignatureP *master_sig); + const char *auditor_name, + struct GNUNET_TIME_Absolute start_date); /** @@ -3018,9 +3018,9 @@ struct TALER_EXCHANGEDB_Plugin * @param session a session * @param auditor_pub key of the auditor (primary key for the existing record) * @param auditor_url base URL of the auditor's REST service, to be updated + * @param auditor_name name of the auditor (for humans) * @param change_date date when the auditor status was last changed * (only to be used for replay detection) - * @param master_sig signature affirming the change in status (enable or disable) * @param enabled true to enable, false to disable * @return transaction status code */ @@ -3029,8 +3029,8 @@ struct TALER_EXCHANGEDB_Plugin struct TALER_EXCHANGEDB_Session *session, const struct TALER_AuditorPublicKeyP *auditor_pub, const char *auditor_url, + const char *auditor_name, struct GNUNET_TIME_Absolute change_date, - const struct TALER_MasterSignatureP *master_sig, bool enabled); diff --git a/src/lib/exchange_api_management_auditor_enable.c b/src/lib/exchange_api_management_auditor_enable.c index dedc9e43b..3556cdb3b 100644 --- a/src/lib/exchange_api_management_auditor_enable.c +++ b/src/lib/exchange_api_management_auditor_enable.c @@ -126,6 +126,7 @@ TALER_EXCHANGE_management_enable_auditor ( const char *url, const struct TALER_AuditorPublicKeyP *auditor_pub, const char *auditor_url, + const char *auditor_name, struct GNUNET_TIME_Absolute validity_start, const struct TALER_MasterSignatureP *master_sig, TALER_EXCHANGE_ManagementAuditorEnableCallback cb, @@ -149,9 +150,11 @@ TALER_EXCHANGE_management_enable_auditor ( GNUNET_free (ah); return NULL; } - body = json_pack ("{s:s, s:o, s:o, s:o}", - "master_sig", + body = json_pack ("{s:s, s:s, s:o, s:o, s:o}", + "auditor_url", auditor_url, + "auditor_name", + auditor_name, "auditor_pub", GNUNET_JSON_from_data_auto (auditor_pub), "master_sig", diff --git a/src/testing/testing_api_cmd_auditor_add.c b/src/testing/testing_api_cmd_auditor_add.c index 0a37c73db..64a848190 100644 --- a/src/testing/testing_api_cmd_auditor_add.c +++ b/src/testing/testing_api_cmd_auditor_add.c @@ -252,6 +252,7 @@ auditor_add_run (void *cls, exchange_url, &auditor_pub, auditor_url, + "test-case auditor", /* human-readable auditor name */ now, &master_sig, &auditor_add_cb, -- cgit v1.2.3