commit 123c4a344533f83ce5d5933404bf6e4a82715573
parent 2b5d168b9589b1ee38405d72dee52866217bd685
Author: Tellenbach Reto <tellr1@bfh.ch>
Date: Sun, 31 May 2026 09:15:43 +0200
[new] thinker_TalerAPI: pars get_config response
Diffstat:
5 files changed, 257 insertions(+), 89 deletions(-)
diff --git a/thinker/taler_api/src/lib/CMakeLists.txt b/thinker/taler_api/src/lib/CMakeLists.txt
@@ -3,8 +3,9 @@ add_library(bank bank_api_get_config.c bank_api_curl_defaults.c)
find_package(CURL REQUIRED)
pkg_check_modules(GNUNET REQUIRED gnunetutil)
+pkg_check_modules(LIBMICROHTTPD REQUIRED libmicrohttpd)
target_link_libraries(bank
- PUBLIC CURL::libcurl gnunetutil talerutil
+ PUBLIC CURL::libcurl gnunetutil talerutil microhttpd
PRIVATE talercurl talerjson gnunetutil gnunetcurl gnunetjson jansson
)
\ No newline at end of file
diff --git a/thinker/taler_api/src/lib/bank_api_get_config.c b/thinker/taler_api/src/lib/bank_api_get_config.c
@@ -1,5 +1,7 @@
+#include <microhttpd.h>
#include "bank_api_get_config.h"
#include "bank_api_curl_defaults.h"
+#include "taler/taler_json_lib.h"
/**
* Which revision of the Taler core-bank protocol is implemented
@@ -14,6 +16,19 @@
/**
+ * Log error related to CURL operations.
+ *
+ * @param type log level
+ * @param function which function failed to run
+ * @param code what was the curl error code
+ */
+#define CURL_STRERROR(type, function, code) \
+ GNUNET_log (type, \
+ "Curl function `%s' has failed at `%s:%d' with error: %s", \
+ function, __FILE__, __LINE__, curl_easy_strerror (code));
+
+
+/**
* Handle for the get config request.
*/
struct TALER_BANK_GetConfigHandle
@@ -24,7 +39,7 @@ struct TALER_BANK_GetConfigHandle
struct GNUNET_CURL_Context *ctx;
/**
- * Function to call with the auditor's certification data,
+ * Function to call with the ,
* NULL if this has already been done.
*/
TALER_BANK_ConfigCallback config_cb;
@@ -46,33 +61,174 @@ struct TALER_BANK_GetConfigHandle
char *job_url;
};
+
+/**
+ * Decode the JSON in @a resp_obj from the /config response
+ *
+ * @param[in] resp_obj JSON object to parse
+ * @param[in,out] vi where to store the results we decoded
+ * @param[out] vc where to store config compatibility data
+ * @return #TALER_EC_NONE on success
+ */
+static enum TALER_ErrorCode
+decode_config_json (const json_t *resp_obj,
+ struct TALER_BANK_ConfigInformation *vi,
+ enum TALER_BANK_VersionCompatibility *vc)
+{
+ struct TALER_JSON_ProtocolVersion pv;
+ const char *ver;
+ bool bank_name_missing;
+
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_version ("version",
+ &pv),
+ GNUNET_JSON_spec_string ("version",
+ &ver),
+ GNUNET_JSON_spec_string ("currency",
+ &vi->currency),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("bank_name",
+ &vi->bank_name),
+ &bank_name_missing),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (JSON_OBJECT != json_typeof (resp_obj))
+ {
+ GNUNET_break_op (0);
+ return TALER_EC_GENERIC_JSON_INVALID;
+ }
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (resp_obj,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ return TALER_EC_GENERIC_JSON_INVALID;
+ }
+
+ /* Set default fot optional values */
+ if (bank_name_missing)
+ {
+ vi->bank_name = GNUNET_strdup("Taler Bank");
+ }
+
+ /* Version comparison */
+ vi->version = ver;
+ *vc = TALER_BANK_VC_MATCH;
+ if (TALER_PROTOCOL_CURRENT < pv.current)
+ {
+ *vc |= TALER_BANK_VC_NEWER;
+ if (TALER_PROTOCOL_CURRENT < pv.current - pv.age)
+ *vc |= TALER_BANK_VC_INCOMPATIBLE;
+ }
+ if (TALER_PROTOCOL_CURRENT > pv.current)
+ {
+ *vc |= TALER_BANK_VC_OLDER;
+ if (TALER_PROTOCOL_CURRENT - TALER_PROTOCOL_AGE > pv.current)
+ *vc |= TALER_BANK_VC_INCOMPATIBLE;
+ }
+
+ struct GNUNET_JSON_Specification spec2[] = {
+ GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_amount ("min_wire_transfer_amount",
+ vi->currency,
+ &vi->min_wire_transfer_amount),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_amount ("max_wire_transfer_amount",
+ vi->currency,
+ &vi->max_wire_transfer_amount),
+ NULL),
+ TALER_JSON_spec_currency_specification ("currency_specification",
+ vi->currency,
+ &vi->currency_specification),
+ GNUNET_JSON_spec_mark_optional (
+ TALER_JSON_spec_amount("wire_transfer_fees",
+ vi->currency,
+ &vi->wire_transfer_fees),
+ NULL),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (resp_obj,
+ spec2,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ return TALER_EC_GENERIC_JSON_INVALID;
+ }
+
+ return TALER_EC_NONE;
+}
+
+
/**
* Callback used when http reply arived to a /config request.
*
* @param cls the `struct TALER_BANK_GetConfigHandle`
* @param response_code HTTP response code or 0 on error
- * @param gresp_obj parsed JSON result, NULL on error, must be a `const json_t *`
+ * @param gresp_obj JSON result, NULL on error, must be a `const json_t *`
*/
static void
response_cb(void *cls,
long response_code,
- const void *response)
+ const void *gresp_obj)
{
struct TALER_BANK_GetConfigHandle *bank = cls;
- const json_t *resp_obj = response;
+ const json_t *resp_obj = gresp_obj;
- struct TALER_BANK_ConfigResponse vr = {
+ struct TALER_BANK_ConfigResponse cr = {
.hr.response = resp_obj,
.hr.http_status = (unsigned int)response_code
};
- bank->job = NULL;
+ bank->job = NULL; //job was successfull, curl job cancel not needed anymore in cleanup
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received config from URL `%s' with status %ld.\n",
bank->job_url,
response_code);
+
+ switch (response_code)
+ {
+ case 0:
+ GNUNET_break_op (0);
+ cr.hr.ec = TALER_EC_INVALID;
+ break;
+ case MHD_HTTP_OK:
+ if (NULL == resp_obj)
+ {
+ GNUNET_break_op (0);
+ cr.hr.http_status = 0;
+ cr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ break;
+ }
+ cr.hr.ec = decode_config_json (resp_obj,
+ &cr.details.ok.configi,
+ &cr.details.ok.version_compa);
+ if (TALER_EC_NONE != cr.hr.ec)
+ {
+ GNUNET_break_op (0);
+ cr.hr.http_status = 0;
+ break;
+ }
+ break;
+ case MHD_HTTP_INTERNAL_SERVER_ERROR:
+ cr.hr.ec = TALER_JSON_get_error_code (resp_obj);
+ cr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
+ break;
+ default:
+ cr.hr.ec = TALER_JSON_get_error_code (resp_obj);
+ cr.hr.hint = TALER_JSON_get_error_hint (resp_obj);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u/%d\n",
+ (unsigned int) response_code,
+ (int) cr.hr.ec);
+ break;
+ }
- bank->config_cb (bank->config_cb_cls, &vr);
+ bank->config_cb (bank->config_cb_cls, &cr);
TALER_BANK_get_config_cancel(bank);
}
diff --git a/thinker/taler_api/src/lib/bank_api_get_config.h b/thinker/taler_api/src/lib/bank_api_get_config.h
@@ -9,10 +9,6 @@
*/
struct TALER_BANK_ConfigInformation
{
- /**
- * Name of api
- */
- const char *api_name;
/**
* Supported Taler protocol version by the bank.
@@ -23,88 +19,93 @@ struct TALER_BANK_ConfigInformation
const char *version;
/**
- * Bank display name to be used in user interfaces.
- * For consistency use "Taler Bank" if missing.
+ * Currency used by this bank.
*/
- const char *bank_name;
+ const char *currency;
/**
- * Advertised base URL to use when you sharing an URL with another program.
- */
- const char *base_url;
-
- /** If 'true' the server provides local currency conversion support
- * If 'false' some parts of the API are not supported and return 501
- */
- const bool allow_conversion;
-
- /** If 'true' anyone can register
- * If 'false' only admin can
+ * Minimum wire transfer amount allowed. Only applies to bank transactions and withdrawals.
*/
- const bool allow_registrations;
+ struct TALER_Amount min_wire_transfer_amount;
/**
- * If 'true' account can delete themselves
- * If 'false' only admin can delete accounts
+ * Maximum wire transfer amount allowed. Only applies to bank transactions and withdrawals.
*/
- const bool allow_deletions;
-
- /**
- * If 'true' anyone can edit their name
- * If 'false' only admin can
- */
- const bool allow_edit_name;
-
- /**
- * If 'true' anyone can edit their cashout account
- * If 'false' only admin can
- */
- const bool allow_edit_cashout_payto_uri;
-
- /**
- * Default debt limit for newly created accounts
- */
- const struct TALER_AmountNBO default_debit_threshold;
-
-
- /**
- * Currency used by this bank.
- */
- const char *currency;
+ struct TALER_Amount max_wire_transfer_amount;
/**
* How the bank SPA should render this currency.
*/
- const struct TALER_CurrencySpecification currency_specification;
+ struct TALER_CurrencySpecification currency_specification;
- /**
- * Stand in string for the TAN channel. Not used in the callbacks
- * when used needs to be addapted
- * TAN channels supported by the server
- */
- const char *supported_tan_channels;
-
- /**
- * Wire transfer type supported by the bank.
- * Defaults to 'iban' is missing
+ /**
+ * Bank display name to be used in user interfaces.
+ * For consistency use "Taler Bank" if missing.
*/
- const char *wire_type;
+ const char *bank_name;
/**
* Wire transfer execution fees. Only applies to bank transactions and withdrawals.
*/
- const struct TALER_AmountNBO wire_transfer_fees;
-
- /**
- * Minimum wire transfer amount allowed. Only applies to bank transactions and withdrawals.
- */
- const struct TALER_AmountNBO min_wire_transfer_amount;
+ struct TALER_Amount wire_transfer_fees;
+
+ // /**
+ // * Name of api
+ // */
+ // const char *api_name;
+
+
+ // /**
+ // * Advertised base URL to use when you sharing an URL with another program.
+ // */
+ // const char *base_url;
+
+ // /** If 'true' the server provides local currency conversion support
+ // * If 'false' some parts of the API are not supported and return 501
+ // */
+ // const bool allow_conversion;
+
+ // /** If 'true' anyone can register
+ // * If 'false' only admin can
+ // */
+ // const bool allow_registrations;
+
+ // /**
+ // * If 'true' account can delete themselves
+ // * If 'false' only admin can delete accounts
+ // */
+ // const bool allow_deletions;
+
+ // /**
+ // * If 'true' anyone can edit their name
+ // * If 'false' only admin can
+ // */
+ // const bool allow_edit_name;
+
+ // /**
+ // * If 'true' anyone can edit their cashout account
+ // * If 'false' only admin can
+ // */
+ // const bool allow_edit_cashout_payto_uri;
+
+ // /**
+ // * Default debt limit for newly created accounts
+ // */
+ // const struct TALER_AmountNBO default_debit_threshold;
+
+ // /**
+ // * Stand in string for the TAN channel. Not used in the callbacks
+ // * when used needs to be addapted
+ // * TAN channels supported by the server
+ // */
+ // const char *supported_tan_channels;
+
+ // /**
+ // * Wire transfer type supported by the bank.
+ // * Defaults to 'iban' is missing
+ // */
+ // const char *wire_type;
-
- /**
- * Maximum wire transfer amount allowed. Only applies to bank transactions and withdrawals.
- */
- const struct TALER_AmountNBO max_wire_transfer_amount;
};
/**
@@ -130,6 +131,14 @@ struct TALER_BANK_ConfigResponse
struct
{
+ /**
+ * Protocol compatibility evaluation.
+ */
+ enum TALER_BANK_VersionCompatibility version_compa;
+
+ /**
+ * Config data returned by /config.
+ */
struct TALER_BANK_ConfigInformation configi;
} ok;
@@ -159,6 +168,9 @@ struct TALER_BANK_GetConfigHandle;
/**
* Obtain config inforamtion about the connected Bank
+ * @param ctx
+ * @param url
+ * @return NULL on failure
*/
struct TALER_BANK_GetConfigHandle *
TALER_BANK_get_config ( struct GNUNET_CURL_Context *ctx,
diff --git a/thinker/taler_api/src/taler-digitizer.c b/thinker/taler_api/src/taler-digitizer.c
@@ -64,20 +64,10 @@ static struct GNUNET_CURL_RescheduleContext *reschedule_ctx;
*/
static struct TALER_BANK_GetConfigHandle *get_config_handle;
-/**
- * All the variables needed in run() that must be cleaned in shutdown
- */
-struct TALER_DIGITIZER_State
-{
- struct GNUNET_CURL_Context *curl_ctx;
- struct GNUNET_CURL_RescheduleContext *reschedule_ctx;
- struct TALER_BANK_GetConfigHandle *get_config_handle;
-};
-
static void
-after_get_config (void *cls,
- const struct TALER_BANK_ConfigResponse *vr)
+on_config_received (void *cls,
+ const struct TALER_BANK_ConfigResponse *vr)
{
(void) cls;
(void) vr;
@@ -86,6 +76,7 @@ after_get_config (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Config Callback\n");
+
GNUNET_SCHEDULER_shutdown ();
}
@@ -230,8 +221,10 @@ run (void *cls,
get_config_handle = TALER_BANK_get_config (curl_ctx,
cfg_backend_base_url,
- &after_get_config,
+ &on_config_received,
NULL);
+
+
return;
}
diff --git a/thinker/taler_api/src/taler/taler_digitizer_service.h b/thinker/taler_api/src/taler/taler_digitizer_service.h
@@ -70,6 +70,12 @@ struct TALER_BANK_HttpResponse
*/
const json_t *response;
+ /**
+ * Set to the human-readable 'hint' that is optionally
+ * provided by the exchange together with errors. NULL
+ * if no hint was provided or if there was no error.
+ */
+ const char *hint;
/**
* HTTP status code for the response.