diff options
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-post-instances.c')
-rw-r--r-- | src/backend/taler-merchant-httpd_private-post-instances.c | 311 |
1 files changed, 93 insertions, 218 deletions
diff --git a/src/backend/taler-merchant-httpd_private-post-instances.c b/src/backend/taler-merchant-httpd_private-post-instances.c index 58a93b27..a4cf884d 100644 --- a/src/backend/taler-merchant-httpd_private-post-instances.c +++ b/src/backend/taler-merchant-httpd_private-post-instances.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2020, 2021 Taler Systems SA + (C) 2020-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as @@ -25,6 +25,8 @@ #include "platform.h" #include "taler-merchant-httpd_private-post-instances.h" #include "taler-merchant-httpd_helper.h" +#include "taler_merchant_bank_lib.h" +#include <taler/taler_dbevents.h> #include <taler/taler_json_lib.h> #include <regex.h> @@ -35,104 +37,6 @@ /** - * Check if the array of @a payto_uris contains exactly the same - * URIs as those already in @a mi (possibly in a different order). - * - * @param mi a merchant instance with accounts - * @param payto_uris a JSON array with accounts (presumably) - * @return true if they are 'equal', false if not or of payto_uris is not an array - */ -static bool -accounts_equal (const struct TMH_MerchantInstance *mi, - json_t *payto_uris) -{ - if (! json_is_array (payto_uris)) - return false; - { - unsigned int len = json_array_size (payto_uris); - bool matches[GNUNET_NZL (len)]; - struct TMH_WireMethod *wm; - - memset (matches, - 0, - sizeof (matches)); - for (wm = mi->wm_head; - NULL != wm; - wm = wm->next) - { - const char *uri = wm->payto_uri; - - GNUNET_assert (NULL != uri); - for (unsigned int i = 0; i<len; i++) - { - const char *str = json_string_value (json_array_get (payto_uris, - i)); - - GNUNET_assert (NULL != str); - if (0 == strcasecmp (uri, - str)) - { - if (matches[i]) - { - GNUNET_break (0); - return false; /* duplicate entry!? */ - } - matches[i] = true; - break; - } - } - } - for (unsigned int i = 0; i<len; i++) - if (! matches[i]) - return false; - } - return true; -} - - -/** - * Free memory used by @a wm - * - * @param wm wire method to free - */ -static void -free_wm (struct TMH_WireMethod *wm) -{ - GNUNET_free (wm->payto_uri); - GNUNET_free (wm->wire_method); - GNUNET_free (wm); -} - - -/** - * Free memory used by @a mi. - * - * @param mi instance to free - */ -static void -free_mi (struct TMH_MerchantInstance *mi) -{ - struct TMH_WireMethod *wm; - - while (NULL != (wm = mi->wm_head)) - { - GNUNET_CONTAINER_DLL_remove (mi->wm_head, - mi->wm_tail, - wm); - free_wm (wm); - } - GNUNET_free (mi->settings.id); - GNUNET_free (mi->settings.name); - GNUNET_free (mi->settings.website); - GNUNET_free (mi->settings.email); - GNUNET_free (mi->settings.logo); - json_decref (mi->settings.address); - json_decref (mi->settings.jurisdiction); - GNUNET_free (mi); -} - - -/** * Generate an instance, given its configuration. * * @param rh context of the handler @@ -145,46 +49,42 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, struct MHD_Connection *connection, struct TMH_HandlerContext *hc) { - struct TALER_MERCHANTDB_InstanceSettings is; + struct TALER_MERCHANTDB_InstanceSettings is = { 0 }; struct TALER_MERCHANTDB_InstanceAuthSettings ias; - json_t *payto_uris; const char *auth_token = NULL; + const char *uts = "business"; struct TMH_WireMethod *wm_head = NULL; struct TMH_WireMethod *wm_tail = NULL; - json_t *jauth; + const json_t *jauth; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("payto_uris", - &payto_uris), GNUNET_JSON_spec_string ("id", (const char **) &is.id), GNUNET_JSON_spec_string ("name", (const char **) &is.name), - GNUNET_JSON_spec_mark_optional( + 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_mark_optional ( GNUNET_JSON_spec_string ("website", (const char **) &is.website), NULL), - GNUNET_JSON_spec_mark_optional( + GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_string ("logo", (const char **) &is.logo), NULL), - GNUNET_JSON_spec_json ("auth", - &jauth), + GNUNET_JSON_spec_object_const ("auth", + &jauth), GNUNET_JSON_spec_json ("address", &is.address), GNUNET_JSON_spec_json ("jurisdiction", &is.jurisdiction), - TALER_JSON_spec_amount ("default_max_wire_fee", - TMH_currency, - &is.default_max_wire_fee), - GNUNET_JSON_spec_uint32 ("default_wire_fee_amortization", - &is.default_wire_fee_amortization), - TALER_JSON_spec_amount ("default_max_deposit_fee", - TMH_currency, - &is.default_max_deposit_fee), + GNUNET_JSON_spec_bool ("use_stefan", + &is.use_stefan), GNUNET_JSON_spec_relative_time ("default_wire_transfer_delay", &is.default_wire_transfer_delay), GNUNET_JSON_spec_relative_time ("default_pay_delay", @@ -203,6 +103,19 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, ? MHD_YES : MHD_NO; } + if (NULL == uts) + uts = "business"; + if (GNUNET_OK != + TALER_KYCLOGIC_kyc_user_type_from_string (uts, + &is.ut)) + { + GNUNET_break_op (0); + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "user_type"); + } { enum GNUNET_GenericReturnValue ret; @@ -211,16 +124,12 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, jauth, &auth_token); if (GNUNET_OK != ret) + { + GNUNET_JSON_parse_free (spec); return (GNUNET_NO == ret) ? MHD_YES : MHD_NO; + } } - /* check payto_uris for well-formedness */ - if (! TMH_payto_uri_array_valid (payto_uris)) - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_BAD_REQUEST, - TALER_EC_GENERIC_PAYTO_URI_MALFORMED, - NULL); - /* check 'id' well-formed */ { static bool once; @@ -229,6 +138,7 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, if (! once) { + once = true; GNUNET_assert (0 == regcomp (®, "^[A-Za-z0-9][A-Za-z0-9_.@-]+$", @@ -240,10 +150,13 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, 0, NULL, 0)) id_wellformed = false; if (! id_wellformed) + { + GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, TALER_EC_GENERIC_PARAMETER_MALFORMED, "id"); + } } if (! TMH_location_object_valid (is.address)) @@ -297,18 +210,18 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, is.id)) && (0 == strcmp (mi->settings.name, is.name)) && - ((mi->settings.email == is.email) || - (NULL != is.email && NULL != mi->settings.email && - 0 == strcmp (mi->settings.email, - is.email))) && - ((mi->settings.website == is.website) || - (NULL != is.website && NULL != mi->settings.website && - 0 == strcmp (mi->settings.website, - is.website))) && - ((mi->settings.logo == is.logo) || - (NULL != is.logo && NULL != mi->settings.logo && - 0 == strcmp (mi->settings.logo, - is.logo))) && + ((mi->settings.email == is.email) || + (NULL != is.email && NULL != mi->settings.email && + 0 == strcmp (mi->settings.email, + is.email))) && + ((mi->settings.website == is.website) || + (NULL != is.website && NULL != mi->settings.website && + 0 == strcmp (mi->settings.website, + is.website))) && + ((mi->settings.logo == is.logo) || + (NULL != is.logo && NULL != mi->settings.logo && + 0 == strcmp (mi->settings.logo, + is.logo))) && ( ( (NULL != auth_token) && (GNUNET_OK == TMH_check_auth (auth_token, @@ -321,26 +234,13 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, is.address)) && (1 == json_equal (mi->settings.jurisdiction, is.jurisdiction)) && - (GNUNET_OK == TALER_amount_cmp_currency ( - &mi->settings.default_max_deposit_fee, - &is.default_max_deposit_fee)) && - (0 == TALER_amount_cmp (&mi->settings.default_max_deposit_fee, - &is.default_max_deposit_fee)) && - (GNUNET_OK == TALER_amount_cmp_currency ( - &mi->settings.default_max_wire_fee, - &is.default_max_wire_fee)) && - (0 == TALER_amount_cmp (&mi->settings.default_max_wire_fee, - &is.default_max_wire_fee)) && - (mi->settings.default_wire_fee_amortization == - is.default_wire_fee_amortization) && + (mi->settings.use_stefan == is.use_stefan) && (GNUNET_TIME_relative_cmp (mi->settings.default_wire_transfer_delay, ==, is.default_wire_transfer_delay)) && (GNUNET_TIME_relative_cmp (mi->settings.default_pay_delay, ==, - is.default_pay_delay)) && - (accounts_equal (mi, - payto_uris)) ) + is.default_pay_delay)) ) { GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_static (connection, @@ -349,31 +249,11 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, NULL, 0); } - else - { - GNUNET_JSON_parse_free (spec); - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_CONFLICT, - TALER_EC_MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS, - is.id); - } - } - } - - /* convert provided payto URIs into internal data structure with salts */ - { - unsigned int len = json_array_size (payto_uris); - - for (unsigned int i = 0; i<len; i++) - { - json_t *payto_uri = json_array_get (payto_uris, - i); - struct TMH_WireMethod *wm; - - wm = TMH_setup_wire_account (json_string_value (payto_uri)); - GNUNET_CONTAINER_DLL_insert (wm_head, - wm_tail, - wm); + GNUNET_JSON_parse_free (spec); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_CONFLICT, + TALER_EC_MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS, + is.id); } } @@ -425,8 +305,8 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, TMH_db->start (TMH_db->cls, "post /instances")) { - GNUNET_JSON_parse_free (spec); - free_mi (mi); + mi->rc = 1; + TMH_instance_decref (mi); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_START_FAILED, @@ -437,45 +317,41 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh, &mi->merchant_priv, &mi->settings, &mi->auth); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) - { - MHD_RESULT ret; - - TMH_db->rollback (TMH_db->cls); - if (GNUNET_DB_STATUS_SOFT_ERROR == qs) - goto retry; - ret = TALER_MHD_reply_with_error (connection, - MHD_HTTP_CONFLICT, - TALER_EC_MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS, - is.id); - GNUNET_JSON_parse_free (spec); - free_mi (mi); - return ret; - } - for (struct TMH_WireMethod *wm = wm_head; - NULL != wm; - wm = wm->next) - { - struct TALER_MERCHANTDB_AccountDetails ad = { - .payto_uri = wm->payto_uri, - .salt = wm->wire_salt, - .h_wire = wm->h_wire, - .active = wm->active - }; - - qs = TMH_db->insert_account (TMH_db->cls, - mi->settings.id, - &ad); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) - break; - } - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + switch (qs) { - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); - TMH_db->rollback (TMH_db->cls); - if (GNUNET_DB_STATUS_HARD_ERROR == qs) - break; + case GNUNET_DB_STATUS_HARD_ERROR: + { + MHD_RESULT ret; + + TMH_db->rollback (TMH_db->cls); + GNUNET_break (0); + ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_STORE_FAILED, + is.id); + mi->rc = 1; + TMH_instance_decref (mi); + return ret; + } + case GNUNET_DB_STATUS_SOFT_ERROR: goto retry; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + { + MHD_RESULT ret; + + TMH_db->rollback (TMH_db->cls); + GNUNET_break (0); + ret = TALER_MHD_reply_with_error (connection, + MHD_HTTP_CONFLICT, + TALER_EC_MERCHANT_PRIVATE_POST_INSTANCES_ALREADY_EXISTS, + is.id); + mi->rc = 1; + TMH_instance_decref (mi); + return ret; + } + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + /* handled below */ + break; } qs = TMH_db->commit (TMH_db->cls); if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) @@ -486,8 +362,8 @@ retry: } /* for .. MAX_RETRIES */ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) { - GNUNET_JSON_parse_free (spec); - free_mi (mi); + mi->rc = 1; + TMH_instance_decref (mi); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_GENERIC_DB_COMMIT_FAILED, @@ -498,7 +374,6 @@ retry: TMH_add_instance (mi)); TMH_reload_instances (mi->settings.id); } - GNUNET_JSON_parse_free (spec); if (0 == strcmp (is.id, "default")) { |