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:
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.