donau

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

commit fe0a69a43f5fc05404fc10f58fac4423450644a3
parent 0d6062a0d3e0cf167d3902856f0584d04eaf5996
Author: Matyja Lukas Adam <lukas.matyja@students.bfh.ch>
Date:   Wed, 13 Mar 2024 00:00:04 +0100

[lib] start implement API batch-issue

Diffstat:
Msrc/include/donau_service.h | 20+++++++++++---------
Msrc/lib/Makefile.am | 1+
Asrc/lib/donau_api_batch_issue_receipts.c | 258+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/donau_api_charity_post.c | 6+++---
4 files changed, 273 insertions(+), 12 deletions(-)

diff --git a/src/include/donau_service.h b/src/include/donau_service.h @@ -442,7 +442,7 @@ struct DONAU_BatchIssueReceiptHandle; * Structure with information about a batch * of issue receipts. */ -struct DONAU_BatchIssueReceipts +struct DONAU_BatchIssueResponse { /** * HTTP response data @@ -492,7 +492,7 @@ struct DONAU_BatchIssueReceipts typedef void (*DONAU_BatchIssueReceiptsCallback) ( void *cls, - const struct DONAU_BatchIssueReceipts*dr); + const struct DONAU_BatchIssueResponse*dr); /** @@ -521,13 +521,15 @@ typedef void */ struct DONAU_BatchIssueReceiptHandle * DONAU_charity_issue_receipt ( - struct GNUNET_CURL_Context *ctx, - const char *url, - const struct DONAU_CharityPrivateKeyP *charity_priv, - unsigned int num_bkp, - const struct DONAU_BlindedUniqueDonationIdentifierKeyPair bkp[static num_bkp], - DONAU_BatchIssueReceiptsCallback cb, - void *cb_cls); + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct DONAU_CharityPrivateKeyP *charity_priv, + const uint64_t charity_id, + const uint64_t year, + const unsigned int num_bkp, + const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp[static num_bkp], + DONAU_BatchIssueReceiptsCallback cb, + void *cb_cls); /** * Cancel a batch issue receipt request. This function cannot be used diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am @@ -26,6 +26,7 @@ libdonau_la_SOURCES = \ donau_api_charity_delete.c \ donau_api_charities_get.c \ donau_api_curl_defaults.c donau_api_curl_defaults.h + #donau_api_batch_issue_receipts.c ## maybe need libtalercurl libdonau_la_LIBADD = \ diff --git a/src/lib/donau_api_batch_issue_receipts.c b/src/lib/donau_api_batch_issue_receipts.c @@ -0,0 +1,258 @@ +/* + 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 + 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/donau_api_charity_post.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 <taler/taler_curl_lib.h> +#include "donau_service.h" +#include "donau_util.h" +#include "donau_api_curl_defaults.h" +#include "donau_json_lib.h" + + +/** + * Handle for a POST /batch-issue/$CHARITY_ID request. + */ +struct DONAU_BatchIssueReceiptHandle +{ + /** + * The url for the /batch-issue/$CHARITY_ID request. + */ + char *url; + + /** + * Minor context that holds body and headers. + */ + struct TALER_CURL_PostContext post_ctx; + + /** + * Entry for this request with the `struct GNUNET_CURL_Context`. + */ + struct GNUNET_CURL_Job *job; + + /** + * Function to call with the result. + */ + DONAU_PostCharityResponseCallback cb; + + /** + * BUDI-key-pair signature. + */ + struct DONAU_CharitySignatureP charity_sig; + + /** + * Closure to pass to @e cb. + */ + void *cb_cls; + + /** + * Reference to the execution context. + */ + struct GNUNET_CURL_Context *ctx; + +}; + +/** + * Transform issue receipt request into JSON. + * + * @param num_bkp number of budi-key-pairs in @bkp + * @param bkp budi-key-pair array + * @param year corresponding year + * @param charity_sig signature from charity over @bkp + */ +json_t * +budi_key_pair_to_json (const unsigned int num_bkp, + const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp[static num_bkp], + const uint64_t year; + const DONAU_CharitySignatureP *charity_sig) +{ + json_t *budikeypairs; + for (unsigned int i = 0; i < num_bkp; i++) + { + json_t *budikeypair; + + budikeypair = GNUNET_JSON_PACK ( + GNUNET_JSON_pack_data_auto ("bkp", + &bkp[i])); + GNUNET_assert (NULL != signkey); + GNUNET_assert (0 == + json_array_append_new (budikeypairs, + budikeypair)); + } + return GNUNET_JSON_PACK ( + GNUNET_JSON_pack_array_steal ("budikeypairs", + budikeypairs), + GNUNET_JSON_pack_data_auto ("charity_sig", + charity_sig), + GNUNET_JSON_pack_uint64 ("year", + year)); +} + +/** + * Function called when we're done processing the + * HTTP POST /batch-issue/$CHARITY_ID request. + * + * @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 +handle_batch_issue_finished (void *cls, + long response_code, + const void *resp_obj) +{ + struct DONAU_BatchIssueReceiptHandle *birh = cls; + const json_t *j = resp_obj; + + struct DONAU_BatchIssueResponse biresp = { + .hr.reply = j, + .hr.http_status = (unsigned int) response_code + }; + + birh->job = NULL; + switch (response_code) + { + case MHD_HTTP_CREATED: + break; + case MHD_HTTP_NO_CONTENT: + biresp.hr.ec = TALER_JSON_get_error_code (j); + biresp.hr.hint = TALER_JSON_get_error_hint (j); + break; + case MHD_HTTP_FORBIDDEN: + biresp.hr.ec = TALER_JSON_get_error_code (j); + biresp.hr.hint = TALER_JSON_get_error_hint (j); + break; + case MHD_HTTP_NOT_FOUND: + biresp.hr.ec = TALER_JSON_get_error_code (j); + biresp.hr.hint = TALER_JSON_get_error_hint (j); + break; + case MHD_HTTP_CONTENT_TOO_LARGE: + biresp.hr.ec = TALER_JSON_get_error_code (j); + biresp.hr.hint = TALER_JSON_get_error_hint (j); + break; + default: + /* unexpected response code */ + GNUNET_break_op (0); + biresp.hr.ec = TALER_JSON_get_error_code (j); + biresp.hr.hint = TALER_JSON_get_error_hint (j); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u/%d for POST %s\n", + (unsigned int) response_code, + (int) biresp.hr.ec, + birh->url); + break; + } + if (NULL != birh->cb) + { + birh->cb (birh->cb_cls, + &biresp); + birh->cb = NULL; + } + DONAU_charity_issue_receipt_cancel (birh); +} + + +struct DONAU_CharityPostHandle * +DONAU_charity_issue_receipt ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct DONAU_CharityPrivateKeyP *charity_priv, + const uint64_t charity_id, + const uint64_t year, + const unsigned int num_bkp, + const struct DONAU_BlindedUniqueDonationIdentifierKeyPair *bkp[static num_bkp], + DONAU_BatchIssueReceiptsCallback cb, + void *cb_cls) +{ + struct DONAU_BatchIssueReceiptHandle *birh; + CURL *eh; + json_t *body; + + // make signature over budi-key-pair + DONAU_charity_budi_key_pair_sign(bkp, charity_priv, &birh->charity_sig); + + TALER_LOG_DEBUG ("Connecting to the donau (%s)\n", + url); + birh = GNUNET_new (struct DONAU_BatchIssueReceiptHandle); + birh->url = GNUNET_strdup (url); + birh->cb = cb; + birh->cb_cls = cb_cls; + birh->ctx = ctx; + char arg_str[sizeof (id) * 2 + 32]; + GNUNET_snprintf (arg_str, + sizeof (arg_str), + "batch-issue/%llu", + (unsigned long long) + id); + cgh->url = TALER_url_join (url, + arg_str, + NULL); + if (NULL == birh->url) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Could not construct request URL.\n"); + GNUNET_free (birh); + return NULL; + } + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "issue receipts with URL `%s'.\n", + birh->url); + body = issue_receipt_body_to_json(num_bkp, bkp, year, &birh->charity_sig); + eh = DONAU_curl_easy_get_ (birh->url); + if ( (NULL == eh) || + (GNUNET_OK != + TALER_curl_easy_post (&birh->post_ctx, + eh, + body)) ) + { + GNUNET_break (0); + if (NULL != eh) + curl_easy_cleanup (eh); + json_decref (body); + GNUNET_free (birh->url); + return NULL; + } + json_decref (body); + birh->job = GNUNET_CURL_job_add2 (ctx, + eh, + birh->post_ctx.headers, + &handle_batch_issue_finished, + birh); + return birh; +} + + +void +DONAU_charity_issue_receipt_cancel ( + struct DONAU_BatchIssueReceiptHandle *birh) +{ + if (NULL != birh->job) + { + GNUNET_CURL_job_cancel (birh->job); + birh->job = NULL; + } + TALER_curl_easy_post_finished (&birh->post_ctx); + GNUNET_free (birh->url); + GNUNET_free (birh); +} diff --git a/src/lib/donau_api_charity_post.c b/src/lib/donau_api_charity_post.c @@ -18,7 +18,7 @@ */ /** - * @file lib/donau_api_charity_post.c + * @file lib/donau_batch_issue_receipts.c * @brief Implementation of the "handle" component of the donau's HTTP API * @author Lukas Matyja */ @@ -31,12 +31,12 @@ /** - * Handle for a POST /charities/ request. + * Handle for a POST /charities request. */ struct DONAU_CharityPostHandle { /** - * The url for the /charities/ request. + * The url for the /charities request. */ char *url;