LCOV - code coverage report
Current view: top level - exchangedb - exchangedb_accounts.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 74 95 77.9 %
Date: 2025-06-05 21:03:14 Functions: 6 6 100.0 %

          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 "platform.h"
      22             : #include "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         200 : TALER_EXCHANGEDB_find_accounts (TALER_EXCHANGEDB_AccountCallback cb,
      82             :                                 void *cb_cls)
      83             : {
      84         200 :   for (struct WireAccount *wa = wa_head;
      85         460 :        NULL != wa;
      86         260 :        wa = wa->next)
      87         260 :     cb (cb_cls,
      88         260 :         &wa->ai);
      89         200 : }
      90             : 
      91             : 
      92             : const struct TALER_EXCHANGEDB_AccountInfo *
      93         146 : TALER_EXCHANGEDB_find_account_by_method (const char *method)
      94             : {
      95         146 :   for (struct WireAccount *wa = wa_head;
      96         146 :        NULL != wa;
      97           0 :        wa = wa->next)
      98         146 :     if (0 == strcmp (method,
      99         146 :                      wa->method))
     100         146 :       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          79 : 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          79 :   method = TALER_payto_get_method (url.full_payto);
     116          79 :   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          79 :   ai = TALER_EXCHANGEDB_find_account_by_method (method);
     124          79 :   GNUNET_free (method);
     125          79 :   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       15368 : add_account_cb (void *cls,
     171             :                 const char *section)
     172             : {
     173       15368 :   struct LoaderContext *lc = cls;
     174       15368 :   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       15368 :   if (0 != strncasecmp (section,
     184             :                         "exchange-account-",
     185             :                         strlen ("exchange-account-")))
     186       14852 :     return;
     187             : 
     188         516 :   debit = (GNUNET_YES ==
     189         516 :            GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
     190             :                                                  section,
     191             :                                                  "ENABLE_DEBIT"));
     192         516 :   credit = (GNUNET_YES ==
     193         516 :             GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
     194             :                                                   section,
     195             :                                                   "ENABLE_CREDIT"));
     196         516 :   if (! ( ( (debit) &&
     197         516 :             (lc->debit) ) ||
     198         192 :           ( (credit) &&
     199         192 :             (lc->credit) ) ) )
     200           0 :     return; /* not enabled for us, skip */
     201         516 :   if (GNUNET_OK !=
     202         516 :       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         516 :   full_payto.full_payto = payto_uri;
     213         516 :   method = TALER_payto_get_method (payto_uri);
     214         516 :   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         516 :   GNUNET_assert (NULL != method);
     227         516 :   wa = GNUNET_new (struct WireAccount);
     228         516 :   wa->section_name = GNUNET_strdup (section);
     229         516 :   wa->payto_uri = full_payto;
     230         516 :   wa->method = method;
     231         516 :   wa->ai.debit_enabled = debit;
     232         516 :   wa->ai.credit_enabled = credit;
     233         516 :   wa->ai.auth = NULL;
     234         516 :   wa->ai.section_name = wa->section_name;
     235         516 :   wa->ai.method = wa->method;
     236         516 :   wa->ai.payto_uri = full_payto;
     237         516 :   if (lc->load_auth_data)
     238             :   {
     239             :     char *csn;
     240             : 
     241         411 :     GNUNET_asprintf (&csn,
     242             :                      "exchange-accountcredentials-%s",
     243             :                      &section[strlen ("exchange-account-")]);
     244         411 :     if (GNUNET_OK !=
     245         411 :         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         411 :     wa->ai.auth = &wa->auth;
     259         411 :     GNUNET_free (csn);
     260             :   }
     261         516 :   GNUNET_CONTAINER_DLL_insert (wa_head,
     262             :                                wa_tail,
     263             :                                wa);
     264             : }
     265             : 
     266             : 
     267             : enum GNUNET_GenericReturnValue
     268         406 : TALER_EXCHANGEDB_load_accounts (
     269             :   const struct GNUNET_CONFIGURATION_Handle *cfg,
     270             :   enum TALER_EXCHANGEDB_AccountLoaderOptions options)
     271             : {
     272         406 :   struct LoaderContext lc = {
     273             :     .cfg = cfg,
     274         406 :     .debit = 0 != (options & TALER_EXCHANGEDB_ALO_DEBIT),
     275         406 :     .credit = 0 != (options & TALER_EXCHANGEDB_ALO_CREDIT),
     276         406 :     .load_auth_data = 0 != (options & TALER_EXCHANGEDB_ALO_AUTHDATA),
     277             :   };
     278             : 
     279         406 :   GNUNET_CONFIGURATION_iterate_sections (cfg,
     280             :                                          &add_account_cb,
     281             :                                          &lc);
     282         406 :   if (GNUNET_SYSERR == lc.res)
     283           0 :     return GNUNET_SYSERR;
     284         406 :   if (NULL == wa_head)
     285           0 :     return GNUNET_NO;
     286         406 :   return GNUNET_OK;
     287             : }
     288             : 
     289             : 
     290             : void
     291         406 : TALER_EXCHANGEDB_unload_accounts (void)
     292             : {
     293             :   struct WireAccount *wa;
     294             : 
     295         922 :   while (NULL != (wa = wa_head))
     296             :   {
     297         516 :     GNUNET_CONTAINER_DLL_remove (wa_head,
     298             :                                  wa_tail,
     299             :                                  wa);
     300         516 :     if (NULL != wa->ai.auth)
     301         411 :       TALER_BANK_auth_free (&wa->auth);
     302         516 :     GNUNET_free (wa->section_name);
     303         516 :     GNUNET_free (wa->payto_uri.full_payto);
     304         516 :     GNUNET_free (wa->method);
     305         516 :     GNUNET_free (wa);
     306             :   }
     307         406 : }
     308             : 
     309             : 
     310             : /* end of exchangedb_accounts.c */

Generated by: LCOV version 1.16