From ba3f70390a1e7210195c41e3afa3e7fe1511eb96 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 3 Aug 2021 21:58:36 +0200 Subject: restructure configuration, move bank account credentials from exchange-account-XXX to exchange-accountcredentials-XXX --- src/exchangedb/exchangedb_accounts.c | 334 +++++++++++++++++------------------ 1 file changed, 162 insertions(+), 172 deletions(-) (limited to 'src/exchangedb') diff --git a/src/exchangedb/exchangedb_accounts.c b/src/exchangedb/exchangedb_accounts.c index e56839838..54204eaaf 100644 --- a/src/exchangedb/exchangedb_accounts.c +++ b/src/exchangedb/exchangedb_accounts.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2018 Taler Systems SA + Copyright (C) 2018-2021 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 @@ -23,150 +23,76 @@ /** - * Head of list of wire accounts of the exchange. - */ -static struct TALER_EXCHANGEDB_WireAccount *wa_head; - -/** - * Tail of list of wire accounts of the exchange. + * Information we keep for each supported account of the exchange. */ -static struct TALER_EXCHANGEDB_WireAccount *wa_tail; +struct WireAccount +{ + /** + * Accounts are kept in a DLL. + */ + struct WireAccount *next; + /** + * Plugins are kept in a DLL. + */ + struct WireAccount *prev; -/** - * Closure of #check_for_account. - */ -struct FindAccountContext -{ /** - * Configuration we are using. + * Externally visible account information. */ - const struct GNUNET_CONFIGURATION_Handle *cfg; + struct TALER_EXCHANGEDB_AccountInfo ai; /** - * Callback to invoke. + * Authentication data. Only parsed if + * #TALER_EXCHANGEDB_ALO_AUTHDATA was set. */ - TALER_EXCHANGEDB_AccountCallback cb; + struct TALER_BANK_AuthenticationData auth; /** - * Closure for @e cb. + * Name of the section that configures this account. */ - void *cb_cls; + char *section_name; /** - * Set to #GNUNET_SYSERR if the configuration is invalid. + * Name of the wire method underlying the account. */ - int res; + char *method; + }; /** - * Check if @a section begins with "exchange-account-", and if so if the - * "PAYTO_URI" is given. If not, a warning is printed, otherwise we also check - * if "ENABLE_CREDIT" or "ENABLE_DEBIT" options are set to "YES" and then call - * the callback in @a cls with all of the information gathered. - * - * @param cls our `struct FindAccountContext` - * @param section name of a section in the configuration + * Head of list of wire accounts of the exchange. */ -static void -check_for_account (void *cls, - const char *section) -{ - struct FindAccountContext *ctx = cls; - char *method; - char *payto_uri; - - if (0 != strncasecmp (section, - "exchange-account-", - strlen ("exchange-account-"))) - return; - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (ctx->cfg, - section, - "PAYTO_URI", - &payto_uri)) - { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, - section, - "PAYTO_URI"); - ctx->res = GNUNET_SYSERR; - return; - } - method = TALER_payto_get_method (payto_uri); - if (NULL == method) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "payto URI in config ([%s]/PAYTO_URI) malformed\n", - section); - ctx->res = GNUNET_SYSERR; - GNUNET_free (payto_uri); - return; - } - { - struct TALER_EXCHANGEDB_AccountInfo ai = { - .section_name = section, - .method = method, - .debit_enabled = (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno ( - ctx->cfg, - section, - "ENABLE_DEBIT")), - .credit_enabled = (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (ctx->cfg, - section, - "ENABLE_CREDIT")) - }; - - ctx->cb (ctx->cb_cls, - &ai); - } - GNUNET_free (payto_uri); - GNUNET_free (method); -} - +static struct WireAccount *wa_head; /** - * Parse the configuration to find account information. - * - * @param cfg configuration to use - * @param cb callback to invoke - * @param cb_cls closure for @a cb - * @return #GNUNET_OK if the configuration seems valid, #GNUNET_SYSERR if not + * Tail of list of wire accounts of the exchange. */ -int -TALER_EXCHANGEDB_find_accounts (const struct GNUNET_CONFIGURATION_Handle *cfg, - TALER_EXCHANGEDB_AccountCallback cb, +static struct WireAccount *wa_tail; + + +void +TALER_EXCHANGEDB_find_accounts (TALER_EXCHANGEDB_AccountCallback cb, void *cb_cls) { - struct FindAccountContext ctx = { - .cfg = cfg, - .cb = cb, - .cb_cls = cb_cls, - .res = GNUNET_OK - }; - - GNUNET_CONFIGURATION_iterate_sections (cfg, - &check_for_account, - &ctx); - return ctx.res; + for (struct WireAccount *wa = wa_head; + NULL != wa; + wa = wa->next) + cb (cb_cls, + &wa->ai); } -/** - * Find the wire plugin for the given payto:// URL - * - * @param method wire method we need an account for - * @return NULL on error - */ -struct TALER_EXCHANGEDB_WireAccount * +const struct TALER_EXCHANGEDB_AccountInfo * TALER_EXCHANGEDB_find_account_by_method (const char *method) { - for (struct TALER_EXCHANGEDB_WireAccount *wa = wa_head; NULL != wa; wa = - wa->next) + for (struct WireAccount *wa = wa_head; + NULL != wa; + wa = wa->next) if (0 == strcmp (method, wa->method)) - return wa; + return &wa->ai; GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No wire account known for method `%s'\n", method); @@ -174,17 +100,11 @@ TALER_EXCHANGEDB_find_account_by_method (const char *method) } -/** - * Find the wire plugin for the given payto:// URL - * - * @param url wire address we need an account for - * @return NULL on error - */ -struct TALER_EXCHANGEDB_WireAccount * +const struct TALER_EXCHANGEDB_AccountInfo * TALER_EXCHANGEDB_find_account_by_payto_uri (const char *url) { char *method; - struct TALER_EXCHANGEDB_WireAccount *wa; + const struct TALER_EXCHANGEDB_AccountInfo *ai; method = TALER_payto_get_method (url); if (NULL == method) @@ -194,107 +114,177 @@ TALER_EXCHANGEDB_find_account_by_payto_uri (const char *url) url); return NULL; } - wa = TALER_EXCHANGEDB_find_account_by_method (method); + ai = TALER_EXCHANGEDB_find_account_by_method (method); GNUNET_free (method); - return wa; + return ai; } +/** + * Closure for #add_account_cb(). + */ +struct LoaderContext +{ + /** + * Configuration to use. + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; + + /** + * true if we are to load the authentication data + * for the access to the bank account. + */ + bool load_auth_data; + + /** + * Load accounts enabled for CREDIT. + */ + bool credit; + + /** + * Load accounts enabled for DEBIT. + */ + bool debit; + + /** + * Loader status (set by callback). + */ + enum GNUNET_GenericReturnValue res; +}; + + /** * Function called with information about a wire account. Adds * the account to our list. * - * @param cls closure, a `struct GNUNET_CONFIGURATION_Handle` + * @param cls closure, a `struct LoaderContext` * @param ai account information */ static void add_account_cb (void *cls, - const struct TALER_EXCHANGEDB_AccountInfo *ai) + const char *section) { - const struct GNUNET_CONFIGURATION_Handle *cfg = cls; - struct TALER_EXCHANGEDB_WireAccount *wa; + struct LoaderContext *lc = cls; + const struct GNUNET_CONFIGURATION_Handle *cfg = lc->cfg; + struct WireAccount *wa; char *payto_uri; + char *method; + bool debit; + bool credit; - (void) cls; - if (GNUNET_YES != ai->debit_enabled) + if (0 != strncasecmp (section, + "exchange-account-", + strlen ("exchange-account-"))) + return; + + debit = (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (lc->cfg, + section, + "ENABLE_DEBIT")); + credit = (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (lc->cfg, + section, + "ENABLE_CREDIT")); + if (! ( ( (debit) && + (lc->debit) ) || + ( (credit) && + (lc->credit) ) ) ) return; /* not enabled for us, skip */ - wa = GNUNET_new (struct TALER_EXCHANGEDB_WireAccount); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, - ai->section_name, + section, "PAYTO_URI", &payto_uri)) { - GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - ai->section_name, + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, + section, "PAYTO_URI"); - GNUNET_free (wa); + lc->res = GNUNET_SYSERR; return; } - wa->method = TALER_payto_get_method (payto_uri); - if (NULL == wa->method) + method = TALER_payto_get_method (payto_uri); + GNUNET_free (payto_uri); + if (NULL == method) { - GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, - ai->section_name, - "PAYTO_URI", - "could not obtain wire method from URI"); - GNUNET_free (wa); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "payto URI in config ([%s]/PAYTO_URI) malformed\n", + section); + lc->res = GNUNET_SYSERR; return; } - GNUNET_free (payto_uri); - if (GNUNET_OK != - TALER_BANK_auth_parse_cfg (cfg, - ai->section_name, - &wa->auth)) + wa = GNUNET_new (struct WireAccount); + wa->section_name = GNUNET_strdup (section); + wa->method = method; + wa->ai.debit_enabled = debit; + wa->ai.credit_enabled = credit; + wa->ai.auth = NULL; + wa->ai.section_name = wa->section_name; + wa->ai.method = wa->method; + if (lc->load_auth_data) { - GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, - "Failed to load exchange account `%s'\n", - ai->section_name); - GNUNET_free (wa->method); - GNUNET_free (wa); - return; + char *csn; + + GNUNET_asprintf (&csn, + "exchange-accountcredentials-%s", + §ion[strlen ("exchange-account-")]); + if (GNUNET_OK != + TALER_BANK_auth_parse_cfg (cfg, + csn, + &wa->auth)) + { + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Failed to load exchange account credentials from section `%s'\n", + csn); + GNUNET_free (csn); + GNUNET_free (wa->section_name); + GNUNET_free (wa->method); + GNUNET_free (wa); + return; + } + wa->ai.auth = &wa->auth; + GNUNET_free (csn); } - wa->section_name = GNUNET_strdup (ai->section_name); GNUNET_CONTAINER_DLL_insert (wa_head, wa_tail, wa); } -/** - * Load account information opf the exchange from - * @a cfg. - * - * @param cfg configuration to load from - * @return #GNUNET_OK on success, #GNUNET_NO if no accounts are configured - */ -int -TALER_EXCHANGEDB_load_accounts (const struct GNUNET_CONFIGURATION_Handle *cfg) +enum GNUNET_GenericReturnValue +TALER_EXCHANGEDB_load_accounts ( + const struct GNUNET_CONFIGURATION_Handle *cfg, + enum TALER_EXCHANGEDB_AccountLoaderOptions options) { - TALER_EXCHANGEDB_find_accounts (cfg, - &add_account_cb, - (void *) cfg); + struct LoaderContext lc = { + .cfg = cfg, + .debit = 0 != (options & TALER_EXCHANGEDB_ALO_DEBIT), + .credit = 0 != (options & TALER_EXCHANGEDB_ALO_CREDIT), + .load_auth_data = 0 != (options & TALER_EXCHANGEDB_ALO_AUTHDATA), + }; + + GNUNET_CONFIGURATION_iterate_sections (cfg, + &add_account_cb, + &lc); + if (GNUNET_SYSERR == lc.res) + return GNUNET_SYSERR; if (NULL == wa_head) return GNUNET_NO; return GNUNET_OK; } -/** - * Free resources allocated by - * #TALER_EXCHANGEDB_load_accounts(). - */ void TALER_EXCHANGEDB_unload_accounts (void) { - struct TALER_EXCHANGEDB_WireAccount *wa; + struct WireAccount *wa; while (NULL != (wa = wa_head)) { GNUNET_CONTAINER_DLL_remove (wa_head, wa_tail, wa); - TALER_BANK_auth_free (&wa->auth); + if (NULL != wa->ai.auth) + TALER_BANK_auth_free (&wa->auth); GNUNET_free (wa->section_name); GNUNET_free (wa->method); GNUNET_free (wa); -- cgit v1.2.3