aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-09-10 12:07:49 +0200
committerChristian Grothoff <christian@grothoff.org>2024-09-10 12:07:49 +0200
commita1c13db558cee1cd6f69a690a0525513006f3565 (patch)
treec714efef1c072f39a02f4cfd3d9a362eb05c1d2d
parente04ba8974b1b7a1690ffacb52ba2fb3588f49a6d (diff)
refactor to use new exchange convenience API to check account restrictions
-rw-r--r--configure.ac24
-rw-r--r--src/backend/taler-merchant-httpd_exchanges.c294
-rw-r--r--src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c50
-rw-r--r--src/backend/taler-merchant-httpd_private-patch-products-ID.c2
-rw-r--r--src/backend/taler-merchant-httpd_qr.c2
-rw-r--r--src/backend/taler-merchant-kyccheck.c53
6 files changed, 52 insertions, 373 deletions
diff --git a/configure.ac b/configure.ac
index bc6b9b0c..d530f71c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -263,6 +263,30 @@ AS_IF([test $libtalerutil != 1],
*** https://taler.net
*** ]])])
+libtalerexchange=0
+AC_MSG_CHECKING([for libtalerexchange])
+AC_ARG_WITH(exchange,
+ [AS_HELP_STRING([--with-exchange=PFX], [base of Taler EXCHANGE installation])],
+ [AC_MSG_RESULT([given as $with_exchange])],
+ [AC_MSG_RESULT(not given)
+ with_exchange=yes])
+AS_CASE([$with_exchange],
+ [yes], [],
+ [no], [AC_MSG_ERROR([--with-exchange is required])],
+ [LDFLAGS="-L$with_exchange/lib $LDFLAGS"
+ CPPFLAGS="-I$with_exchange/include $CPPFLAGS $POSTGRESQL_CPPFLAGS"])
+
+AC_CHECK_HEADERS([taler/taler_exchange_service.h],
+ [AC_CHECK_LIB([talerexchange], [TALER_EXCHANGE_test_account_allowed], libtalerexchange=1)])
+AM_CONDITIONAL(HAVE_TALEREXCHANGE, test x$libtalerexchange = x1)
+AS_IF([test $libtalerexchange != 1],
+ [AC_MSG_ERROR([[
+***
+*** You need libtalerexchange >= 0.14.0 to build this program.
+*** This library is part of the GNU Taler exchange, available at
+*** https://taler.net
+*** ]])])
+
libtalermhd=0
AC_MSG_CHECKING([for libtalermhd])
diff --git a/src/backend/taler-merchant-httpd_exchanges.c b/src/backend/taler-merchant-httpd_exchanges.c
index d1397870..d36ce581 100644
--- a/src/backend/taler-merchant-httpd_exchanges.c
+++ b/src/backend/taler-merchant-httpd_exchanges.c
@@ -116,87 +116,6 @@ struct FeesByWireMethod
/**
- * Restriction that applies to an exchange account.
- */
-struct Restriction
-{
- /**
- * Kept in a DLL.
- */
- struct Restriction *next;
-
- /**
- * Kept in a DLL.
- */
- struct Restriction *prev;
-
- /**
- * Type of restriction imposed on the account.
- */
- enum TALER_EXCHANGE_AccountRestrictionType type;
-
- /**
- * Details depending on @e type.
- */
- union
- {
-
- /**
- * Accounts must match the given regular expression.
- */
- struct
- {
-
- /**
- * Pre-compiled regex.
- */
- regex_t ex;
-
- } regex;
-
- } details;
-};
-
-
-/**
- * Information about a bank account of the exchange.
- */
-struct ExchangeAccount
-{
- /**
- * Kept in a DLL.
- */
- struct ExchangeAccount *next;
-
- /**
- * Kept in a DLL.
- */
- struct ExchangeAccount *prev;
-
- /**
- * Wire method of this exchange account.
- */
- char *wire_method;
-
- /**
- * Currency conversion that applies to this account,
- * NULL if none.
- */
- char *conversion_url;
-
- /**
- * Head of DLL of debit restrictions of this account.
- */
- struct Restriction *d_head;
-
- /**
- * Tail of DLL of debit restrictions of this account.
- */
- struct Restriction *d_tail;
-};
-
-
-/**
* Internal representation for an exchange
*/
struct TMH_Exchange
@@ -223,16 +142,6 @@ struct TMH_Exchange
struct TMH_EXCHANGES_KeysOperation *keys_tail;
/**
- * Head of accounts of this exchange.
- */
- struct ExchangeAccount *acc_head;
-
- /**
- * Tail of accounts of this exchange.
- */
- struct ExchangeAccount *acc_tail;
-
- /**
* (base) URL of the exchange.
*/
char *url;
@@ -330,61 +239,6 @@ TMH_EXCHANGES_get_currency (
/**
- * Free data structures within @a ea, but not @a ea
- * pointer itself.
- *
- * @param[in] ea data structure to free
- */
-static void
-free_exchange_account (struct ExchangeAccount *ea)
-{
- struct Restriction *r;
-
- while (NULL != (r = ea->d_head))
- {
- GNUNET_CONTAINER_DLL_remove (ea->d_head,
- ea->d_tail,
- r);
- switch (r->type)
- {
- case TALER_EXCHANGE_AR_INVALID:
- GNUNET_assert (0);
- break;
- case TALER_EXCHANGE_AR_DENY:
- break;
- case TALER_EXCHANGE_AR_REGEX:
- regfree (&r->details.regex.ex);
- break;
- }
- GNUNET_free (r);
- }
- GNUNET_free (ea->wire_method);
- GNUNET_free (ea->conversion_url);
-}
-
-
-/**
- * Free list of all accounts in @a exchange.
- *
- * @param[in,out] exchange entry to free accounts for
- */
-static void
-purge_exchange_accounts (struct TMH_Exchange *exchange)
-{
- struct ExchangeAccount *acc;
-
- while (NULL != (acc = exchange->acc_head))
- {
- GNUNET_CONTAINER_DLL_remove (exchange->acc_head,
- exchange->acc_tail,
- acc);
- free_exchange_account (acc);
- GNUNET_free (acc);
- }
-}
-
-
-/**
* Lookup exchange by @a exchange_url. Create one
* if it does not exist.
*
@@ -412,71 +266,6 @@ lookup_exchange (const char *exchange_url)
/**
- * Set the list of accounts of @a exchange.
- *
- * @param[in,out] exchange exchange to initialize or update
- * @param accounts_len length of @a accounts array
- * @param accounts array of accounts to convert
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-set_exchange_accounts (
- struct TMH_Exchange *exchange,
- unsigned int accounts_len,
- const struct TALER_EXCHANGE_WireAccount accounts[static accounts_len])
-{
- enum GNUNET_GenericReturnValue ret = GNUNET_OK;
-
- purge_exchange_accounts (exchange);
- for (unsigned int i = 0; i<accounts_len; i++)
- {
- const struct TALER_EXCHANGE_WireAccount *account = &accounts[i];
- struct ExchangeAccount *acc;
-
- acc = GNUNET_new (struct ExchangeAccount);
- acc->wire_method = TALER_payto_get_method (account->payto_uri);
- if (NULL != account->conversion_url)
- acc->conversion_url = GNUNET_strdup (account->conversion_url);
- GNUNET_CONTAINER_DLL_insert (exchange->acc_head,
- exchange->acc_tail,
- acc);
- for (unsigned int j = 0; j<account->debit_restrictions_length; j++)
- {
- const struct TALER_EXCHANGE_AccountRestriction *ar =
- &account->debit_restrictions[j];
- struct Restriction *r;
-
- r = GNUNET_new (struct Restriction);
- r->type = ar->type;
- switch (ar->type)
- {
- case TALER_EXCHANGE_AR_INVALID:
- GNUNET_assert (0);
- break;
- case TALER_EXCHANGE_AR_DENY:
- break;
- case TALER_EXCHANGE_AR_REGEX:
- if (0 != regcomp (&r->details.regex.ex,
- ar->details.regex.posix_egrep,
- REG_NOSUB | REG_EXTENDED))
- {
- GNUNET_break_op (0);
- GNUNET_free (r);
- ret = GNUNET_SYSERR;
- continue;
- }
- break;
- }
- GNUNET_CONTAINER_DLL_insert (acc->d_head,
- acc->d_tail,
- r);
- }
- }
- return ret;
-}
-
-
-/**
* Check if we have any remaining pending requests for the
* given @a exchange, and if we have the required data, call
* the callback.
@@ -820,7 +609,6 @@ free_exchange_entry (struct TMH_Exchange *exchange)
GNUNET_CONTAINER_DLL_remove (exchange_head,
exchange_tail,
exchange);
- purge_exchange_accounts (exchange);
while (NULL != (f = exchange->wire_fees_head))
{
struct TALER_EXCHANGE_WireAggregateFees *af;
@@ -876,72 +664,28 @@ TMH_exchange_check_debit (
const struct TMH_Exchange *exchange,
const struct TMH_WireMethod *wm)
{
- if (NULL == exchange->acc_head)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "No accounts available for %s\n",
- exchange->url);
+ const struct TALER_EXCHANGE_Keys *keys = exchange->keys;
+
+ if (NULL == keys)
return GNUNET_SYSERR;
- }
- /* FIXME: move into convenience function in libtalerexchange? See also taler-merchant-httpd_private-get-instances-ID-kyc.c, taler-merchant-kyccheck (!) */
- for (struct ExchangeAccount *acc = exchange->acc_head;
- NULL != acc;
- acc = acc->next)
+ /* For all accounts of the exchange */
+ for (unsigned int i = 0; i<keys->accounts_len; i++)
{
- bool ok = true;
-
- if (0 != strcmp (acc->wire_method,
- wm->wire_method))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Exchange %s wire method %s != %s\n",
- exchange->url,
- acc->wire_method,
- wm->wire_method);
- continue;
- }
- if (NULL != acc->conversion_url)
+ const struct TALER_EXCHANGE_WireAccount *account
+ = &keys->accounts[i];
+ if (NULL != account->conversion_url)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Exchange %s account requires currency conversion (not supported)\n",
exchange->url);
continue; /* never use accounts with conversion */
}
- for (struct Restriction *r = acc->d_head;
- NULL != r;
- r = r->next)
- {
- switch (r->type)
- {
- case TALER_EXCHANGE_AR_INVALID:
- GNUNET_break (0);
- ok = false;
- break;
- case TALER_EXCHANGE_AR_DENY:
- ok = false;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Exchange %s account is disabled\n",
- exchange->url);
- break;
- case TALER_EXCHANGE_AR_REGEX:
- if (0 != regexec (&r->details.regex.ex,
- wm->payto_uri,
- 0, NULL, 0))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Exchange %s account regex does not match %s\n",
- exchange->url,
- wm->payto_uri);
- ok = false;
- }
- break;
- }
- if (! ok)
- break;
- }
-
- if (ok)
- return GNUNET_OK;
+ if (GNUNET_YES !=
+ TALER_EXCHANGE_test_account_allowed (account,
+ false, /* debit */
+ wm->payto_uri))
+ continue;
+ return GNUNET_YES;
}
return GNUNET_NO;
}
@@ -1031,16 +775,6 @@ reload_exchange_keys (struct TMH_Exchange *exchange)
"Loaded /keys from database with %u accounts\n",
keys->accounts_len);
if (GNUNET_OK !=
- set_exchange_accounts (exchange,
- keys->accounts_len,
- keys->accounts))
- {
- /* invalid account specification given */
- GNUNET_break_op (0);
- /* but: we can continue anyway, things may just not
- work, but probably better than to not keep going. */
- }
- if (GNUNET_OK !=
process_wire_fees (exchange,
&keys->master_pub,
keys->fees_len,
diff --git a/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c b/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c
index c2990ebd..ca5688bd 100644
--- a/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c
+++ b/src/backend/taler-merchant-httpd_private-get-instances-ID-kyc.c
@@ -648,59 +648,19 @@ determine_eligible_accounts (
for (unsigned int i = 0; i<keys->accounts_len; i++)
{
/* FIXME: move into convenience function in libtalerexchange? See also taler-merchant-kyccheck.c! */
- struct TALER_EXCHANGE_WireAccount *account
+ const struct TALER_EXCHANGE_WireAccount *account
= &keys->accounts[i];
- bool account_restricted = false;
const char *exchange_account_payto
= account->payto_uri;
/* KYC auth transfers are never supported with conversion */
if (NULL != account->conversion_url)
continue;
-
/* filter by source account by credit_restrictions */
- for (unsigned int j = 0; j<account->credit_restrictions_length; j++)
- {
- const struct TALER_EXCHANGE_AccountRestriction *ar
- = &account->credit_restrictions[j];
-
- switch (ar->type)
- {
- case TALER_EXCHANGE_AR_INVALID:
- continue;
- case TALER_EXCHANGE_AR_DENY:
- account_restricted = true;
- break;
- case TALER_EXCHANGE_AR_REGEX:
- {
- regex_t ex;
- bool allowed = false;
-
- if (0 != regcomp (&ex,
- ar->details.regex.posix_egrep,
- REG_NOSUB | REG_EXTENDED))
- {
- GNUNET_break_op (0);
- continue;
- }
- if (regexec (&ex,
- ekr->payto_uri,
- 0, NULL,
- REG_STARTEND))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Merchant account `%s' allowed by regex\n",
- ekr->payto_uri);
- allowed = true;
- }
- regfree (&ex);
- if (! allowed)
- account_restricted = true;
- break;
- }
- } /* end switch */
- } /* end loop over credit restrictions */
- if (account_restricted)
+ if (GNUNET_YES !=
+ TALER_EXCHANGE_test_account_allowed (account,
+ true, /* credit */
+ ekr->payto_uri))
continue;
/* exchange account is allowed, add it */
{
diff --git a/src/backend/taler-merchant-httpd_private-patch-products-ID.c b/src/backend/taler-merchant-httpd_private-patch-products-ID.c
index 81633051..0756b207 100644
--- a/src/backend/taler-merchant-httpd_private-patch-products-ID.c
+++ b/src/backend/taler-merchant-httpd_private-patch-products-ID.c
@@ -189,7 +189,7 @@ TMH_private_patch_products_ID (
}
if (NULL == pd.image)
- pd.image = "";
+ pd.image = (char *) "";
if (! TMH_image_data_url_valid (pd.image))
{
GNUNET_break_op (0);
diff --git a/src/backend/taler-merchant-httpd_qr.c b/src/backend/taler-merchant-httpd_qr.c
index 59e80bf2..3bea9173 100644
--- a/src/backend/taler-merchant-httpd_qr.c
+++ b/src/backend/taler-merchant-httpd_qr.c
@@ -21,7 +21,7 @@
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
#include <qrencode.h>
-
+#include <taler-merchant-httpd_qr.h>
/**
* Create the HTML for a QR code for a URI.
diff --git a/src/backend/taler-merchant-kyccheck.c b/src/backend/taler-merchant-kyccheck.c
index 9bd72822..fd7877f3 100644
--- a/src/backend/taler-merchant-kyccheck.c
+++ b/src/backend/taler-merchant-kyccheck.c
@@ -679,64 +679,25 @@ finish:
* @param a an account
*/
static bool
-is_eligible (struct TALER_EXCHANGE_Keys *keys,
- struct Account *a)
+is_eligible (const struct TALER_EXCHANGE_Keys *keys,
+ const struct Account *a)
{
/* For all accounts of the exchange */
for (unsigned int i = 0; i<keys->accounts_len; i++)
{
/* FIXME: move into convenience function in libtalerexchange? See also taler-merchant-httpd_private-get-instances-ID-kyc.c, taler-merchant-httpd_exchanges (!)*/
- struct TALER_EXCHANGE_WireAccount *account
+ const struct TALER_EXCHANGE_WireAccount *account
= &keys->accounts[i];
bool account_restricted = false;
/* KYC auth transfers are never supported with conversion */
if (NULL != account->conversion_url)
continue;
-
/* filter by source account by credit_restrictions */
- for (unsigned int j = 0; j<account->credit_restrictions_length; j++)
- {
- const struct TALER_EXCHANGE_AccountRestriction *ar
- = &account->credit_restrictions[j];
-
- switch (ar->type)
- {
- case TALER_EXCHANGE_AR_INVALID:
- continue;
- case TALER_EXCHANGE_AR_DENY:
- account_restricted = true;
- break;
- case TALER_EXCHANGE_AR_REGEX:
- {
- regex_t ex;
- bool allowed = false;
-
- if (0 != regcomp (&ex,
- ar->details.regex.posix_egrep,
- REG_NOSUB | REG_EXTENDED))
- {
- GNUNET_break_op (0);
- continue;
- }
- if (regexec (&ex,
- a->merchant_account_uri,
- 0, NULL,
- REG_STARTEND))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Merchant account `%s' allowed by regex\n",
- a->merchant_account_uri);
- allowed = true;
- }
- regfree (&ex);
- if (! allowed)
- account_restricted = true;
- break;
- }
- } /* end switch */
- } /* end loop over credit restrictions */
- if (account_restricted)
+ if (GNUNET_YES !=
+ TALER_EXCHANGE_test_account_allowed (account,
+ true, /* credit */
+ a->merchant_account_uri))
continue;
/* exchange account is allowed, add it */
return true;