aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-07-28 11:53:32 +0200
committerChristian Grothoff <christian@grothoff.org>2024-07-29 12:18:49 +0200
commit412952ddbdf2c0b10e6271f26e0a3b6fed39f374 (patch)
tree37065d0d0f3bad406ba9eba5e2b571c7aecfcc92
parent16f967fe07ab1dac37a2a0622999efd01f49858e (diff)
downloadexchange-412952ddbdf2c0b10e6271f26e0a3b6fed39f374.tar.xz
finish kyc-upload endpoint
m---------contrib/gana0
-rw-r--r--src/exchange/taler-exchange-httpd_kyc-upload.c98
-rw-r--r--src/exchange/taler-exchange-httpd_reserves_get_attest.c10
-rw-r--r--src/include/taler_kyclogic_lib.h8
-rw-r--r--src/kyclogic/kyclogic_api.c23
5 files changed, 81 insertions, 58 deletions
diff --git a/contrib/gana b/contrib/gana
-Subproject 4b0b4afb5a9a47d89d461f6a16159ed5369ae14
+Subproject d0a05d57c856c8b68342ac075fb8d5f0f26f5df
diff --git a/src/exchange/taler-exchange-httpd_kyc-upload.c b/src/exchange/taler-exchange-httpd_kyc-upload.c
index 12dbcb3e8..2b870249d 100644
--- a/src/exchange/taler-exchange-httpd_kyc-upload.c
+++ b/src/exchange/taler-exchange-httpd_kyc-upload.c
@@ -351,10 +351,11 @@ aml_trigger_callback (
MHD_RESULT
-TEH_handler_kyc_upload (struct TEH_RequestContext *rc,
- const char *id,
- size_t *upload_data_size,
- const char *upload_data)
+TEH_handler_kyc_upload (
+ struct TEH_RequestContext *rc,
+ const char *id,
+ size_t *upload_data_size,
+ const char *upload_data)
{
struct UploadContext *uc = rc->rh_ctx;
@@ -365,10 +366,11 @@ TEH_handler_kyc_upload (struct TEH_RequestContext *rc,
uc = GNUNET_new (struct UploadContext);
uc->rc = rc;
- uc->pp = MHD_create_post_processor (rc->connection,
- UPLOAD_BUFFER_SIZE,
- &post_helper,
- uc);
+ uc->pp = MHD_create_post_processor (
+ rc->connection,
+ UPLOAD_BUFFER_SIZE,
+ &post_helper,
+ uc);
if (NULL == uc->pp)
{
GNUNET_break (0);
@@ -407,11 +409,12 @@ TEH_handler_kyc_upload (struct TEH_RequestContext *rc,
TALER_EC_GENERIC_PARAMETER_MALFORMED,
"Access token in ID is malformed");
}
- if (2 != sscanf (slash + 1,
- "%u-%llu%c",
- &uc->measure_index,
- &uc->legitimization_measure_serial_id,
- &dummy))
+ if (2 !=
+ sscanf (slash + 1,
+ "%u-%llu%c",
+ &uc->measure_index,
+ &uc->legitimization_measure_serial_id,
+ &dummy))
{
GNUNET_break_op (0);
return TALER_MHD_reply_with_error (
@@ -450,7 +453,8 @@ TEH_handler_kyc_upload (struct TEH_RequestContext *rc,
bool is_finished = false;
size_t enc_attributes_len;
void *enc_attributes;
- json_t *xattributes;
+ const char *error_message;
+ enum TALER_ErrorCode ec;
qs = TEH_plugin->lookup_pending_legitimization (
TEH_plugin->cls,
@@ -482,38 +486,54 @@ TEH_handler_kyc_upload (struct TEH_RequestContext *rc,
if (is_finished)
{
- // FIXME: should check for idempotency:
- // enc_attributes -> xattributes
- // json_equal (xattributes, attributes)?
- // => return OK (idempotent)
- // or fail (conflicting submission)
-
- /* Note: we do not distinguish between row ID unknown and
- access token wrong here; this is on purpose to
- minimize information leakage (but we could distinguish
- the two in the future to help diagnose issues) */
-
- GNUNET_free (enc_attributes);
+ if (NULL != enc_attributes)
+ {
+ json_t *xattributes;
+
+ xattributes
+ = TALER_CRYPTO_kyc_attributes_decrypt (
+ &TEH_attribute_key,
+ enc_attributes,
+ enc_attributes_len);
+ if (json_equal (xattributes,
+ uc->result))
+ {
+ /* Request is idempotent! */
+ json_decref (xattributes);
+ GNUNET_free (enc_attributes);
+ return TALER_MHD_reply_static (
+ rc->connection,
+ MHD_HTTP_NO_CONTENT,
+ NULL,
+ NULL,
+ 0);
+ }
+ json_decref (xattributes);
+ GNUNET_free (enc_attributes);
+ }
+ /* Finished, and with no or different attributes, conflict! */
+ GNUNET_break_op (0);
return TALER_MHD_reply_with_error (
rc->connection,
MHD_HTTP_CONFLICT,
- -1, // FIXME: TALER_EC_EXCHANGE_KYC_FORM_ALREADY_SUBMITTED
+ TALER_EC_EXCHANGE_KYC_FORM_ALREADY_UPLOADED,
NULL);
-
}
+ /* This _should_ not be possible (! is_finished but non-null enc_attributes),
+ but also cannot exactly hurt... */
GNUNET_free (enc_attributes);
- if (GNUNET_OK !=
- TALER_KYCLOGIC_check_form (jmeasures,
- uc->measure_index,
- uc->result))
+ ec = TALER_KYCLOGIC_check_form (jmeasures,
+ uc->measure_index,
+ uc->result,
+ &error_message);
+ if (TALER_EC_NONE != ec)
{
GNUNET_break_op (0);
json_decref (jmeasures);
- return TALER_MHD_reply_with_error (
+ return TALER_MHD_reply_with_ec (
rc->connection,
- MHD_HTTP_CONFLICT,
- -1, // FIXME: TALER_EC_EXCHANGE_KYC_FORM_MEASURE_MISMATCH
- NULL);
+ ec,
+ error_message);
}
json_decref (jmeasures);
@@ -569,10 +589,4 @@ TEH_handler_kyc_upload (struct TEH_RequestContext *rc,
uc);
return MHD_YES;
}
- // FIXME: should check for idempotency above!
- return TALER_MHD_reply_with_error (
- rc->connection,
- MHD_HTTP_CONFLICT,
- TALER_EC_EXCHANGE_KYC_FORM_ALREADY_UPLOADED,
- "insert_kyc_attributes");
}
diff --git a/src/exchange/taler-exchange-httpd_reserves_get_attest.c b/src/exchange/taler-exchange-httpd_reserves_get_attest.c
index 53eff1f5c..602b52ae7 100644
--- a/src/exchange/taler-exchange-httpd_reserves_get_attest.c
+++ b/src/exchange/taler-exchange-httpd_reserves_get_attest.c
@@ -83,11 +83,13 @@ kyc_process_cb (void *cls,
json_t *val;
const char *name;
- if (GNUNET_TIME_absolute_is_past (expiration_time.abs_time))
+ if (GNUNET_TIME_absolute_is_past (
+ expiration_time.abs_time))
return;
- attrs = TALER_CRYPTO_kyc_attributes_decrypt (&TEH_attribute_key,
- enc_attributes,
- enc_attributes_size);
+ attrs = TALER_CRYPTO_kyc_attributes_decrypt (
+ &TEH_attribute_key,
+ enc_attributes,
+ enc_attributes_size);
json_object_foreach (attrs, name, val)
{
bool duplicate = false;
diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h
index 45fc3c56e..57eb587c0 100644
--- a/src/include/taler_kyclogic_lib.h
+++ b/src/include/taler_kyclogic_lib.h
@@ -502,13 +502,15 @@ TALER_KYCLOGIC_select_measure (
* @param jmeasures a LegitimizationMeasures object
* @param measure_index an index into the measures
* @param form_data form data submitted for the measure
- * @return #GNUNET_OK if the form data matches the measure
+ * @param[out] error_message set to error details
+ * @return #TALER_EC_NONE if the form data matches the measure
*/
-enum GNUNET_GenericReturnValue
+enum TALER_ErrorCode
TALER_KYCLOGIC_check_form (
const json_t *jmeasures,
size_t measure_index,
- const json_t *form_data);
+ const json_t *form_data,
+ const char **error_message);
/**
diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c
index aef9d6369..0e39a63a1 100644
--- a/src/kyclogic/kyclogic_api.c
+++ b/src/kyclogic/kyclogic_api.c
@@ -3016,11 +3016,12 @@ TALER_KYCLOGIC_select_measure (
}
-enum GNUNET_GenericReturnValue
+enum TALER_ErrorCode
TALER_KYCLOGIC_check_form (
const json_t *jmeasures,
size_t measure_index,
- const json_t *form_data)
+ const json_t *form_data,
+ const char **error_message)
{
const char *check_name;
const char *prog_name;
@@ -3028,6 +3029,7 @@ TALER_KYCLOGIC_check_form (
struct TALER_KYCLOGIC_KycCheck *kc;
struct TALER_KYCLOGIC_AmlProgram *prog;
+ *error_message = NULL;
if (TALER_EC_NONE !=
TALER_KYCLOGIC_select_measure (jmeasures,
measure_index,
@@ -3036,24 +3038,26 @@ TALER_KYCLOGIC_check_form (
&context))
{
GNUNET_break_op (0);
- return GNUNET_SYSERR;
+ return TALER_EC_EXCHANGE_KYC_MEASURE_INDEX_INVALID;
}
kc = find_check (check_name);
if (NULL == kc)
{
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
+ GNUNET_break (0);
+ *error_message = check_name;
+ return TALER_EC_EXCHANGE_KYC_GENERIC_CHECK_GONE;
}
if (TALER_KYCLOGIC_CT_FORM != kc->type)
{
GNUNET_break_op (0);
- return GNUNET_SYSERR;
+ return TALER_EC_EXCHANGE_KYC_NOT_A_FORM;
}
prog = find_program (prog_name);
if (NULL == prog)
{
GNUNET_break (0);
- return GNUNET_SYSERR;
+ *error_message = prog_name;
+ return TALER_EC_EXCHANGE_KYC_GENERIC_AML_PROGRAM_GONE;
}
for (unsigned int i = 0; i<prog->num_required_attributes; i++)
{
@@ -3066,10 +3070,11 @@ TALER_KYCLOGIC_check_form (
"Form data lacks required attribute `%s' for AML program %s\n",
rattr,
prog_name);
- return GNUNET_NO;
+ *error_message = rattr;
+ return TALER_EC_EXCHANGE_KYC_AML_FORM_INCOMPLETE;
}
}
- return GNUNET_OK;
+ return TALER_EC_NONE;
}