merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit 53cdcd6cb3aadbeac7d878e817c1314c6fc7c63c
parent 6acc51b57c8c05d82d59bd983239cc81a0a30275
Author: Christian Blättler <blatc2@bfh.ch>
Date:   Wed, 10 Apr 2024 07:46:52 +0200

add db functions to select & insert token family keys

Diffstat:
Msrc/backenddb/Makefile.am | 1+
Msrc/backenddb/pg_insert_token_family.h | 2+-
Asrc/backenddb/pg_insert_token_family_key.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/backenddb/pg_insert_token_family_key.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/backenddb/pg_lookup_token_family_key.c | 80++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/backenddb/pg_lookup_token_family_key.h | 12++++++++----
Msrc/backenddb/plugin_merchantdb_postgres.c | 4++++
Msrc/include/taler_merchantdb_plugin.h | 46+++++++++++++++++++++++++++++++++-------------
8 files changed, 229 insertions(+), 58 deletions(-)

diff --git a/src/backenddb/Makefile.am b/src/backenddb/Makefile.am @@ -173,6 +173,7 @@ libtaler_plugin_merchantdb_postgres_la_SOURCES = \ pg_lookup_token_families.h pg_lookup_token_families.c \ pg_delete_token_family.h pg_delete_token_family.c \ pg_update_token_family.h pg_update_token_family.c \ + pg_insert_token_family_key.h pg_insert_token_family_key.c \ pg_lookup_token_family_key.h pg_lookup_token_family_key.c \ plugin_merchantdb_postgres.c \ pg_helper.h pg_helper.c diff --git a/src/backenddb/pg_insert_token_family.h b/src/backenddb/pg_insert_token_family.h @@ -28,7 +28,7 @@ /** * @param cls closure - * @param instance_id instance to insert token family for TODO: Is this needed? + * @param instance_id instance to insert token family for * @param token_family_slug slug of the token family to insert * @param details the token family details to insert * @return database result code diff --git a/src/backenddb/pg_insert_token_family_key.c b/src/backenddb/pg_insert_token_family_key.c @@ -0,0 +1,95 @@ +/* + This file is part of TALER + Copyright (C) 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file backenddb/pg_insert_token_family_key.c + * @brief Implementation of the insert_token_family_key function for Postgres + * @author Christian Blättler + */ +#include "platform.h" +#include <gnunet/gnunet_common.h> +#include <gnunet/gnunet_pq_lib.h> +#include <taler/taler_error_codes.h> +#include <taler/taler_dbevents.h> +#include <taler/taler_pq_lib.h> +#include "pg_insert_token_family_key.h" +#include "pg_helper.h" + +enum GNUNET_DB_QueryStatus +TMH_PG_insert_token_family_key (void *cls, + const char *token_family_slug, + const struct TALER_TokenFamilyPublicKey *pub, + const struct TALER_TokenFamilyPrivateKey *priv, + const struct GNUNET_TIME_Timestamp valid_after, + const struct GNUNET_TIME_Timestamp valid_before) +{ + struct PostgresClosure *pg = cls; + const char *cipher; + // struct GNUNET_HashCode pub_hash; + + switch (pub->public_key.cipher) + { + case GNUNET_CRYPTO_BSA_RSA: + cipher = "rsa"; + break; + case GNUNET_CRYPTO_BSA_CS: + cipher = "cs"; + break; + case GNUNET_CRYPTO_BSA_INVALID: + /* case listed to make compilers happy */ + GNUNET_assert (0); + } + + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (token_family_slug), + GNUNET_PQ_query_param_blind_sign_pub (&pub->public_key), + GNUNET_PQ_query_param_auto_from_type (&pub->public_key.pub_key_hash), + GNUNET_PQ_query_param_blind_sign_priv (&priv->private_key), + GNUNET_PQ_query_param_timestamp (&valid_after), + GNUNET_PQ_query_param_timestamp (&valid_before), + GNUNET_PQ_query_param_string (cipher), + GNUNET_PQ_query_param_end + }; + + GNUNET_assert (pub->public_key.cipher == priv->private_key.cipher); + // TODO: Ensure pub->public_key.pub_key_hash matches the actual public key + // GNUNET_CRYPTO_hash (res, + // len, + // &bpk->pub_key_hash); + // GNUNET_assert (0 == + // GNUNET_memcmp (&pub_hash, + // &pub->public_key.)); + GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( + valid_after.abs_time)); + GNUNET_assert (! GNUNET_TIME_absolute_is_zero ( + valid_before.abs_time)); + + PREPARE (pg, + "token_family_key_insert", + "INSERT INTO merchant_token_family_keys " + "(token_family_serial" + ",pub" + ",h_pub" + ",priv" + ",valid_after" + ",valid_before" + ",cipher)" + " SELECT token_family_serial, $2, $3, $4, $5, $6, $7" + " FROM merchant_token_families" + " WHERE slug = $1"); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "token_family_key_insert", + params); +} +\ No newline at end of file diff --git a/src/backenddb/pg_insert_token_family_key.h b/src/backenddb/pg_insert_token_family_key.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file backenddb/pg_insert_token_family_key.h + * @brief implementation of the insert_token_family_key function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_INSERT_TOKEN_FAMILY_KEY_H +#define PG_INSERT_TOKEN_FAMILY_KEY_H + +#include <taler/taler_util.h> +#include <taler/taler_json_lib.h> +#include "taler_merchantdb_plugin.h" + + +/** + * @param cls closure + * @param token_family_slug slug of the token family to insert the key for + * @param pub public key to insert + * @param priv private key to insert + * @param valid_after start of validity period for this key + * @param valid_before end of validity period for this key + * @return database result code + */ +enum GNUNET_DB_QueryStatus +TMH_PG_insert_token_family_key (void *cls, + const char *token_family_slug, + const struct TALER_TokenFamilyPublicKey *pub, + const struct TALER_TokenFamilyPrivateKey *priv, + const struct GNUNET_TIME_Timestamp valid_after, + const struct GNUNET_TIME_Timestamp valid_before); + +#endif diff --git a/src/backenddb/pg_lookup_token_family_key.c b/src/backenddb/pg_lookup_token_family_key.c @@ -20,6 +20,7 @@ */ #include "platform.h" #include <gnunet/gnunet_pq_lib.h> +#include <gnunet/gnunet_time_lib.h> #include <string.h> #include <taler/taler_error_codes.h> #include <taler/taler_dbevents.h> @@ -30,13 +31,17 @@ enum GNUNET_DB_QueryStatus TMH_PG_lookup_token_family_key (void *cls, const char *instance_id, - struct GNUNET_HashCode *h_public_key, + const char *token_family_slug, + struct GNUNET_TIME_Timestamp min_valid_after, + struct GNUNET_TIME_Timestamp max_valid_after, struct TALER_MERCHANTDB_TokenFamilyKeyDetails *details) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_string (instance_id), - GNUNET_PQ_query_param_auto_from_type (h_public_key), + GNUNET_PQ_query_param_string (token_family_slug), + GNUNET_PQ_query_param_timestamp (&min_valid_after), + GNUNET_PQ_query_param_timestamp (&max_valid_after), GNUNET_PQ_query_param_end }; @@ -55,33 +60,39 @@ TMH_PG_lookup_token_family_key (void *cls, else { char *kind; - char *cipher; + details->pub = NULL; + details->priv = NULL; + details->valid_after = GNUNET_TIME_UNIT_ZERO_TS; + details->valid_before = GNUNET_TIME_UNIT_ZERO_TS; struct GNUNET_PQ_ResultSpec rs[] = { - // TODO: Figure out how to parse keys - // GNUNET_PQ_result_spec_auto_from_type ("h_pub", - // &details->pub_h), - // GNUNET_PQ_result_spec_auto_from_type ("pub", - // &details->pub), - // GNUNET_PQ_result_spec_auto_from_type ("priv", - // &details->priv), - GNUNET_PQ_result_spec_string ("cipher", - &cipher), + // GNUNET_PQ_result_spec_allow_null ( + // GNUNET_PQ_result_spec_blind_sign_pub ("pub", + // &details->pub->public_key), + // NULL), + // GNUNET_PQ_result_spec_allow_null ( + // GNUNET_PQ_result_spec_blind_sign_priv ("priv", + // &details->priv->private_key), + // NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_timestamp ("key_valid_after", + &details->valid_after), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_timestamp ("key_valid_before", + &details->valid_before), + NULL), GNUNET_PQ_result_spec_string ("slug", &details->token_family.slug), GNUNET_PQ_result_spec_string ("name", &details->token_family.name), - GNUNET_PQ_result_spec_timestamp ("merchant_token_family_keys.valid_after", - &details->valid_after), - GNUNET_PQ_result_spec_timestamp ("merchant_token_family_keys.valid_before", - &details->valid_before), GNUNET_PQ_result_spec_string ("description", &details->token_family.description), TALER_PQ_result_spec_json ("description_i18n", &details->token_family.description_i18n), - GNUNET_PQ_result_spec_timestamp ("merchant_token_families.valid_after", + GNUNET_PQ_result_spec_timestamp ("valid_after", &details->token_family.valid_after), - GNUNET_PQ_result_spec_timestamp ("merchant_token_families.valid_before", + GNUNET_PQ_result_spec_timestamp ("valid_before", &details->token_family.valid_before), GNUNET_PQ_result_spec_relative_time ("duration", &details->token_family.duration), @@ -102,8 +113,8 @@ TMH_PG_lookup_token_family_key (void *cls, ",pub" ",priv" ",cipher" - ",merchant_token_family_keys.valid_after" - ",merchant_token_family_keys.valid_before" + ",merchant_token_family_keys.valid_after as key_valid_after" + ",merchant_token_family_keys.valid_before as key_valid_before" ",slug" ",name" ",description" @@ -114,13 +125,16 @@ TMH_PG_lookup_token_family_key (void *cls, ",kind" ",issued" ",redeemed" - " FROM merchant_token_family_keys" - " JOIN merchant_token_families" - " USING (token_family_serial)" + " FROM merchant_token_families" + " LEFT JOIN merchant_token_family_keys" + " ON merchant_token_families.token_family_serial = merchant_token_family_keys.token_family_serial" + " AND merchant_token_family_keys.valid_after >= $3" + " AND merchant_token_family_keys.valid_after <= $4" " JOIN merchant_instances" " USING (merchant_serial)" " WHERE merchant_instances.merchant_id=$1" - " AND h_pub=$2"); + " AND slug=$2" + " LIMIT 1"); enum GNUNET_DB_QueryStatus qs; qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "lookup_token_family_key", @@ -138,24 +152,10 @@ TMH_PG_lookup_token_family_key (void *cls, GNUNET_break (0); return GNUNET_DB_STATUS_HARD_ERROR; } - - if (0 == strcmp(cipher, "rsa")) - { - details->priv.private_key.cipher = GNUNET_CRYPTO_BSA_RSA; - details->pub.public_key.cipher = GNUNET_CRYPTO_BSA_RSA; - } - else if (0 == strcmp(cipher, "cs")) - { - details->priv.private_key.cipher = GNUNET_CRYPTO_BSA_CS; - details->pub.public_key.cipher = GNUNET_CRYPTO_BSA_CS; - } - else - { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; - } } + /* TODO: How to handle multiple results? */ + return qs; } } \ No newline at end of file diff --git a/src/backenddb/pg_lookup_token_family_key.h b/src/backenddb/pg_lookup_token_family_key.h @@ -27,11 +27,13 @@ #include "taler_merchantdb_plugin.h" /** - * Lookup details about a particular token family public key. + * Lookup details about a particular token family key. * * @param cls closure - * @param instance_id instance to lookup token family for - * @param h_public_key hash of token family public key to lookup + * @param instance_id instance to lookup token family key for + * @param token_family_slug slug of token family to lookup + * @param min_valid_after lower bound of the start of the key validation period + * @param max_valid_after upper bound of the start of the key validation period * @param[out] details set to the token family key details on success, can be NULL * (in that case we only want to check if the token family key exists) * @return database result code @@ -39,7 +41,9 @@ enum GNUNET_DB_QueryStatus TMH_PG_lookup_token_family_key (void *cls, const char *instance_id, - struct GNUNET_HashCode *h_public_key, + const char *token_family_slug, + struct GNUNET_TIME_Timestamp min_valid_after, + struct GNUNET_TIME_Timestamp max_valid_after, struct TALER_MERCHANTDB_TokenFamilyKeyDetails *details); diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c @@ -138,6 +138,7 @@ #include "pg_lookup_token_families.h" #include "pg_delete_token_family.h" #include "pg_update_token_family.h" +#include "pg_insert_token_family_key.h" #include "pg_lookup_token_family_key.h" @@ -576,11 +577,14 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) = &TMH_PG_delete_token_family; plugin->update_token_family = &TMH_PG_update_token_family; + plugin->insert_token_family_key + = &TMH_PG_insert_token_family_key; plugin->lookup_token_family_key = &TMH_PG_lookup_token_family_key; plugin->update_deposit_confirmation_status = &TMH_PG_update_deposit_confirmation_status; + return plugin; } diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h @@ -24,6 +24,7 @@ #define TALER_MERCHANTDB_PLUGIN_H #include <gnunet/gnunet_common.h> +#include <gnunet/gnunet_time_lib.h> #include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_db_lib.h> #include <taler/taler_exchange_service.h> @@ -1077,18 +1078,12 @@ struct TALER_MERCHANTDB_TokenFamilyKeyDetails /** * Token family public key. */ - struct TALER_TokenFamilyPublicKey pub; - - /** - * TODO: Remove this separate field, since it's already available within pub. - * Hash of the token family public key. - */ - struct TALER_TokenFamilyPublicKeyHash pub_h; + struct TALER_TokenFamilyPublicKey *pub; /** * Token family private key. */ - struct TALER_TokenFamilyPrivateKey priv; + struct TALER_TokenFamilyPrivateKey *priv; /** * Details about the token family this key belongs to. @@ -3224,7 +3219,7 @@ struct TALER_MERCHANTDB_Plugin * Insert details about a particular token family. * * @param cls closure - * @param instance_id instance to insert product for + * @param instance_id instance to insert token family for * @param token_family_slug slug of token family to insert * @param details the token family details to insert * @return database result code @@ -3238,11 +3233,13 @@ struct TALER_MERCHANTDB_Plugin /** - * Lookup details about a particular token family public key. + * Lookup details about a particular token family key. * * @param cls closure - * @param instance_id instance to lookup token family for - * @param h_public_key hash of token family public key to lookup + * @param instance_id instance to lookup token family key for + * @param token_family_slug slug of token family to lookup + * @param min_valid_after lower bound of the start of the key validation period + * @param max_valid_after upper bound of the start of the key validation period * @param[out] details set to the token family key details on success, can be NULL * (in that case we only want to check if the token family key exists) * @return database result code @@ -3251,9 +3248,32 @@ struct TALER_MERCHANTDB_Plugin (*lookup_token_family_key) ( void *cls, const char *instance_id, - struct GNUNET_HashCode *h_public_key, + const char *token_family_slug, + struct GNUNET_TIME_Timestamp min_valid_after, + struct GNUNET_TIME_Timestamp max_valid_after, struct TALER_MERCHANTDB_TokenFamilyKeyDetails *details); + + /** + * Insert details a key pair for a token family. + * + * @param cls closure + * @param token_family_slug slug of token family to insert the key pair for + * @param pub token family public key + * @param priv token family private key + * @param valid_after start of the key validation period + * @param valid_before end of the key validation period + * @return database result code + */ + enum GNUNET_DB_QueryStatus + (*insert_token_family_key)( + void *cls, + const char *token_family_slug, + const struct TALER_TokenFamilyPublicKey *pub, + const struct TALER_TokenFamilyPrivateKey *priv, + struct GNUNET_TIME_Timestamp valid_after, + struct GNUNET_TIME_Timestamp valid_before); + /** * Lookup deposits that are finished and awaiting a wire transfer. *