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

Generated by: LCOV version 2.0-1