exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

exchangedb_accounts.c (7943B)


      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 TALER_EXCHANGEDB_find_accounts (TALER_EXCHANGEDB_AccountCallback cb,
     82                                 void *cb_cls)
     83 {
     84   for (struct WireAccount *wa = wa_head;
     85        NULL != wa;
     86        wa = wa->next)
     87     cb (cb_cls,
     88         &wa->ai);
     89 }
     90 
     91 
     92 const struct TALER_EXCHANGEDB_AccountInfo *
     93 TALER_EXCHANGEDB_find_account_by_method (const char *method)
     94 {
     95   for (struct WireAccount *wa = wa_head;
     96        NULL != wa;
     97        wa = wa->next)
     98     if (0 == strcmp (method,
     99                      wa->method))
    100       return &wa->ai;
    101   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    102               "No wire account known for method `%s'\n",
    103               method);
    104   return NULL;
    105 }
    106 
    107 
    108 const struct TALER_EXCHANGEDB_AccountInfo *
    109 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   method = TALER_payto_get_method (url.full_payto);
    116   if (NULL == method)
    117   {
    118     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    119                 "Invalid payto:// URL `%s'\n",
    120                 url.full_payto);
    121     return NULL;
    122   }
    123   ai = TALER_EXCHANGEDB_find_account_by_method (method);
    124   GNUNET_free (method);
    125   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 add_account_cb (void *cls,
    171                 const char *section)
    172 {
    173   struct LoaderContext *lc = cls;
    174   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   if (0 != strncasecmp (section,
    184                         "exchange-account-",
    185                         strlen ("exchange-account-")))
    186     return;
    187 
    188   debit = (GNUNET_YES ==
    189            GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
    190                                                  section,
    191                                                  "ENABLE_DEBIT"));
    192   credit = (GNUNET_YES ==
    193             GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
    194                                                   section,
    195                                                   "ENABLE_CREDIT"));
    196   if (! ( ( (debit) &&
    197             (lc->debit) ) ||
    198           ( (credit) &&
    199             (lc->credit) ) ) )
    200     return; /* not enabled for us, skip */
    201   if (GNUNET_OK !=
    202       GNUNET_CONFIGURATION_get_value_string (cfg,
    203                                              section,
    204                                              "PAYTO_URI",
    205                                              &payto_uri))
    206   {
    207     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
    208                                section,
    209                                "PAYTO_URI");
    210     return;
    211   }
    212   full_payto.full_payto = payto_uri;
    213   method = TALER_payto_get_method (payto_uri);
    214   if ( (NULL != (err = TALER_payto_validate (full_payto))) ||
    215        (NULL == method) )
    216   {
    217     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    218                 "payto URI in config ([%s]/PAYTO_URI) malformed: %s\n",
    219                 section,
    220                 err);
    221     lc->res = GNUNET_SYSERR;
    222     GNUNET_free (payto_uri);
    223     GNUNET_free (err);
    224     return;
    225   }
    226   GNUNET_assert (NULL != method);
    227   wa = GNUNET_new (struct WireAccount);
    228   wa->section_name = GNUNET_strdup (section);
    229   wa->payto_uri = full_payto;
    230   wa->method = method;
    231   wa->ai.debit_enabled = debit;
    232   wa->ai.credit_enabled = credit;
    233   wa->ai.auth = NULL;
    234   wa->ai.section_name = wa->section_name;
    235   wa->ai.method = wa->method;
    236   wa->ai.payto_uri = full_payto;
    237   if (lc->load_auth_data)
    238   {
    239     char *csn;
    240 
    241     GNUNET_asprintf (&csn,
    242                      "exchange-accountcredentials-%s",
    243                      &section[strlen ("exchange-account-")]);
    244     if (GNUNET_OK !=
    245         TALER_BANK_auth_parse_cfg (cfg,
    246                                    csn,
    247                                    &wa->auth))
    248     {
    249       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
    250                   "Failed to load exchange account credentials from section `%s'\n",
    251                   csn);
    252       GNUNET_free (csn);
    253       GNUNET_free (wa->section_name);
    254       GNUNET_free (wa->method);
    255       GNUNET_free (wa);
    256       return;
    257     }
    258     wa->ai.auth = &wa->auth;
    259     GNUNET_free (csn);
    260   }
    261   GNUNET_CONTAINER_DLL_insert (wa_head,
    262                                wa_tail,
    263                                wa);
    264 }
    265 
    266 
    267 enum GNUNET_GenericReturnValue
    268 TALER_EXCHANGEDB_load_accounts (
    269   const struct GNUNET_CONFIGURATION_Handle *cfg,
    270   enum TALER_EXCHANGEDB_AccountLoaderOptions options)
    271 {
    272   struct LoaderContext lc = {
    273     .cfg = cfg,
    274     .debit = 0 != (options & TALER_EXCHANGEDB_ALO_DEBIT),
    275     .credit = 0 != (options & TALER_EXCHANGEDB_ALO_CREDIT),
    276     .load_auth_data = 0 != (options & TALER_EXCHANGEDB_ALO_AUTHDATA),
    277   };
    278 
    279   GNUNET_CONFIGURATION_iterate_sections (cfg,
    280                                          &add_account_cb,
    281                                          &lc);
    282   if (GNUNET_SYSERR == lc.res)
    283     return GNUNET_SYSERR;
    284   if (NULL == wa_head)
    285     return GNUNET_NO;
    286   return GNUNET_OK;
    287 }
    288 
    289 
    290 void
    291 TALER_EXCHANGEDB_unload_accounts (void)
    292 {
    293   struct WireAccount *wa;
    294 
    295   while (NULL != (wa = wa_head))
    296   {
    297     GNUNET_CONTAINER_DLL_remove (wa_head,
    298                                  wa_tail,
    299                                  wa);
    300     if (NULL != wa->ai.auth)
    301       TALER_BANK_auth_free (&wa->auth);
    302     GNUNET_free (wa->section_name);
    303     GNUNET_free (wa->payto_uri.full_payto);
    304     GNUNET_free (wa->method);
    305     GNUNET_free (wa);
    306   }
    307 }
    308 
    309 
    310 /* end of exchangedb_accounts.c */