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 (7903B)


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