cash2ecash

cash2ecash: cash acceptor that issues digital cash (experimental)
Log | Files | Refs | README | LICENSE

commit 0d9423bf84db892877c89a8ade6adaedf0ceb305
parent 19f38bbd194336f66944121614700e4e71525e72
Author: Tellenbach Reto <tellr1@bfh.ch>
Date:   Fri,  5 Jun 2026 16:35:46 +0200

[new] Tapler-api: GET /accounts/ api implmentation done

Diffstat:
Msrc/lib/CMakeLists.txt | 14+++++++++++---
Asrc/lib/api_common.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/lib/api_common.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Asrc/lib/api_parse.c | 157+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/bank_api_get_accounts.c | 31+++++++++++++++++++++++--------
Msrc/lib/bank_api_get_accounts.h | 4+++-
Msrc/taler-digitizer.c | 35+++++++++++++++++++++++++++++++++--
Msrc/taler/taler_digitizer_service.h | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtaler-digitizer.conf | 9++++++---
9 files changed, 426 insertions(+), 17 deletions(-)

diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt @@ -1,11 +1,19 @@ # Add files -add_library(bank bank_api_get_config.c bank_api_curl_defaults.c bank_api_get_accounts.c) +add_library(bank + bank_api_get_config.c + bank_api_curl_defaults.c + bank_api_get_accounts.c) +add_library(common + api_common.c api_parse.c) find_package(CURL REQUIRED) pkg_check_modules(GNUNET REQUIRED gnunetutil) pkg_check_modules(LIBMICROHTTPD REQUIRED libmicrohttpd) target_link_libraries(bank - PUBLIC CURL::libcurl gnunetutil talerutil microhttpd - PRIVATE talercurl talerjson gnunetutil gnunetcurl gnunetjson jansson + PUBLIC + CURL::libcurl gnunetutil talerutil microhttpd + PRIVATE + talercurl talerjson gnunetcurl gnunetjson + jansson common ) \ No newline at end of file diff --git a/src/lib/api_common.c b/src/lib/api_common.c @@ -0,0 +1,76 @@ +/* + This file is part of TALER + Copyright (C) 2015-2020 2026 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see + <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/api_common.c + * @brief Common functions for API implementations in the taler digitizer. + * since types are used which are not in the current bank/exchange lib the the file suffix is not set + * @author Christian Grothoff + * @author Reto Tellenbach + */ +#include "api_common.h" + + +enum GNUNET_GenericReturnValue +DIGITIZER_setup_auth_ (CURL *easy, + const struct DIGITIZER_BankAuthenticationData *auth) +{ + enum GNUNET_GenericReturnValue ret; + + ret = GNUNET_OK; + switch (auth->method) + { + case TALER_BANK_AUTH_NONE: + return GNUNET_OK; + case TALER_BANK_AUTH_BASIC: + { + char *up; + + GNUNET_asprintf (&up, + "%s:%s", + auth->details.basic.username, + auth->details.basic.password); + if ( (CURLE_OK != + curl_easy_setopt (easy, + CURLOPT_HTTPAUTH, + CURLAUTH_BASIC)) || + (CURLE_OK != + curl_easy_setopt (easy, + CURLOPT_USERPWD, + up)) ) + ret = GNUNET_SYSERR; + GNUNET_free (up); + break; + } + case TALER_BANK_AUTH_BEARER: + { + if ( (CURLE_OK != + curl_easy_setopt (easy, + CURLOPT_HTTPAUTH, + CURLAUTH_BEARER)) || + (CURLE_OK != + curl_easy_setopt (easy, + CURLOPT_XOAUTH2_BEARER, + auth->details.bearer.token)) ) + ret = GNUNET_SYSERR; + break; + } + } + return ret; +} + + +/* end of bank_api_common.c */ diff --git a/src/lib/api_common.h b/src/lib/api_common.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2015, 2016, 2017, 2026 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see + <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/api_common.c + * @brief Common functions for API implementations in the taler digitizer. + * since types are used which are not in the current bank/exchange lib the the file suffix is not set + * @author Christian Grothoff + * @author Reto Tellenbach + */ +#ifndef BANK_API_COMMON_H +#define BANK_API_COMMON_H + +#include <gnunet/gnunet_util_lib.h> +#include <gnunet/gnunet_json_lib.h> +#include <gnunet/gnunet_curl_lib.h> +#include "../taler/taler_digitizer_service.h" +#include "taler/taler_bank_service.h" +#include "taler/taler_json_lib.h" + + +/** + * Set authentication data in @a easy from @a auth. + * + * @param easy curl handle to setup for authentication + * @param auth authentication data to use + * @return #GNUNET_OK in success + */ +enum GNUNET_GenericReturnValue +DIGITIZER_setup_auth_ (CURL *easy, + const struct DIGITIZER_BankAuthenticationData *auth); + +#endif diff --git a/src/lib/api_parse.c b/src/lib/api_parse.c @@ -0,0 +1,157 @@ +/* + This file is part of TALER + Copyright (C) 2018-2020, 2026 Taler Systems SA + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see + <http://www.gnu.org/licenses/> +*/ +/** + * @file lib/api_parse.c + * @brief Convenience function to parse authentication configuration + * @author Christian Grothoff + * @author Reto Tellenbach + */ +#include "taler/taler_bank_service.h" +#include "../taler/taler_digitizer_service.h" + + +enum GNUNET_GenericReturnValue +DIGITIZER_bank_auth_parse_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + struct DIGITIZER_BankAuthenticationData *auth) +{ + const struct + { + const char *m; + enum TALER_BANK_AuthenticationMethod e; + } methods[] = { + { "NONE", TALER_BANK_AUTH_NONE }, + { "BASIC", TALER_BANK_AUTH_BASIC }, + { "BEARER", TALER_BANK_AUTH_BEARER }, + { NULL, TALER_BANK_AUTH_NONE } + }; + char *method; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + section, + "AUTH_METHOD", + &method)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + section, + "AUTH_METHOD"); + return GNUNET_SYSERR; + } + + for (unsigned int i = 0; NULL != methods[i].m; i++) + { + if (0 == strcasecmp (method, + methods[i].m)) + { + switch (methods[i].e) + { + case TALER_BANK_AUTH_NONE: + auth->method = TALER_BANK_AUTH_NONE; + GNUNET_free (method); + return GNUNET_OK; + case TALER_BANK_AUTH_BASIC: + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string ( + cfg, + section, + "USERNAME", + &auth->details.basic.username)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + section, + "USERNAME"); + GNUNET_free (method); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string ( + cfg, + section, + "PASSWORD", + &auth->details.basic.password)) + { + GNUNET_free (auth->details.basic.username); + auth->details.basic.username = NULL; + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + section, + "PASSWORD"); + GNUNET_free (method); + return GNUNET_SYSERR; + } + auth->method = TALER_BANK_AUTH_BASIC; + GNUNET_free (method); + return GNUNET_OK; + case TALER_BANK_AUTH_BEARER: + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string ( + cfg, + section, + "TOKEN", + &auth->details.bearer.token)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + section, + "TOKEN"); + GNUNET_free (method); + return GNUNET_SYSERR; + } + auth->method = TALER_BANK_AUTH_BEARER; + GNUNET_free (method); + return GNUNET_OK; + } + } + } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unknown authentication method `%s'\n", + method); + GNUNET_free (method); + return GNUNET_SYSERR; +} + + +void +DIGITIZER_bank_auth_free (struct DIGITIZER_BankAuthenticationData *auth) +{ + switch (auth->method) + { + case TALER_BANK_AUTH_NONE: + break; + case TALER_BANK_AUTH_BASIC: + if (NULL != auth->details.basic.username) + { + GNUNET_free (auth->details.basic.username); + auth->details.basic.username = NULL; + } + if (NULL != auth->details.basic.password) + { + GNUNET_free (auth->details.basic.password); + auth->details.basic.password = NULL; + } + break; + case TALER_BANK_AUTH_BEARER: + if (NULL != auth->details.bearer.token) + { + GNUNET_free (auth->details.bearer.token); + auth->details.bearer.token = NULL; + } + break; + } +} + + +/* end of bank_api_parse.c */ diff --git a/src/lib/bank_api_get_accounts.c b/src/lib/bank_api_get_accounts.c @@ -68,6 +68,11 @@ struct TALER_BANK_GetAccountsHandle struct GNUNET_CURL_Job *job; /** + * Headers sent with http request + */ + struct curl_slist *request_headers; + + /** * The whole request line */ char *job_url; @@ -86,7 +91,7 @@ static enum TALER_ErrorCode decode_config_json (const json_t *resp_obj, struct TALER_BANK_AccountInformation *vi) { - const json_t **channels_pack; + const json_t *channels_pack; json_t *cnt; bool contact_missing; bool tan_channels_missing; @@ -98,7 +103,7 @@ decode_config_json (const json_t *resp_obj, &vi->debit_threshold), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_array_const ("tan_channels", - channels_pack), + &channels_pack), &tan_channels_missing), GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_json ("contact_data", @@ -153,7 +158,7 @@ decode_config_json (const json_t *resp_obj, { size_t idx; json_t *val; - json_array_foreach (*channels_pack, + json_array_foreach (channels_pack, idx, val) { @@ -264,19 +269,23 @@ struct TALER_BANK_GetAccountsHandle * TALER_BANK_get_accounts ( struct GNUNET_CURL_Context *ctx, const char *url, const char *username, + const struct DIGITIZER_BankAuthenticationData *authorization, TALER_BANK_AccountsCallback accounts_cb, void *accounts_cb_cls) { struct TALER_BANK_GetAccountsHandle *account; + char *usr; CURL *eh; account = GNUNET_new(struct TALER_BANK_GetAccountsHandle); account->accounts_cb = accounts_cb; account->accounts_cb_cls = accounts_cb_cls; account->ctx = ctx; + GNUNET_asprintf(&usr, + "accounts/%s", + username); account->job_url = TALER_url_join(url, - "accounts", - username, + usr, NULL); if(NULL == account->job_url) { @@ -294,10 +303,16 @@ TALER_BANK_get_accounts ( struct GNUNET_CURL_Context *ctx, TALER_BANK_get_accounts_cancel(account); return NULL; } + if(GNUNET_OK != DIGITIZER_setup_auth_(eh,authorization)) + { + GNUNET_break(0); + TALER_BANK_get_accounts_cancel(account); + return NULL; + } account->job = GNUNET_CURL_job_add(account->ctx, - eh, - &response_cb, - account); + eh, + &response_cb, + account); if(NULL == account->job) { GNUNET_break(0); diff --git a/src/lib/bank_api_get_accounts.h b/src/lib/bank_api_get_accounts.h @@ -24,7 +24,7 @@ #ifndef BANK_API_GET_ACCOUNTS_H #define BANK_API_GET_ACCOUNTS_H -#include "../taler/taler_digitizer_service.h" +#include "api_common.h" /** @@ -131,6 +131,7 @@ struct TALER_BANK_GetAccountsHandle; * @param ctx curl context * @param url bank url * @param username bank account name + * @param authorization authentication for account * @param accounts_cb callback * @param accounts_cb_cls callback context * @return NULL on failure @@ -139,6 +140,7 @@ struct TALER_BANK_GetAccountsHandle * TALER_BANK_get_accounts ( struct GNUNET_CURL_Context *ctx, const char *url, const char *username, + const struct DIGITIZER_BankAuthenticationData *authorization, TALER_BANK_AccountsCallback accounts_cb, void *accounts_cb_cls); diff --git a/src/taler-digitizer.c b/src/taler-digitizer.c @@ -26,6 +26,7 @@ #include <gnunet/gnunet_util_lib.h> #include "taler_digitizer_util.h" +#include "taler/taler_digitizer_service.h" #include "lib/bank_api_get_config.h" #include "lib/bank_api_get_accounts.h" #include "digitizer_display.h" @@ -58,6 +59,12 @@ static char *cfg_bank_base_url; static char *cfg_bank_account_username; /** + * Taler bank authentication + * method and according data + */ +static struct DIGITIZER_BankAuthenticationData *cfg_bank_authentication; + +/** * Taler exchange backend url read from configuration file */ static char *cfg_exchange_base_url; @@ -344,11 +351,12 @@ on_get_config_done (void *cls, static void on_get_accounts_done(void *cls, - const struct TALER_BANK_GetAccountsHandle *vr) + const struct TALER_BANK_AccountsResponse *vr) { TALER_LOG_DEBUG ("Callback of accounts/$USERNAME\n"); (void) cls; + (void) vr; get_accounts_handle = NULL; ///LOGIC HERE @@ -386,6 +394,8 @@ shutdown_task (void *cls) GNUNET_CURL_fini (curl_ctx); curl_ctx = NULL; } + DIGITIZER_bank_auth_free (cfg_bank_authentication); + GNUNET_free(cfg_bank_authentication); } /** @@ -413,6 +423,26 @@ static void Init_state_task(void *cls) if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, "taler-digitizer", + "BANK_ACCOUNT", + &cfg_bank_account_username)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "taler-digitizer", + "BANK_ACCOUNT"); + global_ret = EXIT_FAILURE; + return; + } + if (GNUNET_OK != + DIGITIZER_bank_auth_parse_cfg (cfg, + "bank-authentication", + cfg_bank_authentication)) + { + global_ret = EXIT_FAILURE; + return; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "taler-digitizer", "EXCHANGE_BASE_URL", &cfg_exchange_base_url)) { @@ -780,11 +810,11 @@ static void TerminalError_state_task(void *cls) static void Idle_state_task(void *cls) { (void)cls; - cfg_bank get_accounts_handle = TALER_BANK_get_accounts (curl_ctx, cfg_bank_base_url, cfg_bank_account_username, + cfg_bank_authentication, &on_get_accounts_done, NULL); } @@ -846,6 +876,7 @@ run (void *cls, state = DIGITIZER_STATE_INIT; state_ctx = GNUNET_new(struct DIGITIZER_StateContext); display_ctx = GNUNET_new(struct DIGITIZER_DisplayContext); + cfg_bank_authentication = GNUNET_new(struct DIGITIZER_BankAuthenticationData); GNUNET_SCHEDULER_add_now(state_controller_task,(void *) cfg); diff --git a/src/taler/taler_digitizer_service.h b/src/taler/taler_digitizer_service.h @@ -27,6 +27,7 @@ #define _TALER_DIGITIZER_SERVICE_H #include <taler/taler_util.h> +#include <taler/taler_bank_service.h> /** * How compatible are the protocol version of the bank and this @@ -150,5 +151,75 @@ struct TALER_BANK_ChallengeContactData const char *phone_number; }; +/** + * authentication data for requests to bank + */ +struct DIGITIZER_BankAuthenticationData +{ + + /** + * Which authentication method should we use? + */ + enum TALER_BANK_AuthenticationMethod method; + + /** + * Further details as per @e method. + */ + union + { + + /** + * Details for #TALER_BANK_AUTH_BASIC. + */ + struct + { + /** + * Username to use. + */ + char *username; + + /** + * Password to use. + */ + char *password; + } basic; + + /** + * Details for #TALER_BANK_AUTH_BEARER. + */ + struct + { + /** + * Token to use. + */ + char *token; + + } bearer; + + } details; +}; + +/** + * Convenience method for parsing configuration section with bank + * authentication data. + * + * @param cfg configuration to parse + * @param section the section with the configuration data + * @param[out] auth set to the configuration data found + * @return #GNUNET_OK on success + */ +enum GNUNET_GenericReturnValue +DIGITIZER_bank_auth_parse_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, + const char *section, + struct DIGITIZER_BankAuthenticationData *auth); + +/** + * Free memory inside of @a auth (but not @a auth itself). + * Dual to #DIGITIZER_bank_auth_parse_cfg(). + * + * @param[in,out] auth authentication data to free + */ +void +DIGITIZER_bank_auth_free (struct DIGITIZER_BankAuthenticationData *auth); #endif \ No newline at end of file diff --git a/taler-digitizer.conf b/taler-digitizer.conf @@ -1,9 +1,8 @@ [taler-digitizer] -BANK_BASE_URL = https://bank.demo.taler.net/ CURRENCY = KUDOS - +BANK_BASE_URL = https://bank.demo.taler.net/ BANK_ACCOUNT = bank_acc_tellr -BANK_TOKEN = Bearer secret-token:HHPNC9XSV3X69RDENP4AHGWF5G681KVRVNJ7E5R6F3QB8J2Y8Y1G + # Withdrawl limitation per person, for a limited time period. # This can only be enforced with KYC functionality @@ -38,3 +37,7 @@ ENABLE = NO DEVICE = /dev/XXX MAX_DENOMINATION = 100 MIN_DENOMINATION = 10 + +[bank-authentication] +AUTH_METHOD = bearer +TOKEN = secret-token:HHPNC9XSV3X69RDENP4AHGWF5G681KVRVNJ7E5R6F3QB8J2Y8Y1G