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

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

Generated by: LCOV version 1.16