exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit d135bff489267cb7d8b89a280855edce3aaaf662
parent 4047818b299348606e483d5a0d14f19c53815216
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 27 Nov 2025 16:56:15 +0100

work on GET /attributes PDF generation

Diffstat:
Msrc/exchange/taler-exchange-httpd.c | 8++++----
Msrc/exchange/taler-exchange-httpd.h | 2+-
Msrc/exchange/taler-exchange-httpd_aml-attributes-get.c | 41++++++++++++++++++-----------------------
Msrc/exchangedb/exchangedb_history.c | 2++
Msrc/exchangedb/pg_select_aml_attributes.c | 6++++++
Msrc/include/taler/taler_error_codes.h | 8++++++++
Msrc/include/taler/taler_exchangedb_plugin.h | 2++
Msrc/util/taler_error_codes.c | 10+++++++++-
8 files changed, 50 insertions(+), 29 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c @@ -2464,10 +2464,10 @@ exchange_serve_process_config (const char *cfg_fn) GNUNET_free (pdf_data); if (NULL == TEH_global_pdf_form_data) { - GNUNET_log_config_malformed (GNUNET_ERROR_TYPE_ERROR, - "exchange", - "GLOBAL_PDF_FORM_DATA", - err.text); + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + "exchange", + "GLOBAL_PDF_FORM_DATA", + err.text); return GNUNET_SYSERR; } } diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h @@ -172,7 +172,7 @@ extern const struct TALER_CurrencySpecification *TEH_cspec; /** * Form data to inject into any Typst form generation. */ -json_t *TEH_global_pdf_form_data; +extern json_t *TEH_global_pdf_form_data; /** * Our currency. diff --git a/src/exchange/taler-exchange-httpd_aml-attributes-get.c b/src/exchange/taler-exchange-httpd_aml-attributes-get.c @@ -190,6 +190,7 @@ free_rc (struct TEH_RequestContext *rc) * @param cls closure * @param row_id current row in kyc_attributes table * @param collection_time when were the attributes collected + * @param by_aml_officer was the attribute set filed by the AML officer * @param enc_attributes_size length of @a enc_attributes * @param enc_attributes the encrypted collected attributes */ @@ -198,6 +199,7 @@ detail_cb ( void *cls, uint64_t row_id, struct GNUNET_TIME_Timestamp collection_time, + bool by_aml_officer, size_t enc_attributes_size, const void *enc_attributes) { @@ -237,6 +239,8 @@ detail_cb ( GNUNET_JSON_PACK ( GNUNET_JSON_pack_int64 ("rowid", row_id), + GNUNET_JSON_pack_bool ("by_aml_officer", + by_aml_officer), GNUNET_JSON_pack_allow_null ( GNUNET_JSON_pack_object_steal ("attributes", attrs)), @@ -250,6 +254,10 @@ detail_cb ( json_object_set_new (attrs, "DATADIR", json_string (datadir))); + GNUNET_assert (0 == + json_object_set_new (attrs, + "BY_AML_OFFICER", + json_boolean (by_aml_officer))); { char *have; @@ -257,7 +265,7 @@ detail_cb ( "HAVE_%s", form_id); GNUNET_assert (0 == - json_object_set_new (rc->pdf.global_attrs, + json_object_set_new (rc->details.pdf.global_attrs, have, json_true ())); GNUNET_free (have); @@ -271,6 +279,7 @@ detail_cb ( rc->details.pdf.docs[rc->details.pdf.off].data = rc->details.pdf.jdata[rc->details.pdf.off]; rc->details.pdf.off++; + // All attachments are under "SOMETHING.FILE", so look for ".FILE"! // FIXME: deal with attachments, use extra slots for those! break; } @@ -311,25 +320,6 @@ pdf_cb (void *cls, } -/** - * Adds cross-reference data to each @a doc that are only available - * in @a rctx after we have processed all inputs. - * - * @param rctx global context - * @param doc document to modify - */ -static void -post_process_pdf (struct ResponseContext *rctx, - struct TALER_MHD_TypstDocument *doc) -{ - json_t *attrs = doc->attrs; - - GNUNET_assert (0 == - json_object_update_missing (attrs, - rctx->pdf.global_attrs)); -} - - MHD_RESULT TEH_handler_aml_attributes_get ( struct TEH_RequestContext *rc, @@ -417,7 +407,7 @@ TEH_handler_aml_attributes_get ( GNUNET_assert (NULL != rctx->details.pdf.global_attrs); if (NULL != TEH_global_pdf_form_data) GNUNET_assert (0 == - json_object_update (attrs, + json_object_update (rctx->details.pdf.global_attrs, TEH_global_pdf_form_data)); // FIXME: need to obtain globals about the // account here first, like the FILE_NUMBER. @@ -492,8 +482,13 @@ TEH_handler_aml_attributes_get ( 0); } for (unsigned int i = 0; i<rctx->details.pdf.off; i++) - post_process_pdf (rctx, - &rctx->details.pdf.docs[i]); + { + GNUNET_assert (0 == + json_object_update_missing ( + rctx->details.pdf.jdata[i], + rctx->details.pdf.global_attrs) + ); + } GNUNET_CONTAINER_DLL_insert (rctx_head, rctx_tail, rctx); diff --git a/src/exchangedb/exchangedb_history.c b/src/exchangedb/exchangedb_history.c @@ -291,6 +291,7 @@ struct DecryptContext * @param cls a `struct DecryptContext *` * @param row_id current row in kyc_attributes table * @param collection_time when were the attributes collected + * @param by_aml_officer true if filed by AML officer * @param enc_attributes_size size of @a enc_attributes * @param enc_attributes the encrypted collected attributes */ @@ -299,6 +300,7 @@ decrypt_attributes ( void *cls, uint64_t row_id, struct GNUNET_TIME_Timestamp collection_time, + bool by_aml_officer, size_t enc_attributes_size, const void *enc_attributes) { diff --git a/src/exchangedb/pg_select_aml_attributes.c b/src/exchangedb/pg_select_aml_attributes.c @@ -73,6 +73,7 @@ handle_aml_attributes (void *cls, { uint64_t rowid; struct GNUNET_TIME_Timestamp collection_time; + bool by_aml_officer; size_t enc_attributes_size; void *enc_attributes; struct GNUNET_PQ_ResultSpec rs[] = { @@ -80,6 +81,8 @@ handle_aml_attributes (void *cls, &rowid), GNUNET_PQ_result_spec_timestamp ("collection_time", &collection_time), + GNUNET_PQ_result_spec_bool ("by_aml_officer", + &by_aml_officer), GNUNET_PQ_result_spec_variable_size ("encrypted_attributes", &enc_attributes, &enc_attributes_size), @@ -99,6 +102,7 @@ handle_aml_attributes (void *cls, ctx->cb (ctx->cb_cls, rowid, collection_time, + by_aml_officer, enc_attributes_size, enc_attributes); GNUNET_PQ_cleanup_result (rs); @@ -139,6 +143,7 @@ TEH_PG_select_aml_attributes ( "SELECT" " kyc_attributes_serial_id" ",collection_time" + ",by_aml_officer" ",encrypted_attributes" " FROM kyc_attributes" " WHERE h_payto=$1" @@ -150,6 +155,7 @@ TEH_PG_select_aml_attributes ( "SELECT" " kyc_attributes_serial_id" ",collection_time" + ",by_aml_officer" ",encrypted_attributes" " FROM kyc_attributes" " WHERE h_payto=$1" diff --git a/src/include/taler/taler_error_codes.h b/src/include/taler/taler_error_codes.h @@ -800,6 +800,14 @@ enum TALER_ErrorCode /** + * One of the binaries needed to generate the PDF is not installed. If this feature is required, the system administrator should make sure Typst and pdftk are both installed. + * Returned with an HTTP status code of #MHD_HTTP_NOT_IMPLEMENTED (501). + * (A value of 0 indicates that the error is generated client-side). + */ + TALER_EC_EXCHANGE_GENERIC_NO_TYPST_OR_PDFTK = 1048, + + + /** * The exchange did not find information about the specified transaction in the database. * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND (404). * (A value of 0 indicates that the error is generated client-side). diff --git a/src/include/taler/taler_exchangedb_plugin.h b/src/include/taler/taler_exchangedb_plugin.h @@ -3902,6 +3902,7 @@ typedef void * @param cls closure * @param row_id current row in kyc_attributes table * @param collection_time when were the attributes collected + * @param by_aml_officer true if the data was filed by an AML officer * @param enc_attributes_size size of @a enc_attributes * @param enc_attributes the encrypted collected attributes */ @@ -3910,6 +3911,7 @@ typedef void void *cls, uint64_t row_id, struct GNUNET_TIME_Timestamp collection_time, + bool by_aml_officer, size_t enc_attributes_size, const void *enc_attributes); diff --git a/src/util/taler_error_codes.c b/src/util/taler_error_codes.c @@ -803,6 +803,14 @@ static const struct ErrorCodeAndHint code_hint_pairs[] = { }, { + /* 1048 */ + .ec = TALER_EC_EXCHANGE_GENERIC_NO_TYPST_OR_PDFTK, + .hint = gettext_noop ( + "One of the binaries needed to generate the PDF is not installed. If this feature is required, the system administrator should make sure Typst and pdftk are both installed."), + .http_code = MHD_HTTP_NOT_IMPLEMENTED + }, + + { /* 1100 */ .ec = TALER_EC_EXCHANGE_DEPOSITS_GET_NOT_FOUND, .hint = gettext_noop ( @@ -5475,7 +5483,7 @@ static const struct ErrorCodeAndHint code_hint_pairs[] = { /** * The length of @e code_hint_pairs. */ -static const unsigned int code_hint_pairs_length = 685; +static const unsigned int code_hint_pairs_length = 686; const char *