LCOV - code coverage report
Current view: top level - exchangedb - exchangedb_accounts.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 77.9 % 95 74
Test Date: 2026-04-14 15:39:31 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2018-2021 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify it under the
       6              :   terms of the GNU General Public License as published by the Free Software
       7              :   Foundation; either version 3, or (at your option) any later version.
       8              : 
       9              :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10              :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11              :   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12              : 
      13              :   You should have received a copy of the GNU General Public License along with
      14              :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15              : */
      16              : /**
      17              :  * @file exchangedb/exchangedb_accounts.c
      18              :  * @brief Logic to parse account information from the configuration
      19              :  * @author Christian Grothoff
      20              :  */
      21              : #include "taler/taler_exchangedb_lib.h"
      22              : 
      23              : 
      24              : /**
      25              :  * Information we keep for each supported account of the exchange.
      26              :  */
      27              : struct WireAccount
      28              : {
      29              :   /**
      30              :    * Accounts are kept in a DLL.
      31              :    */
      32              :   struct WireAccount *next;
      33              : 
      34              :   /**
      35              :    * Plugins are kept in a DLL.
      36              :    */
      37              :   struct WireAccount *prev;
      38              : 
      39              :   /**
      40              :    * Externally visible account information.
      41              :    */
      42              :   struct TALER_EXCHANGEDB_AccountInfo ai;
      43              : 
      44              :   /**
      45              :    * Authentication data. Only parsed if
      46              :    * #TALER_EXCHANGEDB_ALO_AUTHDATA was set.
      47              :    */
      48              :   struct TALER_BANK_AuthenticationData auth;
      49              : 
      50              :   /**
      51              :    * Name of the section that configures this account.
      52              :    */
      53              :   char *section_name;
      54              : 
      55              :   /**
      56              :    * Name of the wire method underlying the account.
      57              :    */
      58              :   char *method;
      59              : 
      60              :   /**
      61              :    * Full payto://-URI of the account.
      62              :    */
      63              :   struct TALER_FullPayto payto_uri;
      64              : 
      65              : };
      66              : 
      67              : 
      68              : /**
      69              :  * Head of list of wire accounts of the exchange.
      70              :  */
      71              : static struct WireAccount *wa_head;
      72              : 
      73              : /**
      74              :  * Tail of list of wire accounts of the exchange.
      75              :  */
      76              : static struct WireAccount *wa_tail;
      77              : 
      78              : 
      79              : void
      80           62 : TALER_EXCHANGEDB_find_accounts (TALER_EXCHANGEDB_AccountCallback cb,
      81              :                                 void *cb_cls)
      82              : {
      83           62 :   for (struct WireAccount *wa = wa_head;
      84          234 :        NULL != wa;
      85          172 :        wa = wa->next)
      86          172 :     cb (cb_cls,
      87          172 :         &wa->ai);
      88           62 : }
      89              : 
      90              : 
      91              : const struct TALER_EXCHANGEDB_AccountInfo *
      92          117 : TALER_EXCHANGEDB_find_account_by_method (const char *method)
      93              : {
      94          117 :   for (struct WireAccount *wa = wa_head;
      95          117 :        NULL != wa;
      96            0 :        wa = wa->next)
      97          117 :     if (0 == strcmp (method,
      98          117 :                      wa->method))
      99          117 :       return &wa->ai;
     100            0 :   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     101              :               "No wire account known for method `%s'\n",
     102              :               method);
     103            0 :   return NULL;
     104              : }
     105              : 
     106              : 
     107              : const struct TALER_EXCHANGEDB_AccountInfo *
     108           65 : TALER_EXCHANGEDB_find_account_by_payto_uri (
     109              :   const struct TALER_FullPayto url)
     110              : {
     111              :   char *method;
     112              :   const struct TALER_EXCHANGEDB_AccountInfo *ai;
     113              : 
     114           65 :   method = TALER_payto_get_method (url.full_payto);
     115           65 :   if (NULL == method)
     116              :   {
     117            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     118              :                 "Invalid payto:// URL `%s'\n",
     119              :                 url.full_payto);
     120            0 :     return NULL;
     121              :   }
     122           65 :   ai = TALER_EXCHANGEDB_find_account_by_method (method);
     123           65 :   GNUNET_free (method);
     124           65 :   return ai;
     125              : }
     126              : 
     127              : 
     128              : /**
     129              :  * Closure for #add_account_cb().
     130              :  */
     131              : struct LoaderContext
     132              : {
     133              :   /**
     134              :    * Configuration to use.
     135              :    */
     136              :   const struct GNUNET_CONFIGURATION_Handle *cfg;
     137              : 
     138              :   /**
     139              :    * true if we are to load the authentication data
     140              :    * for the access to the bank account.
     141              :    */
     142              :   bool load_auth_data;
     143              : 
     144              :   /**
     145              :    * Load accounts enabled for CREDIT.
     146              :    */
     147              :   bool credit;
     148              : 
     149              :   /**
     150              :    * Load accounts enabled for DEBIT.
     151              :    */
     152              :   bool debit;
     153              : 
     154              :   /**
     155              :    * Loader status (set by callback).
     156              :    */
     157              :   enum GNUNET_GenericReturnValue res;
     158              : };
     159              : 
     160              : 
     161              : /**
     162              :  * Function called with information about a wire account.  Adds
     163              :  * the account to our list.
     164              :  *
     165              :  * @param cls closure, a `struct LoaderContext`
     166              :  * @param section section to parse account information from
     167              :  */
     168              : static void
     169         8602 : add_account_cb (void *cls,
     170              :                 const char *section)
     171              : {
     172         8602 :   struct LoaderContext *lc = cls;
     173         8602 :   const struct GNUNET_CONFIGURATION_Handle *cfg = lc->cfg;
     174              :   struct WireAccount *wa;
     175              :   char *payto_uri;
     176              :   char *method;
     177              :   bool debit;
     178              :   bool credit;
     179              :   struct TALER_FullPayto full_payto;
     180              :   char *err;
     181              : 
     182         8602 :   if (0 != strncasecmp (section,
     183              :                         "exchange-account-",
     184              :                         strlen ("exchange-account-")))
     185         8230 :     return;
     186              : 
     187          372 :   debit = (GNUNET_YES ==
     188          372 :            GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
     189              :                                                  section,
     190              :                                                  "ENABLE_DEBIT"));
     191          372 :   credit = (GNUNET_YES ==
     192          372 :             GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
     193              :                                                   section,
     194              :                                                   "ENABLE_CREDIT"));
     195          372 :   if (! ( ( (debit) &&
     196          372 :             (lc->debit) ) ||
     197          172 :           ( (credit) &&
     198          172 :             (lc->credit) ) ) )
     199            0 :     return; /* not enabled for us, skip */
     200          372 :   if (GNUNET_OK !=
     201          372 :       GNUNET_CONFIGURATION_get_value_string (cfg,
     202              :                                              section,
     203              :                                              "PAYTO_URI",
     204              :                                              &payto_uri))
     205              :   {
     206            0 :     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
     207              :                                section,
     208              :                                "PAYTO_URI");
     209            0 :     return;
     210              :   }
     211          372 :   full_payto.full_payto = payto_uri;
     212          372 :   method = TALER_payto_get_method (payto_uri);
     213          372 :   if ( (NULL != (err = TALER_payto_validate (full_payto))) ||
     214              :        (NULL == method) )
     215              :   {
     216            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     217              :                 "payto URI in config ([%s]/PAYTO_URI) malformed: %s\n",
     218              :                 section,
     219              :                 err);
     220            0 :     lc->res = GNUNET_SYSERR;
     221            0 :     GNUNET_free (payto_uri);
     222            0 :     GNUNET_free (err);
     223            0 :     return;
     224              :   }
     225          372 :   GNUNET_assert (NULL != method);
     226          372 :   wa = GNUNET_new (struct WireAccount);
     227          372 :   wa->section_name = GNUNET_strdup (section);
     228          372 :   wa->payto_uri = full_payto;
     229          372 :   wa->method = method;
     230          372 :   wa->ai.debit_enabled = debit;
     231          372 :   wa->ai.credit_enabled = credit;
     232          372 :   wa->ai.auth = NULL;
     233          372 :   wa->ai.section_name = wa->section_name;
     234          372 :   wa->ai.method = wa->method;
     235          372 :   wa->ai.payto_uri = full_payto;
     236          372 :   if (lc->load_auth_data)
     237              :   {
     238              :     char *csn;
     239              : 
     240          263 :     GNUNET_asprintf (&csn,
     241              :                      "exchange-accountcredentials-%s",
     242              :                      &section[strlen ("exchange-account-")]);
     243          263 :     if (GNUNET_OK !=
     244          263 :         TALER_BANK_auth_parse_cfg (cfg,
     245              :                                    csn,
     246              :                                    &wa->auth))
     247              :     {
     248            0 :       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
     249              :                   "Failed to load exchange account credentials from section `%s'\n",
     250              :                   csn);
     251            0 :       GNUNET_free (csn);
     252            0 :       GNUNET_free (wa->section_name);
     253            0 :       GNUNET_free (wa->method);
     254            0 :       GNUNET_free (wa);
     255            0 :       return;
     256              :     }
     257          263 :     wa->ai.auth = &wa->auth;
     258          263 :     GNUNET_free (csn);
     259              :   }
     260          372 :   GNUNET_CONTAINER_DLL_insert (wa_head,
     261              :                                wa_tail,
     262              :                                wa);
     263              : }
     264              : 
     265              : 
     266              : enum GNUNET_GenericReturnValue
     267          162 : TALER_EXCHANGEDB_load_accounts (
     268              :   const struct GNUNET_CONFIGURATION_Handle *cfg,
     269              :   enum TALER_EXCHANGEDB_AccountLoaderOptions options)
     270              : {
     271          162 :   struct LoaderContext lc = {
     272              :     .cfg = cfg,
     273          162 :     .debit = 0 != (options & TALER_EXCHANGEDB_ALO_DEBIT),
     274          162 :     .credit = 0 != (options & TALER_EXCHANGEDB_ALO_CREDIT),
     275          162 :     .load_auth_data = 0 != (options & TALER_EXCHANGEDB_ALO_AUTHDATA),
     276              :   };
     277              : 
     278          162 :   GNUNET_CONFIGURATION_iterate_sections (cfg,
     279              :                                          &add_account_cb,
     280              :                                          &lc);
     281          162 :   if (GNUNET_SYSERR == lc.res)
     282            0 :     return GNUNET_SYSERR;
     283          162 :   if (NULL == wa_head)
     284            0 :     return GNUNET_NO;
     285          162 :   return GNUNET_OK;
     286              : }
     287              : 
     288              : 
     289              : void
     290          162 : TALER_EXCHANGEDB_unload_accounts (void)
     291              : {
     292              :   struct WireAccount *wa;
     293              : 
     294          534 :   while (NULL != (wa = wa_head))
     295              :   {
     296          372 :     GNUNET_CONTAINER_DLL_remove (wa_head,
     297              :                                  wa_tail,
     298              :                                  wa);
     299          372 :     if (NULL != wa->ai.auth)
     300          263 :       TALER_BANK_auth_free (&wa->auth);
     301          372 :     GNUNET_free (wa->section_name);
     302          372 :     GNUNET_free (wa->payto_uri.full_payto);
     303          372 :     GNUNET_free (wa->method);
     304          372 :     GNUNET_free (wa);
     305              :   }
     306          162 : }
     307              : 
     308              : 
     309              : /* end of exchangedb_accounts.c */
        

Generated by: LCOV version 2.0-1