merchant

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

commit 69bc05f340912a11650734df997604f7f7752a8b
parent 920bde28e22fc667b9a49c9b626dbb7de5a477b9
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Wed,  6 Aug 2025 13:41:10 +0200

add public /instances endpoint usable when self-provisioning is enabled

Diffstat:
Msrc/backend/taler-merchant-httpd.c | 18+++++++++++++-----
Msrc/backend/taler-merchant-httpd.h | 10++++++++--
Msrc/backend/taler-merchant-httpd_private-post-instances.c | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/backend/taler-merchant-httpd_private-post-instances.h | 16++++++++++++++++
Msrc/backenddb/pg_insert_instance.c | 10+++++++---
Msrc/backenddb/pg_insert_instance.h | 15+++++++++------
Msrc/backenddb/test_merchantdb.c | 3++-
Msrc/include/taler_merchantdb_plugin.h | 5++++-
8 files changed, 121 insertions(+), 22 deletions(-)

diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c @@ -105,11 +105,6 @@ /** - * Fixme: document. - */ -#define INSTANCE_STALENESS GNUNET_TIME_UNIT_MINUTES - -/** * Backlog for listen operation on unix-domain sockets. */ #define UNIX_BACKLOG 500 @@ -1935,6 +1930,19 @@ url_handler (void *cls, .handler = &TMH_post_using_templates_ID, .max_upload = 1024 * 1024 }, + /* POST /instances */ + { + .url_prefix = "/instances", + .method = MHD_HTTP_METHOD_POST, + .skip_instance = true, + .default_only = true, + .handler = &TMH_public_post_instances, + /* allow instance data of up to 8 MB, that should be plenty; + note that exceeding #GNUNET_MAX_MALLOC_CHECKED (40 MB) + would require further changes to the allocation logic + in the code... */ + .max_upload = 1024 * 1024 * 8 + }, { .url_prefix = "*", .method = MHD_HTTP_METHOD_OPTIONS, diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2025 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 @@ -182,6 +182,12 @@ struct TMH_MerchantInstance * against the DB value when updating the auth token. */ bool auth_override; + + /** + * True if email/sms validation is needed before the + * instance can be used. + */ + bool validation_needed; }; @@ -770,7 +776,7 @@ extern int TMH_strict_v19; extern int TMH_auth_disabled; /** - * True if self-provisioning is enabled. + * #GNUNET_YES if self-provisioning is enabled. */ extern int TMH_have_self_provisioning; diff --git a/src/backend/taler-merchant-httpd_private-post-instances.c b/src/backend/taler-merchant-httpd_private-post-instances.c @@ -25,6 +25,7 @@ #include "platform.h" #include "taler-merchant-httpd_private-post-instances.h" #include "taler-merchant-httpd_helper.h" +#include "taler-merchant-httpd.h" #include "taler_merchant_bank_lib.h" #include <taler/taler_dbevents.h> #include <taler/taler_json_lib.h> @@ -42,12 +43,16 @@ * @param rh context of the handler * @param connection the MHD connection to handle * @param[in,out] hc context with further information about the request + * @param validation_needed true if self-provisioned and + * email/phone registration is required before the + * instance can become fully active * @return MHD result code */ MHD_RESULT -TMH_private_post_instances (const struct TMH_RequestHandler *rh, - struct MHD_Connection *connection, - struct TMH_HandlerContext *hc) +post_instances (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc, + bool validation_needed) { struct TALER_MERCHANTDB_InstanceSettings is = { 0 }; struct TALER_MERCHANTDB_InstanceAuthSettings ias; @@ -282,6 +287,7 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, if (NULL != is.logo) mi->settings.logo = GNUNET_strdup (is.logo); mi->auth = ias; + mi->validation_needed = validation_needed; GNUNET_CRYPTO_eddsa_key_create (&mi->merchant_priv.eddsa_priv); GNUNET_CRYPTO_eddsa_key_get_public (&mi->merchant_priv.eddsa_priv, &mi->merchant_pub.eddsa_pub); @@ -304,7 +310,8 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, &mi->merchant_pub, &mi->merchant_priv, &mi->settings, - &mi->auth); + &mi->auth, + validation_needed); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -374,4 +381,55 @@ retry: } +/** + * Generate an instance, given its configuration. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_private_post_instances (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + return post_instances (rh, + connection, + hc, + false); +} + + +/** + * Generate an instance, given its configuration. + * Public handler to be used when self-provisioning. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_public_post_instances (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + if (GNUNET_YES != + TMH_have_self_provisioning) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_FORBIDDEN, + TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED, + "Self-provisioning is not enabled"); + } + return post_instances (rh, + connection, + hc, + TEH_TCS_NONE != + TEH_mandatory_tan_channels); +} + + /* end of taler-merchant-httpd_private-post-instances.c */ diff --git a/src/backend/taler-merchant-httpd_private-post-instances.h b/src/backend/taler-merchant-httpd_private-post-instances.h @@ -40,4 +40,20 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, struct MHD_Connection *connection, struct TMH_HandlerContext *hc); + +/** + * Generate an instance, given its configuration. + * Public handler to be used when self-provisioning. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_public_post_instances (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc); + + #endif diff --git a/src/backenddb/pg_insert_instance.c b/src/backenddb/pg_insert_instance.c @@ -32,7 +32,8 @@ TMH_PG_insert_instance ( const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPrivateKeyP *merchant_priv, const struct TALER_MERCHANTDB_InstanceSettings *is, - const struct TALER_MERCHANTDB_InstanceAuthSettings *ias) + const struct TALER_MERCHANTDB_InstanceAuthSettings *ias, + bool validation_needed) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { @@ -59,6 +60,7 @@ TMH_PG_insert_instance ( (NULL == is->phone) ? GNUNET_PQ_query_param_null () : GNUNET_PQ_query_param_string (is->phone), + GNUNET_PQ_query_param_bool (validation_needed), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_QueryParam params_priv[] = { @@ -85,9 +87,11 @@ TMH_PG_insert_instance ( ",website" ",email" ",logo" - ",phone_number)" + ",phone_number" + ",validation_needed)" "VALUES" - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)"); + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)") + ; qs = GNUNET_PQ_eval_prepared_non_select (pg->conn, "insert_instance", params); diff --git a/src/backenddb/pg_insert_instance.h b/src/backenddb/pg_insert_instance.h @@ -33,14 +33,17 @@ * @param merchant_priv private key of the instance * @param is details about the instance * @param ias authentication settings for the instance + * @param validation_needed true if validation is + * required before the instance can be used * @return database result code */ enum GNUNET_DB_QueryStatus -TMH_PG_insert_instance (void *cls, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct TALER_MerchantPrivateKeyP *merchant_priv, - const struct TALER_MERCHANTDB_InstanceSettings *is, - const struct - TALER_MERCHANTDB_InstanceAuthSettings *ias); +TMH_PG_insert_instance ( + void *cls, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_MerchantPrivateKeyP *merchant_priv, + const struct TALER_MERCHANTDB_InstanceSettings *is, + const struct TALER_MERCHANTDB_InstanceAuthSettings *ias, + bool validation_needed); #endif diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c @@ -316,7 +316,8 @@ test_insert_instance (const struct InstanceData *instance, &instance->merchant_pub, &instance->merchant_priv, &instance->instance, - &ias), + &ias, + false), "Insert instance failed\n"); return 0; } diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h @@ -1692,6 +1692,8 @@ struct TALER_MERCHANTDB_Plugin * @param merchant_pub public key of the instance * @param merchant_priv private key of the instance * @param is details about the instance + * @param validation_needed true if validation is + * required before the instance can be used * @return database result code */ enum GNUNET_DB_QueryStatus @@ -1699,7 +1701,8 @@ struct TALER_MERCHANTDB_Plugin const struct TALER_MerchantPublicKeyP *merchant_pub, const struct TALER_MerchantPrivateKeyP *merchant_priv, const struct TALER_MERCHANTDB_InstanceSettings *is, - const struct TALER_MERCHANTDB_InstanceAuthSettings *ias); + const struct TALER_MERCHANTDB_InstanceAuthSettings *ias, + bool validation_needed); /** * Insert information about an instance's account into our database.