diff options
| -rw-r--r-- | src/exchange/taler-exchange-httpd_reserves_get_attest.c | 119 | ||||
| -rw-r--r-- | src/include/taler_exchangedb_plugin.h | 37 | ||||
| -rw-r--r-- | src/include/taler_kyclogic_lib.h | 21 | ||||
| -rw-r--r-- | src/kyclogic/kyclogic_api.c | 14 | 
4 files changed, 178 insertions, 13 deletions
| diff --git a/src/exchange/taler-exchange-httpd_reserves_get_attest.c b/src/exchange/taler-exchange-httpd_reserves_get_attest.c index 8fd346c2..bd574acd 100644 --- a/src/exchange/taler-exchange-httpd_reserves_get_attest.c +++ b/src/exchange/taler-exchange-httpd_reserves_get_attest.c @@ -1,6 +1,6 @@  /*    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    terms of the GNU Affero General Public License as published by the Free Software @@ -21,6 +21,7 @@  #include "platform.h"  #include <gnunet/gnunet_util_lib.h>  #include <jansson.h> +#include "taler_kyclogic_lib.h"  #include "taler_mhd_lib.h"  #include "taler_json_lib.h"  #include "taler_dbevents.h" @@ -40,11 +41,21 @@ struct ReserveAttestContext    struct TALER_ReservePublicKeyP reserve_pub;    /** +   * Hash of the payto URI of this reserve. +   */ +  struct TALER_PaytoHashP h_payto; + +  /**     * Available 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.     */    bool not_found; @@ -52,6 +63,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.   * Execute a /reserves/ get attest.  Given the public key of a reserve,   * return the associated transaction attest.  Runs the @@ -75,26 +142,32 @@ reserve_attest_transaction (void *cls,    struct ReserveAttestContext *rsc = cls;    enum GNUNET_DB_QueryStatus qs; -#if FIXME -  qs = TEH_plugin->get_reserve_attributes (TEH_plugin->cls, -                                           &rsc->reserve_pub, -                                           &rsc->attributes); -#else -  qs = GNUNET_DB_STATUS_HARD_ERROR; -#endif -  if (GNUNET_DB_STATUS_HARD_ERROR == qs) +  rsc->attributes = json_array (); +  GNUNET_assert (NULL != rsc->attributes); +  qs = TEH_plugin->iterate_kyc_reference (TEH_plugin->cls, +                                          &rsc->h_payto, +                                          &kyc_process_cb, +                                          rsc); +  switch (qs)    { +  case GNUNET_DB_STATUS_HARD_ERROR:      GNUNET_break (0);      *mhd_ret        = TALER_MHD_reply_with_error (connection,                                      MHD_HTTP_INTERNAL_SERVER_ERROR,                                      TALER_EC_GENERIC_DB_FETCH_FAILED,                                      "get_reserve_attributes"); -  } -  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) +    return qs; +  case GNUNET_DB_STATUS_SOFT_ERROR: +    GNUNET_break (0); +    return qs; +  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:      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; +    break; +  }    return qs;  } @@ -103,7 +176,9 @@ MHD_RESULT  TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc,                                   const char *const args[1])  { -  struct ReserveAttestContext rsc; +  struct ReserveAttestContext rsc = { +    .attributes = NULL +  };    if (GNUNET_OK !=        GNUNET_STRINGS_string_to_data (args[0], @@ -118,6 +193,15 @@ TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc,                                         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;      if (GNUNET_OK != @@ -128,17 +212,26 @@ TEH_handler_reserves_get_attest (struct TEH_RequestContext *rc,                                  &reserve_attest_transaction,                                  &rsc))      { +      json_decref (rsc.attributes);        return mhd_ret;      }    }    /* generate proper response */    if (rsc.not_found)    { +    json_decref (rsc.attributes);      return TALER_MHD_reply_with_error (rc->connection,                                         MHD_HTTP_NOT_FOUND,                                         TALER_EC_EXCHANGE_GENERIC_RESERVE_UNKNOWN,                                         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 (      rc->connection,      MHD_HTTP_OK, diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 609265f1..e5cc8dfa 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -878,6 +878,25 @@ typedef void  /** + * 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.   *   * @param cls closure with a `struct TEH_KeyStateHandle *` @@ -5820,6 +5839,24 @@ struct TALER_EXCHANGEDB_Plugin    /** +   * 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     * for a KYC trigger for a the (debited) account identified by @a h_payto.     * diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h index 2ff652f9..7f4bf5b5 100644 --- a/src/include/taler_kyclogic_lib.h +++ b/src/include/taler_kyclogic_lib.h @@ -307,6 +307,27 @@ TALER_KYCLOGIC_requirements_to_logic (const char *requirements,  /** + * 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.   *   * @param name name of the logic or provider section diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c index b04c2419..0c4a5112 100644 --- a/src/kyclogic/kyclogic_api.c +++ b/src/kyclogic/kyclogic_api.c @@ -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 */ | 
