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

Generated by: LCOV version 2.0-1