donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

commit 2ef298fb7df19aca497e446077ec7cba63ce5908
parent 3395dca930d297b1949c71e28ac696bc8e9164f5
Author: Matyja Lukas Adam <lukas.matyja@students.bfh.ch>
Date:   Thu, 11 Jan 2024 21:44:31 +0100

[lib] started with get charity

Diffstat:
Msrc/include/donau_service.h | 13++++++++++++-
Msrc/include/donau_testing_lib.h | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/Makefile.am | 3++-
Asrc/lib/donau_api_charity_get.c | 248+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/donau_api_handle.c | 3+--
5 files changed, 445 insertions(+), 4 deletions(-)

diff --git a/src/include/donau_service.h b/src/include/donau_service.h @@ -935,6 +935,11 @@ struct CharityHistoryYear struct Charity { /** + * Charity id + */ + uint64_t charity_id; + + /** * name of the charity */ char *name; @@ -963,7 +968,7 @@ struct Charity /** - * @brief A /charities/ GET Handle + * @brief A /charities/$CHARITY_ID GET Handle */ struct DONAU_CharityGetHandle; @@ -1029,6 +1034,7 @@ typedef void * @param ctx curl context * @param url donau base URL * @param bearer for authentication + * @param id of the requested charity * @param cb the callback to call when a reply for this request is available * @param cb_cls closure for the above callback * @return a handle for this request; NULL if the inputs are invalid (i.e. @@ -1039,6 +1045,7 @@ DONAU_charity_get ( struct GNUNET_CURL_Context *ctx, const char *url, const struct DONAU_BearerToken bearer, + const uint64_t id, DONAU_GetCharityResponseCallback cb, void *cb_cls); @@ -1214,6 +1221,7 @@ typedef void * * @param ctx curl context * @param url donau base URL + * @param id of the charity * @param charity_req contains the name, public key and the max donation amount * @param cb the callback to call when a reply for this request is available * @param cb_cls closure for the above callback @@ -1224,6 +1232,7 @@ struct DONAU_CharityPatchHandle * DONAU_charity_patch ( struct GNUNET_CURL_Context *ctx, const char *url, + const uint64_t id, const struct DONAU_CharityRequest *charity_req, const struct DONAU_BearerToken bearer, DONAU_PatchCharityResponseCallback cb, @@ -1285,6 +1294,7 @@ typedef void * * @param ctx curl context * @param url donau base URL + * @param id of the charity * @param bearer for authentication * @param cb the callback to call when a reply for this request is available * @param cb_cls closure for the above callback @@ -1295,6 +1305,7 @@ struct DONAU_CharityDeleteHandle * DONAU_charity_delete ( struct GNUNET_CURL_Context *ctx, const char *url, + const uint64_t id, const struct DONAU_BearerToken bearer, DONAU_DeleteCharityResponseCallback cb, void *cb_cls); diff --git a/src/include/donau_testing_lib.h b/src/include/donau_testing_lib.h @@ -73,4 +73,186 @@ DONAU_TESTING_main (char *const *argv, TALER_TESTING_Main main_cb, void *main_cb_cls); + +/* ****** Specific traits supported by this component ******* */ + + +/** + * Create headers for a trait with name @a name for + * statically allocated data of type @a type. + */ +#define TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT(name,type) \ + enum GNUNET_GenericReturnValue \ + TALER_TESTING_get_trait_ ## name ( \ + const struct TALER_TESTING_Command *cmd, \ + type **ret); \ + struct TALER_TESTING_Trait \ + TALER_TESTING_make_trait_ ## name ( \ + type * value); + + +/** + * Create C implementation for a trait with name @a name for statically + * allocated data of type @a type. + */ +#define TALER_TESTING_MAKE_IMPL_SIMPLE_TRAIT(name,type) \ + enum GNUNET_GenericReturnValue \ + TALER_TESTING_get_trait_ ## name ( \ + const struct TALER_TESTING_Command *cmd, \ + type * *ret) \ + { \ + if (NULL == cmd->traits) return GNUNET_SYSERR; \ + return cmd->traits (cmd->cls, \ + (const void **) ret, \ + TALER_S (name), \ + 0); \ + } \ + struct TALER_TESTING_Trait \ + TALER_TESTING_make_trait_ ## name ( \ + type * value) \ + { \ + struct TALER_TESTING_Trait ret = { \ + .trait_name = TALER_S (name), \ + .ptr = (const void *) value \ + }; \ + return ret; \ + } + + +/** + * Create headers for a trait with name @a name for + * statically allocated data of type @a type. + */ +#define TALER_TESTING_MAKE_DECL_INDEXED_TRAIT(name,type) \ + enum GNUNET_GenericReturnValue \ + TALER_TESTING_get_trait_ ## name ( \ + const struct TALER_TESTING_Command *cmd, \ + unsigned int index, \ + type **ret); \ + struct TALER_TESTING_Trait \ + TALER_TESTING_make_trait_ ## name ( \ + unsigned int index, \ + type *value); + + +/** + * Create C implementation for a trait with name @a name for statically + * allocated data of type @a type. + */ +#define TALER_TESTING_MAKE_IMPL_INDEXED_TRAIT(name,type) \ + enum GNUNET_GenericReturnValue \ + TALER_TESTING_get_trait_ ## name ( \ + const struct TALER_TESTING_Command *cmd, \ + unsigned int index, \ + type * *ret) \ + { \ + if (NULL == cmd->traits) return GNUNET_SYSERR; \ + return cmd->traits (cmd->cls, \ + (const void **) ret, \ + TALER_S (name), \ + index); \ + } \ + struct TALER_TESTING_Trait \ + TALER_TESTING_make_trait_ ## name ( \ + unsigned int index, \ + type * value) \ + { \ + struct TALER_TESTING_Trait ret = { \ + .index = index, \ + .trait_name = TALER_S (name), \ + .ptr = (const void *) value \ + }; \ + return ret; \ + } + + +/** + * Call #op on all simple traits. + */ +#define TALER_TESTING_SIMPLE_TRAITS(op) \ + op (bank_row, const uint64_t) \ + op (officer_pub, const struct TALER_AmlOfficerPublicKeyP) \ + op (officer_priv, const struct TALER_AmlOfficerPrivateKeyP) \ + op (officer_name, const char) \ + op (aml_decision, enum TALER_AmlDecisionState) \ + op (aml_justification, const char) \ + op (auditor_priv, const struct TALER_AuditorPrivateKeyP) \ + op (auditor_pub, const struct TALER_AuditorPublicKeyP) \ + op (master_priv, const struct TALER_MasterPrivateKeyP) \ + op (master_pub, const struct TALER_MasterPublicKeyP) \ + op (purse_priv, const struct TALER_PurseContractPrivateKeyP) \ + op (purse_pub, const struct TALER_PurseContractPublicKeyP) \ + op (merge_priv, const struct TALER_PurseMergePrivateKeyP) \ + op (merge_pub, const struct TALER_PurseMergePublicKeyP) \ + op (contract_priv, const struct TALER_ContractDiffiePrivateP) \ + op (reserve_priv, const struct TALER_ReservePrivateKeyP) \ + op (reserve_sig, const struct TALER_ReserveSignatureP) \ + op (h_payto, const struct TALER_PaytoHashP) \ + op (planchet_secret, const struct TALER_PlanchetMasterSecretP) \ + op (refresh_secret, const struct TALER_RefreshMasterSecretP) \ + op (reserve_pub, const struct TALER_ReservePublicKeyP) \ + op (merchant_priv, const struct TALER_MerchantPrivateKeyP) \ + op (merchant_pub, const struct TALER_MerchantPublicKeyP) \ + op (merchant_sig, const struct TALER_MerchantSignatureP) \ + op (wtid, const struct TALER_WireTransferIdentifierRawP) \ + op (bank_auth_data, const struct TALER_BANK_AuthenticationData) \ + op (contract_terms, const json_t) \ + op (wire_details, const json_t) \ + op (exchange_url, const char) \ + op (auditor_url, const char) \ + op (exchange_bank_account_url, const char) \ + op (taler_uri, const char) \ + op (payto_uri, const char) \ + op (kyc_url, const char) \ + op (web_url, const char) \ + op (row, const uint64_t) \ + op (legi_requirement_row, const uint64_t) \ + op (array_length, const unsigned int) \ + op (credit_payto_uri, const char) \ + op (debit_payto_uri, const char) \ + op (order_id, const char) \ + op (amount, const struct TALER_Amount) \ + op (amount_with_fee, const struct TALER_Amount) \ + op (batch_cmds, struct TALER_TESTING_Command) \ + op (uuid, const struct GNUNET_Uuid) \ + op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \ + op (claim_token, const struct TALER_ClaimTokenP) \ + op (relative_time, const struct GNUNET_TIME_Relative) \ + op (fakebank, struct TALER_FAKEBANK_Handle) \ + op (keys, struct TALER_EXCHANGE_Keys) \ + op (process, struct GNUNET_OS_Process *) + + +/** + * Call #op on all indexed traits. + */ +#define TALER_TESTING_INDEXED_TRAITS(op) \ + op (denom_pub, const struct TALER_EXCHANGE_DenomPublicKey) \ + op (denom_sig, const struct TALER_DenominationSignature) \ + op (amounts, const struct TALER_Amount) \ + op (deposit_amount, const struct TALER_Amount) \ + op (deposit_fee_amount, const struct TALER_Amount) \ + op (age_commitment, const struct TALER_AgeCommitment) \ + op (age_commitment_proof, const struct TALER_AgeCommitmentProof) \ + op (h_age_commitment, const struct TALER_AgeCommitmentHash) \ + op (reserve_history, const struct TALER_EXCHANGE_ReserveHistoryEntry) \ + op (coin_history, const struct TALER_EXCHANGE_CoinHistoryEntry) \ + op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \ + op (exchange_wd_value, const struct TALER_ExchangeWithdrawValues) \ + op (coin_priv, const struct TALER_CoinSpendPrivateKeyP) \ + op (coin_pub, const struct TALER_CoinSpendPublicKeyP) \ + op (coin_sig, const struct TALER_CoinSpendSignatureP) \ + op (absolute_time, const struct GNUNET_TIME_Absolute) \ + op (timestamp, const struct GNUNET_TIME_Timestamp) \ + op (wire_deadline, const struct GNUNET_TIME_Timestamp) \ + op (refund_deadline, const struct GNUNET_TIME_Timestamp) \ + op (exchange_pub, const struct TALER_ExchangePublicKeyP) \ + op (exchange_sig, const struct TALER_ExchangeSignatureP) \ + op (blinding_key, const union GNUNET_CRYPTO_BlindingSecretP) \ + op (h_blinded_coin, const struct TALER_BlindedCoinHashP) + +TALER_TESTING_SIMPLE_TRAITS (TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT) + +TALER_TESTING_INDEXED_TRAITS (TALER_TESTING_MAKE_DECL_INDEXED_TRAIT) + #endif \ No newline at end of file diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am @@ -20,7 +20,8 @@ libdonau_la_LDFLAGS = \ -version-info 5:0:0 \ -no-undefined libdonau_la_SOURCES = \ - donau_api_handle.c donau_api_handle.h + donau_api_handle.c \ + donau_api_charity_get.c ## maybe need libtalercurl libdonau_la_LIBADD = \ diff --git a/src/lib/donau_api_charity_get.c b/src/lib/donau_api_charity_get.c @@ -0,0 +1,247 @@ +/* + This file is part of TALER + Copyright (C) 2024 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 + CHARITYABILITY 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/donau_api_charity_get.c + * @brief Implementation of the "handle" component of the donau's HTTP API + * @author Lukas Matyja + */ +#include <gnunet/gnunet_curl_lib.h> +#include "taler/taler_json_lib.h" +#include "donau_service.h" +#include "donau_api_curl_defaults.h" +#include "donau_json_lib.h" + + +/** + * Handle for a GET /charities/$CHARITY_ID request. + */ +struct DONAU_CharityGetHandle +{ + + /** + * The donau base URL (i.e. "http://donau.taler.net/") + */ + char *donau_url; + + /** + * The url for the /charities/$CHARITY_ID request. + */ + char *url; + + /** + * Entry for this request with the `struct GNUNET_CURL_Context`. + */ + struct GNUNET_CURL_Job *job; + + /** + * Function to call with the donau's certification data, + * NULL if this has already been done. + */ + DONAU_GetCharityResponseCallback cert_cb; + + /** + * Closure to pass to @e cert_cb. + */ + void *cert_cb_cls; + +}; + +/** + * Callback used when downloading the reply to a /charity request + * is complete. + * + * @param cls the `struct KeysRequest` + * @param response_code HTTP response code, 0 on error + * @param resp_obj parsed JSON result, NULL on error + */ +static void +charity_completed_cb (void *cls, + long response_code, + const void *resp_obj) +{ + struct DONAU_CharityGetHandle *cgh = cls; + //const json_t *j = resp_obj; + //struct Charity *cd = NULL; + + // struct DONAU_KeysResponse kresp = { + // .hr.reply = j, + // .hr.http_status = (unsigned int) response_code, + // .details.ok.compat = DONAU_VC_PROTOCOL_ERROR, + // }; + + // cgh->job = NULL; + // GNUNET_log (GNUNET_ERROR_TYPE_INFO, + // "Received keys from URL `%s' with status %ld.\n", + // cgh->url, + // response_code); + // switch (response_code) + // { + // case 0: + // GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + // "Failed to receive /keys response from donau %s\n", + // cgh->donau_url); + // break; + // case MHD_HTTP_OK: + // if (NULL == j) + // { + // GNUNET_break (0); + // response_code = 0; + // break; + // } + // kd = GNUNET_new (struct DONAU_Keys); + // kd->donau_url = GNUNET_strdup (cgh->donau_url); + + // if (GNUNET_OK != + // decode_keys_json (j, + // kd, + // &kresp.details.ok.compat)) + // { + // TALER_LOG_ERROR ("Could not decode /keys response\n"); + // kd->rc = 1; + // DONAU_keys_decref (kd); + // kd = NULL; + // kresp.hr.http_status = 0; + // kresp.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; + // break; + // } + // kd->rc = 1; + + // kresp.details.ok.keys = kd; + // break; + // case MHD_HTTP_BAD_REQUEST: + // case MHD_HTTP_UNAUTHORIZED: + // case MHD_HTTP_FORBIDDEN: + // case MHD_HTTP_NOT_FOUND: + // if (NULL == j) + // { + // kresp.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + // kresp.hr.hint = TALER_ErrorCode_get_hint (kresp.hr.ec); + // } + // else + // { + // kresp.hr.ec = TALER_JSON_get_error_code (j); + // kresp.hr.hint = TALER_JSON_get_error_hint (j); + // } + // break; + // default: + // if (NULL == j) + // { + // kresp.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + // kresp.hr.hint = TALER_ErrorCode_get_hint (kresp.hr.ec); + // } + // else + // { + // kresp.hr.ec = TALER_JSON_get_error_code (j); + // kresp.hr.hint = TALER_JSON_get_error_hint (j); + // } + // GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + // "Unexpected response code %u/%d\n", + // (unsigned int) response_code, + // (int) kresp.hr.ec); + // break; + // } + // cgh->cert_cb (cgh->cert_cb_cls, + // &kresp, + // kd); + DONAU_charity_get_cancel (cgh); +} + +struct DONAU_CharityGetHandle * +DONAU_charity_get ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct DONAU_BearerToken bearer, + const uint64_t id, + DONAU_GetCharityResponseCallback cb, + void *cb_cls) +{ + struct DONAU_CharityGetHandle *cgh; + CURL *eh; + + TALER_LOG_DEBUG ("Connecting to the donau (%s)\n", + url); + cgh = GNUNET_new (struct DONAU_CharityGetHandle); + cgh->donau_url = GNUNET_strdup (url); + cgh->cert_cb = cb; + cgh->cert_cb_cls = cb_cls; + char arg_str[sizeof (struct DONAU_DonationUnitHashP) * 2 + 32]; + char id_str[sizeof (struct DONAU_DonationUnitHashP) * 2]; + char *end; + + end = GNUNET_STRINGS_data_to_string (&id, + sizeof (id), + id_str, + sizeof (id_str)); + *end = '\0'; + GNUNET_snprintf (arg_str, + sizeof (arg_str), + "charities/%s", + id_str); + cgh->url = TALER_url_join (url, + arg_str, + NULL); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Requesting a charity with URL `%s'.\n", + cgh->url); + eh = DONAU_curl_easy_get_ (cgh->url); + if (NULL == eh) + { + GNUNET_break (0); + GNUNET_free (cgh->donau_url); + GNUNET_free (cgh->url); + GNUNET_free (cgh); + return NULL; + } + GNUNET_break (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_VERBOSE, + 0)); + GNUNET_break (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_TIMEOUT, + 120 /* seconds */)); + // GNUNET_assert (CURLE_OK == + // curl_easy_setopt (eh, + // CURLOPT_HEADERFUNCTION, + // &header_cb)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_HEADERDATA, + cgh)); + cgh->job = GNUNET_CURL_job_add_with_ct_json (ctx, + eh, + &charity_completed_cb, + cgh); + return cgh; +} + +void +DONAU_charity_get_cancel ( + struct DONAU_CharityGetHandle *cgh) +{ + if (NULL != cgh->job) + { + GNUNET_CURL_job_cancel (cgh->job); + cgh->job = NULL; + } + GNUNET_free (cgh->donau_url); + GNUNET_free (cgh->url); + GNUNET_free (cgh); +} +\ No newline at end of file diff --git a/src/lib/donau_api_handle.c b/src/lib/donau_api_handle.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2024 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 @@ -368,7 +368,6 @@ decode_keys_json (const json_t *resp_obj, parse_json_denomkey_partially pass */ struct DONAU_DonationUnitInformation dk = { .value = group.value - //.year = group.year }; bool found = false;