complete taler-exchange-httpd_reserves_get_attest.c logic (first pass, still without DB logic or tests)

This commit is contained in:
Christian Grothoff 2022-10-02 23:57:09 +02:00
parent 1ce70b1dab
commit 3bca75d6cf
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 178 additions and 13 deletions

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014-2022 Taler Systems SA Copyright (C) 2022 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software terms of the GNU Affero General Public License as published by the Free Software
@ -21,6 +21,7 @@
#include "platform.h" #include "platform.h"
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include <jansson.h> #include <jansson.h>
#include "taler_kyclogic_lib.h"
#include "taler_mhd_lib.h" #include "taler_mhd_lib.h"
#include "taler_json_lib.h" #include "taler_json_lib.h"
#include "taler_dbevents.h" #include "taler_dbevents.h"
@ -39,11 +40,21 @@ struct ReserveAttestContext
*/ */
struct TALER_ReservePublicKeyP reserve_pub; struct TALER_ReservePublicKeyP reserve_pub;
/**
* Hash of the payto URI of this reserve.
*/
struct TALER_PaytoHashP h_payto;
/** /**
* Available attributes. * Available attributes.
*/ */
json_t *attributes; json_t *attributes;
/**
* Error code encountered in interaction with KYC provider.
*/
enum TALER_ErrorCode ec;
/** /**
* Set to true if we did not find the reserve. * Set to true if we did not find the reserve.
*/ */
@ -51,6 +62,62 @@ struct ReserveAttestContext
}; };
/**
* Function called with information about all applicable
* legitimization processes for the given user.
*
* @param cls our `struct ReserveAttestContext *`
* @param provider_section KYC provider configuration section
* @param provider_user_id UID at a provider (can be NULL)
* @param legi_id legitimization process ID (can be NULL)
*/
static void
kyc_process_cb (void *cls,
const char *provider_section,
const char *provider_user_id,
const char *legi_id)
{
struct ReserveAttestContext *rsc = cls;
struct GNUNET_TIME_Timestamp etime;
json_t *attrs;
rsc->ec = TALER_KYCLOGIC_user_to_attributes (provider_section,
provider_user_id,
legi_id,
&etime,
&attrs);
if (TALER_EC_NONE != rsc->ec)
return;
{
json_t *val;
const char *name;
json_object_foreach (attrs, name, val)
{
bool duplicate = false;
size_t idx;
json_t *str;
json_array_foreach (rsc->attributes, idx, str)
{
if (0 == strcmp (json_string_value (str),
name))
{
duplicate = true;
break;
}
}
if (duplicate)
continue;
GNUNET_assert (0 ==
json_array_append (rsc->attributes,
json_string (name)));
}
}
}
/** /**
* Function implementing GET /reserves/$RID/attest transaction. * Function implementing GET /reserves/$RID/attest transaction.
* Execute a /reserves/ get attest. Given the public key of a reserve, * Execute a /reserves/ get attest. Given the public key of a reserve,
@ -75,26 +142,32 @@ reserve_attest_transaction (void *cls,
struct ReserveAttestContext *rsc = cls; struct ReserveAttestContext *rsc = cls;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
#if FIXME rsc->attributes = json_array ();
qs = TEH_plugin->get_reserve_attributes (TEH_plugin->cls, GNUNET_assert (NULL != rsc->attributes);
&rsc->reserve_pub, qs = TEH_plugin->iterate_kyc_reference (TEH_plugin->cls,
&rsc->attributes); &rsc->h_payto,
#else &kyc_process_cb,
qs = GNUNET_DB_STATUS_HARD_ERROR; rsc);
#endif switch (qs)
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{ {
case GNUNET_DB_STATUS_HARD_ERROR:
GNUNET_break (0); GNUNET_break (0);
*mhd_ret *mhd_ret
= TALER_MHD_reply_with_error (connection, = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED, TALER_EC_GENERIC_DB_FETCH_FAILED,
"get_reserve_attributes"); "get_reserve_attributes");
} return qs;
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) case GNUNET_DB_STATUS_SOFT_ERROR:
GNUNET_break (0);
return qs;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
rsc->not_found = true; rsc->not_found = true;
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) return qs;
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
rsc->not_found = false; rsc->not_found = false;
break;
}
return qs; return qs;
} }
@ -103,7 +176,9 @@ MHD_RESULT
TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc, TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc,
const char *const args[1]) const char *const args[1])
{ {
struct ReserveAttestContext rsc; struct ReserveAttestContext rsc = {
.attributes = NULL
};
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_STRINGS_string_to_data (args[0], GNUNET_STRINGS_string_to_data (args[0],
@ -117,6 +192,15 @@ TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc,
TALER_EC_GENERIC_RESERVE_PUB_MALFORMED, TALER_EC_GENERIC_RESERVE_PUB_MALFORMED,
args[0]); args[0]);
} }
{
char *payto_uri;
payto_uri = TALER_reserve_make_payto (TEH_base_url,
&rsc.reserve_pub);
TALER_payto_hash (payto_uri,
&rsc.h_payto);
GNUNET_free (payto_uri);
}
{ {
MHD_RESULT mhd_ret; MHD_RESULT mhd_ret;
@ -128,17 +212,26 @@ TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc,
&reserve_attest_transaction, &reserve_attest_transaction,
&rsc)) &rsc))
{ {
json_decref (rsc.attributes);
return mhd_ret; return mhd_ret;
} }
} }
/* generate proper response */ /* generate proper response */
if (rsc.not_found) if (rsc.not_found)
{ {
json_decref (rsc.attributes);
return TALER_MHD_reply_with_error (rc->connection, return TALER_MHD_reply_with_error (rc->connection,
MHD_HTTP_NOT_FOUND, MHD_HTTP_NOT_FOUND,
TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN, TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN,
args[0]); args[0]);
} }
if (TALER_EC_NONE != rsc.ec)
{
json_decref (rsc.attributes);
return TALER_MHD_reply_with_ec (rc->connection,
rsc.ec,
NULL);
}
return TALER_MHD_REPLY_JSON_PACK ( return TALER_MHD_REPLY_JSON_PACK (
rc->connection, rc->connection,
MHD_HTTP_OK, MHD_HTTP_OK,

View File

@ -877,6 +877,25 @@ typedef void
const char *kyc_provider_section_name); const char *kyc_provider_section_name);
/**
* Function called on all legitimization operations
* we have performed for the given account so far
* (and that have not yet expired).
*
* @param cls closure
* @param kyc_provider_section_name configuration section
* of the respective KYC process
* @param provider_user_id UID at a provider (can be NULL)
* @param legi_id legitimization process ID (can be NULL)
*/
typedef void
(*TALER_EXCHANGEDB_LegitimizationProcessCallback)(
void *cls,
const char *kyc_provider_section_name,
const char *provider_user_id,
const char *legi_id);
/** /**
* Function called with information about the exchange's auditors. * Function called with information about the exchange's auditors.
* *
@ -5819,6 +5838,24 @@ struct TALER_EXCHANGEDB_Plugin
void *spc_cls); void *spc_cls);
/**
* Call us on KYC legitimization processes satisfied and not expired for the
* given account.
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param h_payto account identifier
* @param lpc function to call for each satisfied KYC legitimization process
* @param lpc_cls closure for @a lpc
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*iterate_kyc_reference)(
void *cls,
const struct TALER_PaytoHashP *h_payto,
TALER_EXCHANGEDB_LegitimizationProcessCallback lpc,
void *lpc_cls);
/** /**
* Call @a kac on withdrawn amounts after @a time_limit which are relevant * Call @a kac on withdrawn amounts after @a time_limit which are relevant
* for a KYC trigger for a the (debited) account identified by @a h_payto. * for a KYC trigger for a the (debited) account identified by @a h_payto.

View File

@ -306,6 +306,27 @@ TALER_KYCLOGIC_requirements_to_logic (const char *requirements,
const char **configuration_section); const char **configuration_section);
/**
* Obtain attributes we collected about a user from a
* provider.
*
* @param provider_section configuration section of a
* provider that triggered KYC process for a user
* @param provider_user user ID of the user at the provider
* @param legitimization_id legitimizatin ID of a process
* of that user at the provider
* @param[out] attr_expiration set to when the @a attrs expire
* @param[out] attrs attributes we have about the user
* @return error code, #TALER_EC_NONE on success
*/
enum TALER_ErrorCode
TALER_KYCLOGIC_user_to_attributes (const char *provider_section,
const char *provider_user_id,
const char *legitimization_id,
struct GNUNET_TIME_Timestamp *attr_expiration,
json_t **attrs);
/** /**
* Obtain the provider logic for a given @a name. * Obtain the provider logic for a given @a name.
* *

View File

@ -1311,4 +1311,18 @@ TALER_KYCLOGIC_kyc_iterate_thresholds (
} }
enum TALER_ErrorCode
TALER_KYCLOGIC_user_to_attributes (const char *provider_section,
const char *provider_user_id,
const char *legitimization_id,
struct GNUNET_TIME_Timestamp *attr_expiration,
json_t **attrs)
{
GNUNET_break (0); // FIXME: not yet implemented!!!
*attrs = json_object ();
*attr_expiration = GNUNET_TIME_UNIT_ZERO_TS;
return TALER_EC_NONE;
}
/* end of taler-exchange-httpd_kyc.c */ /* end of taler-exchange-httpd_kyc.c */