2018-04-02 14:24:45 +02:00
|
|
|
/*
|
|
|
|
This file is part of TALER
|
|
|
|
Copyright (C) 2018 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
|
|
|
|
Foundation; either version 3, or (at your option) any later version.
|
|
|
|
|
|
|
|
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
|
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
|
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* @file exchangedb/exchangedb_accounts.c
|
|
|
|
* @brief Logic to parse account information from the configuration
|
|
|
|
* @author Christian Grothoff
|
|
|
|
*/
|
|
|
|
#include "platform.h"
|
|
|
|
#include "taler_exchangedb_lib.h"
|
|
|
|
|
|
|
|
|
2020-03-12 10:11:24 +01:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
static struct TALER_EXCHANGEDB_WireAccount *wa_tail;
|
|
|
|
|
|
|
|
|
2018-04-02 14:24:45 +02:00
|
|
|
/**
|
|
|
|
* Closure of #check_for_account.
|
|
|
|
*/
|
|
|
|
struct FindAccountContext
|
|
|
|
{
|
|
|
|
/**
|
2020-03-31 20:57:11 +02:00
|
|
|
* Configuration we are using.
|
2018-04-02 14:24:45 +02:00
|
|
|
*/
|
|
|
|
const struct GNUNET_CONFIGURATION_Handle *cfg;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Callback to invoke.
|
|
|
|
*/
|
|
|
|
TALER_EXCHANGEDB_AccountCallback cb;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Closure for @e cb.
|
|
|
|
*/
|
|
|
|
void *cb_cls;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2020-03-07 00:28:07 +01:00
|
|
|
* 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.
|
2018-04-02 14:24:45 +02:00
|
|
|
*
|
2020-03-07 00:28:07 +01:00
|
|
|
* @param cls our `struct FindAccountContext`
|
2018-04-02 14:24:45 +02:00
|
|
|
* @param section name of a section in the configuration
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
check_for_account (void *cls,
|
|
|
|
const char *section)
|
|
|
|
{
|
|
|
|
struct FindAccountContext *ctx = cls;
|
2020-01-11 15:19:56 +01:00
|
|
|
char *method;
|
2020-01-19 17:03:19 +01:00
|
|
|
char *payto_uri;
|
2018-04-02 14:24:45 +02:00
|
|
|
char *wire_response_filename;
|
|
|
|
|
|
|
|
if (0 != strncasecmp (section,
|
2020-01-19 18:48:14 +01:00
|
|
|
"exchange-account-",
|
|
|
|
strlen ("exchange-account-")))
|
2018-04-02 14:24:45 +02:00
|
|
|
return;
|
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_string (ctx->cfg,
|
|
|
|
section,
|
2020-01-19 17:03:19 +01:00
|
|
|
"PAYTO_URI",
|
|
|
|
&payto_uri))
|
2018-04-02 14:24:45 +02:00
|
|
|
{
|
|
|
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
|
|
|
|
section,
|
2020-01-19 17:03:19 +01:00
|
|
|
"PAYTO_URI");
|
2018-04-02 14:24:45 +02:00
|
|
|
return;
|
|
|
|
}
|
2020-01-19 19:12:47 +01:00
|
|
|
method = TALER_payto_get_method (payto_uri);
|
|
|
|
if (NULL == method)
|
2018-04-02 14:24:45 +02:00
|
|
|
{
|
2020-01-19 19:12:47 +01:00
|
|
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
|
|
|
"payto URI in config ([%s]/PAYTO_URI) malformed\n",
|
|
|
|
section);
|
2020-01-19 17:03:19 +01:00
|
|
|
GNUNET_free (payto_uri);
|
2018-04-02 14:24:45 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_filename (ctx->cfg,
|
|
|
|
section,
|
|
|
|
"WIRE_RESPONSE",
|
|
|
|
&wire_response_filename))
|
|
|
|
wire_response_filename = NULL;
|
2020-01-20 01:23:02 +01:00
|
|
|
{
|
|
|
|
struct TALER_EXCHANGEDB_AccountInfo ai = {
|
|
|
|
.section_name = section,
|
|
|
|
.method = method,
|
|
|
|
.payto_uri = payto_uri,
|
|
|
|
.wire_response_filename = wire_response_filename,
|
|
|
|
.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);
|
|
|
|
}
|
2020-01-19 17:03:19 +01:00
|
|
|
GNUNET_free (payto_uri);
|
2020-01-11 15:19:56 +01:00
|
|
|
GNUNET_free (method);
|
2020-07-05 16:56:41 +02:00
|
|
|
GNUNET_free (wire_response_filename);
|
2018-04-02 14:24:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse the configuration to find account information.
|
|
|
|
*
|
|
|
|
* @param cfg configuration to use
|
|
|
|
* @param cb callback to invoke
|
|
|
|
* @param cb_cls closure for @a cb
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
TALER_EXCHANGEDB_find_accounts (const struct GNUNET_CONFIGURATION_Handle *cfg,
|
|
|
|
TALER_EXCHANGEDB_AccountCallback cb,
|
|
|
|
void *cb_cls)
|
|
|
|
{
|
|
|
|
struct FindAccountContext ctx;
|
|
|
|
|
|
|
|
ctx.cfg = cfg;
|
|
|
|
ctx.cb = cb;
|
|
|
|
ctx.cb_cls = cb_cls;
|
|
|
|
GNUNET_CONFIGURATION_iterate_sections (cfg,
|
|
|
|
&check_for_account,
|
|
|
|
&ctx);
|
|
|
|
}
|
|
|
|
|
2019-10-31 12:59:50 +01:00
|
|
|
|
2020-03-12 10:11:24 +01:00
|
|
|
/**
|
|
|
|
* 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 *
|
|
|
|
TALER_EXCHANGEDB_find_account_by_method (const char *method)
|
|
|
|
{
|
|
|
|
for (struct TALER_EXCHANGEDB_WireAccount *wa = wa_head; NULL != wa; wa =
|
|
|
|
wa->next)
|
|
|
|
if (0 == strcmp (method,
|
|
|
|
wa->method))
|
|
|
|
return wa;
|
|
|
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
|
|
|
"No wire account known for method `%s'\n",
|
|
|
|
method);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 *
|
|
|
|
TALER_EXCHANGEDB_find_account_by_payto_uri (const char *url)
|
|
|
|
{
|
|
|
|
char *method;
|
|
|
|
struct TALER_EXCHANGEDB_WireAccount *wa;
|
|
|
|
|
|
|
|
method = TALER_payto_get_method (url);
|
|
|
|
if (NULL == method)
|
|
|
|
{
|
|
|
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
|
|
|
"Invalid payto:// URL `%s'\n",
|
|
|
|
url);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
wa = TALER_EXCHANGEDB_find_account_by_method (method);
|
|
|
|
GNUNET_free (method);
|
|
|
|
return wa;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function called with information about a wire account. Adds
|
|
|
|
* the account to our list.
|
|
|
|
*
|
|
|
|
* @param cls closure, a `struct GNUNET_CONFIGURATION_Handle`
|
|
|
|
* @param ai account information
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
add_account_cb (void *cls,
|
|
|
|
const struct TALER_EXCHANGEDB_AccountInfo *ai)
|
|
|
|
{
|
|
|
|
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
|
|
|
|
struct TALER_EXCHANGEDB_WireAccount *wa;
|
|
|
|
char *payto_uri;
|
|
|
|
|
|
|
|
(void) cls;
|
|
|
|
if (GNUNET_YES != ai->debit_enabled)
|
|
|
|
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,
|
|
|
|
"PAYTO_URI",
|
|
|
|
&payto_uri))
|
|
|
|
{
|
|
|
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
|
|
|
ai->section_name,
|
|
|
|
"PAYTO_URI");
|
|
|
|
GNUNET_free (wa);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
wa->method = TALER_payto_get_method (payto_uri);
|
|
|
|
if (NULL == wa->method)
|
|
|
|
{
|
|
|
|
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
|
|
|
ai->section_name,
|
|
|
|
"PAYTO_URI",
|
|
|
|
"could not obtain wire method from URI");
|
|
|
|
GNUNET_free (wa);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
GNUNET_free (payto_uri);
|
|
|
|
if (GNUNET_OK !=
|
|
|
|
TALER_BANK_auth_parse_cfg (cfg,
|
|
|
|
ai->section_name,
|
|
|
|
&wa->auth))
|
|
|
|
{
|
|
|
|
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
|
|
|
|
"Failed to load exchange account `%s'\n",
|
|
|
|
ai->section_name);
|
|
|
|
GNUNET_free (wa->method);
|
|
|
|
GNUNET_free (wa);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
TALER_EXCHANGEDB_find_accounts (cfg,
|
|
|
|
&add_account_cb,
|
|
|
|
(void *) cfg);
|
|
|
|
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;
|
|
|
|
|
|
|
|
while (NULL != (wa = wa_head))
|
|
|
|
{
|
|
|
|
GNUNET_CONTAINER_DLL_remove (wa_head,
|
|
|
|
wa_tail,
|
|
|
|
wa);
|
|
|
|
TALER_BANK_auth_free (&wa->auth);
|
|
|
|
TALER_EXCHANGEDB_fees_free (wa->af);
|
|
|
|
GNUNET_free (wa->section_name);
|
|
|
|
GNUNET_free (wa->method);
|
|
|
|
GNUNET_free (wa);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-02 14:24:45 +02:00
|
|
|
/* end of exchangedb_accounts.c */
|