commit ddbc213487a90dd1285c454b780fbdb3da5bb2a7
parent 0c13799e32be9f24b3915bca7814a216a6ffb6f5
Author: bohdan-potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date: Tue, 5 Aug 2025 12:52:32 +0200
Merge branch 'master' into dev/bohdan-potuzhnyi/donau-integration
Diffstat:
9 files changed, 123 insertions(+), 71 deletions(-)
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
@@ -125,68 +125,36 @@
*/
#define DEFAULT_MAX_UPLOAD_SIZE (16 * 1024)
-/**
- * Which currency do we use?
- */
char *TMH_currency;
-/**
- * What is the base URL for this merchant backend? NULL if it is not
- * configured and is to be determined from HTTP headers (X-Forwarded-Host and
- * X-Forwarded-Port and X-Forwarded-Prefix) of the reverse proxy.
- */
char *TMH_base_url;
-/**
- * Inform the auditor for all deposit confirmations (global option)
- */
int TMH_force_audit;
-/**
- * Connection handle to the our database
- */
struct TALER_MERCHANTDB_Plugin *TMH_db;
-/**
- * Event handler for instance settings changes.
- */
-static struct GNUNET_DB_EventHandler *instance_eh;
-
-/**
- * Hashmap pointing at merchant instances by 'id'. An 'id' is
- * just a string that identifies a merchant instance. When a frontend
- * needs to specify an instance to the backend, it does so by 'id'
- */
struct GNUNET_CONTAINER_MultiHashMap *TMH_by_id_map;
-/**
- * #GNUNET_YES if protocol version 19 is strictly enforced.
- * (Default is #GNUNET_NO)
- */
int TMH_strict_v19;
-/**
- * #GNUNET_YES if authentication is disabled (For testing only!!).
- * (Default is #GNUNET_NO)
- */
int TMH_auth_disabled;
-/**
- * How long do we need to keep information on paid contracts on file for tax
- * or other legal reasons? Used to block deletions for younger transaction
- * data.
- */
+int TMH_have_self_provisioning;
+
+enum TEH_TanChannelSet TEH_mandatory_tan_channels;
+
struct GNUNET_TIME_Relative TMH_legal_expiration;
-/**
- * Length of the TMH_cspecs array.
- */
unsigned int TMH_num_cspecs;
+struct TALER_CurrencySpecification *TMH_cspecs;
+
+struct GNUNET_CURL_Context *TMH_curl_ctx;
+
/**
- * Rendering specs for currencies.
+ * Event handler for instance settings changes.
*/
-struct TALER_CurrencySpecification *TMH_cspecs;
+static struct GNUNET_DB_EventHandler *instance_eh;
/**
* True if we started any HTTP daemon.
@@ -199,11 +167,6 @@ static bool have_daemons;
static int merchant_connection_close;
/**
- * Context for all exchange operations (useful to the event loop).
- */
-struct GNUNET_CURL_Context *TMH_curl_ctx;
-
-/**
* Context for integrating #TMH_curl_ctx with the
* GNUnet event loop.
*/
@@ -631,6 +594,7 @@ TMH_instance_decref (struct TMH_MerchantInstance *mi)
GNUNET_free (mi->settings.id);
GNUNET_free (mi->settings.name);
GNUNET_free (mi->settings.email);
+ GNUNET_free (mi->settings.phone);
GNUNET_free (mi->settings.website);
GNUNET_free (mi->settings.logo);
json_decref (mi->settings.address);
@@ -2550,6 +2514,8 @@ add_instance_cb (void *cls,
mi->settings.name = GNUNET_strdup (mi->settings.name);
if (NULL != mi->settings.email)
mi->settings.email = GNUNET_strdup (mi->settings.email);
+ if (NULL != mi->settings.phone)
+ mi->settings.email = GNUNET_strdup (mi->settings.phone);
if (NULL != mi->settings.website)
mi->settings.website = GNUNET_strdup (mi->settings.website);
if (NULL != mi->settings.logo)
@@ -2779,11 +2745,12 @@ run (void *cls,
}
if (GNUNET_SYSERR ==
- (TMH_strict_v19 = GNUNET_CONFIGURATION_get_value_yesno (cfg,
- "merchant",
- "STRICT_PROTOCOL_V19")))
+ (TMH_strict_v19
+ = GNUNET_CONFIGURATION_get_value_yesno (cfg,
+ "merchant",
+ "STRICT_PROTOCOL_V19")))
{
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO,
"merchant",
"STRICT_PROTOCOL_V19");
TMH_strict_v19 = GNUNET_NO;
@@ -2800,6 +2767,19 @@ run (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"DANGEROUS: Endpoint Authentication disabled!");
}
+
+ if (GNUNET_SYSERR ==
+ (TMH_have_self_provisioning
+ = GNUNET_CONFIGURATION_get_value_yesno (cfg,
+ "merchant",
+ "ENABLE_SELF_PROVISIONING")))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_INFO,
+ "merchant",
+ "ENABLE_SELF_PROVISIONING");
+ TMH_have_self_provisioning = GNUNET_NO;
+ }
+
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (cfg,
"merchant",
@@ -2813,6 +2793,44 @@ run (void *cls,
GNUNET_SCHEDULER_shutdown ();
return;
}
+
+ {
+ char *tan_channels;
+
+ if (GNUNET_OK ==
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ "merchant",
+ "MANDATORY_TAN_CHANNELS",
+ &tan_channels))
+ {
+ for (char *tok = strtok (tan_channels,
+ " ");
+ NULL != tok;
+ tok = strtok (NULL,
+ " "))
+ {
+ if (0 == strcasecmp (tok,
+ "sms"))
+ TEH_mandatory_tan_channels |= TEH_TCS_SMS;
+ else if (0 == strcasecmp (tok,
+ "email"))
+ TEH_mandatory_tan_channels |= TEH_TCS_EMAIL;
+ else
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ "merchant",
+ "MANDATORY_TAN_CHANNELS",
+ tok);
+ global_ret = EXIT_NOTCONFIGURED;
+ GNUNET_SCHEDULER_shutdown ();
+ GNUNET_free (tan_channels);
+ return;
+ }
+ }
+ GNUNET_free (tan_channels);
+ }
+ }
+
if (GNUNET_OK ==
GNUNET_CONFIGURATION_get_value_string (cfg,
"merchant",
diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h
@@ -769,6 +769,27 @@ extern int TMH_strict_v19;
*/
extern int TMH_auth_disabled;
+/**
+ * True if self-provisioning is enabled.
+ */
+extern int TMH_have_self_provisioning;
+
+/**
+ * Set of TAN channels.
+ */
+enum TEH_TanChannelSet
+{
+ TEH_TCS_NONE = 0,
+ TEH_TCS_SMS = 1,
+ TEH_TCS_EMAIL = 2
+};
+
+
+/**
+ * Which TAN channels are mandatory for self-provisioned
+ * accounts and password resets? Bitmask.
+ */
+extern enum TEH_TanChannelSet TEH_mandatory_tan_channels;
/**
* Callback that frees an instances removing
diff --git a/src/backend/taler-merchant-httpd_config.c b/src/backend/taler-merchant-httpd_config.c
@@ -90,11 +90,21 @@ MH_handler_config (const struct TMH_RequestHandler *rh,
{
json_t *specs = json_object ();
json_t *exchanges = json_array ();
+ json_t *mtc = json_array ();
GNUNET_assert (NULL != specs);
GNUNET_assert (NULL != exchanges);
+ GNUNET_assert (NULL != mtc);
TMH_exchange_get_trusted (&add_exchange,
exchanges);
+ if (0 != (TEH_TCS_SMS & TEH_mandatory_tan_channels))
+ GNUNET_assert (0 ==
+ json_array_append_new (mtc,
+ json_string ("sms")));
+ if (0 != (TEH_TCS_EMAIL & TEH_mandatory_tan_channels))
+ GNUNET_assert (0 ==
+ json_array_append_new (mtc,
+ json_string ("email")));
for (unsigned int i = 0; i<TMH_num_cspecs; i++)
{
const struct TALER_CurrencySpecification *cspec = &TMH_cspecs[i];
@@ -110,10 +120,15 @@ MH_handler_config (const struct TMH_RequestHandler *rh,
response = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_string ("currency",
TMH_currency),
+ GNUNET_JSON_pack_bool ("have_self_provisioning",
+ GNUNET_YES ==
+ TMH_have_self_provisioning),
GNUNET_JSON_pack_object_steal ("currencies",
specs),
GNUNET_JSON_pack_array_steal ("exchanges",
exchanges),
+ GNUNET_JSON_pack_array_steal ("mandatory_tan_channels",
+ mtc),
GNUNET_JSON_pack_string (
"implementation",
"urn:net:taler:specs:taler-merchant:c-reference"),
diff --git a/src/backend/taler-merchant-httpd_private-get-instances-ID.c b/src/backend/taler-merchant-httpd_private-get-instances-ID.c
@@ -73,8 +73,8 @@ get_instances_ID (struct TMH_MerchantInstance *mi,
auth = GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("method",
GNUNET_is_zero (&mi->auth.auth_hash)
- ? "external"
- : "token"));
+ ? "external"
+ : "token"));
return TALER_MHD_REPLY_JSON_PACK (
connection,
MHD_HTTP_OK,
@@ -82,9 +82,6 @@ get_instances_ID (struct TMH_MerchantInstance *mi,
ja),
GNUNET_JSON_pack_string ("name",
mi->settings.name),
- GNUNET_JSON_pack_string (
- "user_type",
- "business"),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("website",
mi->settings.website)),
@@ -92,6 +89,9 @@ get_instances_ID (struct TMH_MerchantInstance *mi,
GNUNET_JSON_pack_string ("email",
mi->settings.email)),
GNUNET_JSON_pack_allow_null (
+ GNUNET_JSON_pack_string ("phone_number",
+ mi->settings.phone)),
+ GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("logo",
mi->settings.logo)),
GNUNET_JSON_pack_data_auto ("merchant_pub",
diff --git a/src/backend/taler-merchant-httpd_private-get-instances.c b/src/backend/taler-merchant-httpd_private-get-instances.c
@@ -74,9 +74,6 @@ add_instance (void *cls,
GNUNET_JSON_PACK (
GNUNET_JSON_pack_string ("name",
mi->settings.name),
- GNUNET_JSON_pack_string (
- "user_type",
- "business"),
GNUNET_JSON_pack_allow_null (
GNUNET_JSON_pack_string ("website",
mi->settings.website)),
diff --git a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c
@@ -78,6 +78,10 @@ patch_instances_ID (struct TMH_MerchantInstance *mi,
(const char **) &is.email),
NULL),
GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("phone_number",
+ (const char **) &is.phone),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("logo",
(const char **) &is.logo),
NULL),
@@ -215,6 +219,7 @@ giveup:
/* Update our 'settings' */
GNUNET_free (mi->settings.name);
GNUNET_free (mi->settings.email);
+ GNUNET_free (mi->settings.phone);
GNUNET_free (mi->settings.website);
GNUNET_free (mi->settings.logo);
json_decref (mi->settings.address);
@@ -226,6 +231,8 @@ giveup:
mi->settings.name = GNUNET_strdup (name);
if (NULL != is.email)
mi->settings.email = GNUNET_strdup (is.email);
+ if (NULL != is.phone)
+ mi->settings.email = GNUNET_strdup (is.phone);
if (NULL != is.website)
mi->settings.website = GNUNET_strdup (is.website);
if (NULL != is.logo)
diff --git a/src/backend/taler-merchant-httpd_private-post-instances.c b/src/backend/taler-merchant-httpd_private-post-instances.c
@@ -52,7 +52,6 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh,
struct TALER_MERCHANTDB_InstanceSettings is = { 0 };
struct TALER_MERCHANTDB_InstanceAuthSettings ias;
const char *auth_password = NULL;
- const char *uts = "business";
struct TMH_WireMethod *wm_head = NULL;
struct TMH_WireMethod *wm_tail = NULL;
const json_t *jauth;
@@ -62,14 +61,14 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh,
GNUNET_JSON_spec_string ("name",
(const char **) &is.name),
GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_string ("user_type",
- &uts),
- NULL),
- GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("email",
(const char **) &is.email),
NULL),
GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("phone_number",
+ (const char **) &is.phone),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_string ("website",
(const char **) &is.website),
NULL),
@@ -276,6 +275,8 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh,
mi->settings.name = GNUNET_strdup (is.name);
if (NULL != is.email)
mi->settings.email = GNUNET_strdup (is.email);
+ if (NULL != is.email)
+ mi->settings.phone = GNUNET_strdup (is.phone);
if (NULL != is.website)
mi->settings.website = GNUNET_strdup (is.website);
if (NULL != is.logo)
diff --git a/src/lib/merchant_api_get_instance.c b/src/lib/merchant_api_get_instance.c
@@ -93,16 +93,12 @@ handle_get_instance_finished (void *cls,
{
case MHD_HTTP_OK:
{
- const char *uts;
const json_t *address;
const json_t *jurisdiction;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string (
"name",
&igr.details.ok.details.name),
- GNUNET_JSON_spec_string (
- "user_type",
- &uts),
GNUNET_JSON_spec_fixed_auto (
"merchant_pub",
&igr.details.ok.details.merchant_pub),
diff --git a/src/lib/merchant_api_get_instances.c b/src/lib/merchant_api_get_instances.c
@@ -103,12 +103,9 @@ parse_instances (const json_t *json,
json_array_foreach (ia, index, value) {
struct TALER_MERCHANT_InstanceInformation *ii = &iis[index];
- const char *uts;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("name",
&ii->name),
- GNUNET_JSON_spec_string ("user_type",
- &uts),
GNUNET_JSON_spec_string ("id",
&ii->id),
GNUNET_JSON_spec_fixed_auto ("merchant_pub",