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:
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