LCOV - code coverage report
Current view: top level - exchangedb - exchangedb_history.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 19.3 % 88 17
Test Date: 2025-12-28 14:06:02 Functions: 28.6 % 7 2

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2023, 2024 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify it under the
       6              :   terms of the GNU Affero General Public License as published by the Free Software
       7              :   Foundation; either version 3, or (at your option) any later version.
       8              : 
       9              :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10              :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11              :   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
      12              : 
      13              :   You should have received a copy of the GNU Affero General Public License along with
      14              :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15              : */
      16              : /**
      17              :  * @file exchangedb_history.c
      18              :  * @brief helper function to build AML inputs from account histories
      19              :  * @author Christian Grothoff
      20              :  */
      21              : #include "taler/taler_exchangedb_plugin.h"
      22              : #include "taler/taler_exchangedb_lib.h"
      23              : #include "taler/taler_kyclogic_lib.h"
      24              : #include "taler/taler_json_lib.h"
      25              : #include <gnunet/gnunet_common.h>
      26              : 
      27              : /**
      28              :  * Function called to expand AML history for the account.
      29              :  *
      30              :  * @param cls a `json_t *` array to build
      31              :  * @param outcome_serial_id row ID of the decision
      32              :  * @param decision_time when was the decision taken
      33              :  * @param justification what was the given justification
      34              :  * @param decider_pub which key signed the decision
      35              :  * @param jproperties what are the new account properties
      36              :  * @param jnew_rules what are the new account rules
      37              :  * @param to_investigate should AML staff investigate
      38              :  *          after the decision
      39              :  * @param is_active is this the active decision
      40              :  */
      41              : static void
      42            0 : add_aml_history_entry (
      43              :   void *cls,
      44              :   uint64_t outcome_serial_id,
      45              :   struct GNUNET_TIME_Timestamp decision_time,
      46              :   const char *justification,
      47              :   const struct TALER_AmlOfficerPublicKeyP *decider_pub,
      48              :   const json_t *jproperties,
      49              :   const json_t *jnew_rules,
      50              :   bool to_investigate,
      51              :   bool is_active)
      52              : {
      53            0 :   json_t *aml_history = cls;
      54              :   json_t *e;
      55              : 
      56            0 :   e = GNUNET_JSON_PACK (
      57              :     GNUNET_JSON_pack_timestamp ("decision_time",
      58              :                                 decision_time),
      59              :     GNUNET_JSON_pack_string ("justification",
      60              :                              justification),
      61              :     GNUNET_JSON_pack_data_auto ("decider_pub",
      62              :                                 decider_pub),
      63              :     GNUNET_JSON_pack_object_incref ("properties",
      64              :                                     (json_t *) jproperties),
      65              :     GNUNET_JSON_pack_object_incref ("new_rules",
      66              :                                     (json_t *) jnew_rules),
      67              :     GNUNET_JSON_pack_bool ("to_investigate",
      68              :                            to_investigate),
      69              :     GNUNET_JSON_pack_bool ("is_active",
      70              :                            is_active)
      71              :     );
      72            0 :   GNUNET_assert (0 ==
      73              :                  json_array_append_new (aml_history,
      74              :                                         e));
      75            0 : }
      76              : 
      77              : 
      78              : json_t *
      79            0 : TALER_EXCHANGEDB_aml_history_builder (void *cls)
      80              : {
      81            0 :   struct TALER_EXCHANGEDB_HistoryBuilderContext *hbc = cls;
      82            0 :   const struct TALER_NormalizedPaytoHashP *acc = hbc->account;
      83              :   enum GNUNET_DB_QueryStatus qs;
      84              :   json_t *aml_history;
      85              : 
      86            0 :   aml_history = json_array ();
      87            0 :   GNUNET_assert (NULL != aml_history);
      88            0 :   qs = hbc->db_plugin->lookup_aml_history (
      89            0 :     hbc->db_plugin->cls,
      90              :     acc,
      91              :     UINT64_MAX, /* offset */
      92              :     -16 * 1024,  /* limit: none for all practical purposes (for now) */
      93              :     &add_aml_history_entry,
      94              :     aml_history);
      95            0 :   switch (qs)
      96              :   {
      97            0 :   case GNUNET_DB_STATUS_HARD_ERROR:
      98              :   case GNUNET_DB_STATUS_SOFT_ERROR:
      99            0 :     GNUNET_break (0);
     100            0 :     json_decref (aml_history);
     101            0 :     return NULL;
     102            0 :   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     103              :     /* empty history is fine! */
     104            0 :     break;
     105            0 :   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     106            0 :     break;
     107              :   }
     108            0 :   return aml_history;
     109              : }
     110              : 
     111              : 
     112              : /**
     113              :  * Closure for #add_kyc_history_entry.
     114              :  */
     115              : struct KycContext
     116              : {
     117              :   /**
     118              :    * JSON array we are building.
     119              :    */
     120              :   json_t *kyc_history;
     121              : 
     122              :   /**
     123              :    * Key to use to decrypt KYC attributes.
     124              :    */
     125              :   const struct TALER_AttributeEncryptionKeyP *attribute_key;
     126              : };
     127              : 
     128              : 
     129              : /**
     130              :  * Function called to expand KYC history for the account.
     131              :  *
     132              :  * @param cls a `json_t *` array to build
     133              :  * @param provider_name name of the KYC provider
     134              :  *    or NULL for none
     135              :  * @param finished did the KYC process finish
     136              :  * @param error_code error code from the KYC process
     137              :  * @param error_message error message from the KYC process,
     138              :  *    or NULL for none
     139              :  * @param provider_user_id user ID at the provider
     140              :  *    or NULL for none
     141              :  * @param provider_legitimization_id legitimization process ID at the provider
     142              :  *    or NULL for none
     143              :  * @param collection_time when was the data collected
     144              :  * @param expiration_time when does the collected data expire
     145              :  * @param encrypted_attributes_len number of bytes in @a encrypted_attributes
     146              :  * @param encrypted_attributes encrypted KYC attributes
     147              :  */
     148              : static void
     149            0 : add_kyc_history_entry (
     150              :   void *cls,
     151              :   const char *provider_name,
     152              :   bool finished,
     153              :   enum TALER_ErrorCode error_code,
     154              :   const char *error_message,
     155              :   const char *provider_user_id,
     156              :   const char *provider_legitimization_id,
     157              :   struct GNUNET_TIME_Timestamp collection_time,
     158              :   struct GNUNET_TIME_Absolute expiration_time,
     159              :   size_t encrypted_attributes_len,
     160              :   const void *encrypted_attributes)
     161              : {
     162            0 :   struct KycContext *kc = cls;
     163            0 :   json_t *kyc_history = kc->kyc_history;
     164              :   json_t *attributes;
     165              :   json_t *e;
     166              : 
     167            0 :   attributes = TALER_CRYPTO_kyc_attributes_decrypt (
     168              :     kc->attribute_key,
     169              :     encrypted_attributes,
     170              :     encrypted_attributes_len);
     171            0 :   e = GNUNET_JSON_PACK (
     172              :     GNUNET_JSON_pack_string (
     173              :       "provider_name",
     174              :       provider_name),
     175              :     GNUNET_JSON_pack_bool (
     176              :       "finished",
     177              :       finished),
     178              :     TALER_JSON_pack_ec (error_code),
     179              :     GNUNET_JSON_pack_allow_null (
     180              :       GNUNET_JSON_pack_string (
     181              :         "error_message",
     182              :         error_message)),
     183              :     GNUNET_JSON_pack_allow_null (
     184              :       GNUNET_JSON_pack_string (
     185              :         "provider_user_id",
     186              :         provider_user_id)),
     187              :     GNUNET_JSON_pack_allow_null (
     188              :       GNUNET_JSON_pack_string (
     189              :         "provider_legitimization_id",
     190              :         provider_legitimization_id)),
     191              :     GNUNET_JSON_pack_allow_null (
     192              :       GNUNET_JSON_pack_timestamp (
     193              :         "collection_time",
     194              :         collection_time)),
     195              :     GNUNET_JSON_pack_allow_null (
     196              :       GNUNET_JSON_pack_timestamp (
     197              :         "expiration_time",
     198              :         GNUNET_TIME_absolute_to_timestamp (
     199              :           expiration_time))),
     200              :     GNUNET_JSON_pack_allow_null (
     201              :       GNUNET_JSON_pack_object_steal (
     202              :         "attributes",
     203              :         attributes))
     204              :     );
     205              : 
     206            0 :   GNUNET_assert (0 ==
     207              :                  json_array_append_new (kyc_history,
     208              :                                         e));
     209            0 : }
     210              : 
     211              : 
     212              : json_t *
     213            0 : TALER_EXCHANGEDB_kyc_history_builder (void *cls)
     214              : {
     215            0 :   struct TALER_EXCHANGEDB_HistoryBuilderContext *hbc = cls;
     216            0 :   const struct TALER_NormalizedPaytoHashP *acc = hbc->account;
     217              :   enum GNUNET_DB_QueryStatus qs;
     218            0 :   struct KycContext kc = {
     219            0 :     .kyc_history = json_array (),
     220            0 :     .attribute_key = hbc->attribute_key
     221              :   };
     222              : 
     223            0 :   GNUNET_assert (NULL != kc.kyc_history);
     224            0 :   qs = hbc->db_plugin->lookup_kyc_history (
     225            0 :     hbc->db_plugin->cls,
     226              :     acc,
     227              :     &add_kyc_history_entry,
     228              :     &kc);
     229            0 :   switch (qs)
     230              :   {
     231            0 :   case GNUNET_DB_STATUS_HARD_ERROR:
     232              :   case GNUNET_DB_STATUS_SOFT_ERROR:
     233            0 :     GNUNET_break (0);
     234            0 :     json_decref (kc.kyc_history);
     235            0 :     return NULL;
     236            0 :   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     237              :     /* empty history is fine! */
     238            0 :     break;
     239            0 :   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     240            0 :     break;
     241              :   }
     242            0 :   return kc.kyc_history;
     243              : }
     244              : 
     245              : 
     246              : json_t *
     247            0 : TALER_EXCHANGEDB_current_rule_builder (void *cls)
     248              : {
     249            0 :   struct TALER_EXCHANGEDB_HistoryBuilderContext *hbc = cls;
     250            0 :   const struct TALER_NormalizedPaytoHashP *acc = hbc->account;
     251              :   enum GNUNET_DB_QueryStatus qs;
     252              :   json_t *jlrs;
     253              : 
     254            0 :   qs = hbc->db_plugin->get_kyc_rules2 (
     255            0 :     hbc->db_plugin->cls,
     256              :     acc,
     257              :     &jlrs);
     258            0 :   switch (qs)
     259              :   {
     260            0 :   case GNUNET_DB_STATUS_HARD_ERROR:
     261              :   case GNUNET_DB_STATUS_SOFT_ERROR:
     262            0 :     GNUNET_break (0);
     263            0 :     return NULL;
     264            0 :   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     265            0 :     jlrs = TALER_KYCLOGIC_get_default_legi_rules (
     266            0 :       hbc->is_wallet);
     267            0 :     break;
     268            0 :   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     269            0 :     break;
     270              :   }
     271            0 :   return jlrs;
     272              : }
     273              : 
     274              : 
     275              : /**
     276              :  * Closure for decrypt_attributes().
     277              :  */
     278              : struct DecryptContext
     279              : {
     280              :   /**
     281              :    * Overall context.
     282              :    */
     283              :   const struct TALER_EXCHANGEDB_HistoryBuilderContext *hbc;
     284              : 
     285              :   /**
     286              :    * Where to return the attributes.
     287              :    */
     288              :   json_t *attr;
     289              : };
     290              : 
     291              : 
     292              : /**
     293              :  * Decrypt and return AML attribute information.
     294              :  *
     295              :  * @param cls a `struct DecryptContext *`
     296              :  * @param row_id current row in kyc_attributes table
     297              :  * @param collection_time when were the attributes collected
     298              :  * @param by_aml_officer true if filed by AML officer
     299              :  * @param officer_name name of the officer, NULL if not @a by_aml_officer
     300              :  * @param enc_attributes_size size of @a enc_attributes
     301              :  * @param enc_attributes the encrypted collected attributes
     302              :  */
     303              : static void
     304           10 : decrypt_attributes (
     305              :   void *cls,
     306              :   uint64_t row_id,
     307              :   struct GNUNET_TIME_Timestamp collection_time,
     308              :   bool by_aml_officer,
     309              :   const char *officer_name,
     310              :   size_t enc_attributes_size,
     311              :   const void *enc_attributes)
     312              : {
     313           10 :   struct DecryptContext *decon = cls;
     314              : 
     315              :   (void) row_id;
     316              :   (void) collection_time;
     317              :   (void) officer_name;
     318              :   decon->attr
     319           10 :     = TALER_CRYPTO_kyc_attributes_decrypt (decon->hbc->attribute_key,
     320              :                                            enc_attributes,
     321              :                                            enc_attributes_size);
     322           10 :   GNUNET_break (NULL != decon->attr);
     323           10 : }
     324              : 
     325              : 
     326              : json_t *
     327           10 : TALER_EXCHANGEDB_current_attributes_builder (void *cls)
     328              : {
     329           10 :   struct TALER_EXCHANGEDB_HistoryBuilderContext *hbc = cls;
     330           10 :   const struct TALER_NormalizedPaytoHashP *acc = hbc->account;
     331              :   enum GNUNET_DB_QueryStatus qs;
     332           10 :   struct DecryptContext decon = {
     333              :     .hbc = hbc
     334              :   };
     335              : 
     336           10 :   qs = hbc->db_plugin->select_aml_attributes (
     337           10 :     hbc->db_plugin->cls,
     338              :     acc,
     339              :     INT64_MAX,
     340              :     -1, /* we only fetch the latest ones */
     341              :     &decrypt_attributes,
     342              :     &decon);
     343           10 :   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     344              :               "select_aml_attributes returned %d\n",
     345              :               (int) qs);
     346           10 :   switch (qs)
     347              :   {
     348            0 :   case GNUNET_DB_STATUS_HARD_ERROR:
     349              :   case GNUNET_DB_STATUS_SOFT_ERROR:
     350            0 :     GNUNET_break (0);
     351            0 :     return NULL;
     352            0 :   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     353            0 :     decon.attr = json_object ();
     354            0 :     GNUNET_break (NULL != decon.attr);
     355            0 :     break;
     356           10 :   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     357           10 :     GNUNET_break (NULL != decon.attr);
     358           10 :     break;
     359              :   }
     360           10 :   return decon.attr;
     361              : }
        

Generated by: LCOV version 2.0-1