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 §ion[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 */