merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

lookup_instances.c (8975B)


      1 /*
      2    This file is part of TALER
      3    Copyright (C) 2022--2026 Taler Systems SA
      4 
      5    TALER is free software; you can redistribute it and/or modify it under the
      6    terms of the GNU 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 General Public License for more details.
     12 
     13    You should have received a copy of the GNU General Public License along with
     14    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 /**
     17  * @file src/backenddb/lookup_instances.c
     18  * @brief Implementation of the lookup_instances function for Postgres
     19  * @author Christian Grothoff
     20  */
     21 #include "platform.h"
     22 #include <taler/taler_pq_lib.h>
     23 #include "merchant-database/lookup_instances.h"
     24 #include "helper.h"
     25 
     26 
     27 /**
     28  * Context for lookup_instances().
     29  */
     30 struct LookupInstancesContext
     31 {
     32   /**
     33    * Function to call with the results.
     34    */
     35   TALER_MERCHANTDB_InstanceCallback cb;
     36 
     37   /**
     38    * Closure for @e cb.
     39    */
     40   void *cb_cls;
     41 
     42   /**
     43    * Database context.
     44    */
     45   struct TALER_MERCHANTDB_PostgresContext *pg;
     46 
     47   /**
     48    * Set to the return value on errors.
     49    */
     50   enum GNUNET_DB_QueryStatus qs;
     51 
     52 };
     53 
     54 
     55 /**
     56  * Function to be called with the results of a SELECT statement
     57  * that has returned @a num_results results about instances.
     58  *
     59  * @param cls of type `struct LookupInstancesContext *`
     60  * @param result the postgres result
     61  * @param num_results the number of results in @a result
     62  */
     63 static void
     64 lookup_instances_cb (void *cls,
     65                      PGresult *result,
     66                      unsigned int num_results)
     67 {
     68   struct LookupInstancesContext *lic = cls;
     69 
     70   for (unsigned int i = 0; i < num_results; i++)
     71   {
     72     struct TALER_MERCHANTDB_InstanceSettings is;
     73     struct TALER_MERCHANTDB_InstanceAuthSettings ias;
     74     uint64_t instance_serial;
     75     struct TALER_MerchantPublicKeyP merchant_pub;
     76     struct TALER_MerchantPrivateKeyP merchant_priv;
     77     bool no_auth;
     78     bool no_salt;
     79     bool no_priv;
     80     char *dwtri;
     81     struct GNUNET_PQ_ResultSpec rs[] = {
     82       GNUNET_PQ_result_spec_uint64 ("merchant_serial",
     83                                     &instance_serial),
     84       GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
     85                                             &merchant_pub),
     86       GNUNET_PQ_result_spec_allow_null (
     87         GNUNET_PQ_result_spec_auto_from_type ("auth_hash",
     88                                               &ias.auth_hash),
     89         &no_auth),
     90       GNUNET_PQ_result_spec_allow_null (
     91         GNUNET_PQ_result_spec_auto_from_type ("auth_salt",
     92                                               &ias.auth_salt),
     93         &no_salt),
     94       GNUNET_PQ_result_spec_allow_null (
     95         GNUNET_PQ_result_spec_auto_from_type ("merchant_priv",
     96                                               &merchant_priv),
     97         &no_priv),
     98       GNUNET_PQ_result_spec_string ("merchant_id",
     99                                     &is.id),
    100       GNUNET_PQ_result_spec_string ("merchant_name",
    101                                     &is.name),
    102       TALER_PQ_result_spec_json ("address",
    103                                  &is.address),
    104       TALER_PQ_result_spec_json ("jurisdiction",
    105                                  &is.jurisdiction),
    106       GNUNET_PQ_result_spec_bool ("use_stefan",
    107                                   &is.use_stefan),
    108       GNUNET_PQ_result_spec_bool ("phone_validated",
    109                                   &is.phone_validated),
    110       GNUNET_PQ_result_spec_bool ("email_validated",
    111                                   &is.email_validated),
    112       GNUNET_PQ_result_spec_relative_time (
    113         "default_wire_transfer_delay",
    114         &is.default_wire_transfer_delay),
    115       GNUNET_PQ_result_spec_relative_time ("default_pay_delay",
    116                                            &is.default_pay_delay),
    117       GNUNET_PQ_result_spec_relative_time ("default_refund_delay",
    118                                            &is.default_refund_delay),
    119       GNUNET_PQ_result_spec_allow_null (
    120         GNUNET_PQ_result_spec_string ("website",
    121                                       &is.website),
    122         NULL),
    123       GNUNET_PQ_result_spec_allow_null (
    124         GNUNET_PQ_result_spec_string ("email",
    125                                       &is.email),
    126         NULL),
    127       GNUNET_PQ_result_spec_allow_null (
    128         GNUNET_PQ_result_spec_string ("phone_number",
    129                                       &is.phone),
    130         NULL),
    131       GNUNET_PQ_result_spec_allow_null (
    132         GNUNET_PQ_result_spec_string ("logo",
    133                                       &is.logo),
    134         NULL),
    135       GNUNET_PQ_result_spec_string (
    136         "default_wire_transfer_rounding_interval",
    137         &dwtri),
    138       GNUNET_PQ_result_spec_end
    139     };
    140 
    141     memset (&ias.auth_salt,
    142             0,
    143             sizeof (ias.auth_salt));
    144     memset (&ias.auth_hash,
    145             0,
    146             sizeof (ias.auth_hash));
    147     if (GNUNET_OK !=
    148         GNUNET_PQ_extract_result (result,
    149                                   rs,
    150                                   i))
    151     {
    152       GNUNET_break (0);
    153       lic->qs = GNUNET_DB_STATUS_HARD_ERROR;
    154       return;
    155     }
    156     if (GNUNET_OK !=
    157         GNUNET_TIME_string_to_round_interval (
    158           dwtri,
    159           &is.default_wire_transfer_rounding_interval))
    160     {
    161       GNUNET_break (0);
    162       lic->qs = GNUNET_DB_STATUS_HARD_ERROR;
    163       return;
    164     }
    165     lic->cb (lic->cb_cls,
    166              &merchant_pub,
    167              (no_priv) ? NULL : &merchant_priv,
    168              &is,
    169              &ias);
    170     GNUNET_PQ_cleanup_result (rs);
    171   }
    172 }
    173 
    174 
    175 enum GNUNET_DB_QueryStatus
    176 TALER_MERCHANTDB_lookup_instances (
    177   struct TALER_MERCHANTDB_PostgresContext *pg,
    178   bool active_only,
    179   TALER_MERCHANTDB_InstanceCallback cb,
    180   void *cb_cls)
    181 {
    182   struct LookupInstancesContext lic = {
    183     .cb = cb,
    184     .cb_cls = cb_cls,
    185     .pg = pg
    186   };
    187   struct GNUNET_PQ_QueryParam params[] = {
    188     GNUNET_PQ_query_param_bool (active_only),
    189     GNUNET_PQ_query_param_end
    190   };
    191   enum GNUNET_DB_QueryStatus qs;
    192 
    193   check_connection (pg);
    194   PREPARE (pg,
    195            "lookup_instances",
    196            "SELECT"
    197            "  merchant_serial"
    198            " ,merchant_pub"
    199            " ,auth_hash"
    200            " ,auth_salt"
    201            " ,merchant_priv"
    202            " ,merchant_id"
    203            " ,merchant_name"
    204            " ,address::TEXT"
    205            " ,jurisdiction::TEXT"
    206            " ,use_stefan"
    207            " ,phone_validated"
    208            " ,email_validated"
    209            " ,default_wire_transfer_delay"
    210            " ,default_pay_delay"
    211            " ,default_refund_delay"
    212            " ,website"
    213            " ,email"
    214            " ,phone_number"
    215            " ,logo"
    216            " ,default_wire_transfer_rounding_interval::TEXT"
    217            "  FROM merchant.merchant_instances"
    218            " WHERE (NOT $1 OR merchant_priv IS NOT NULL)");
    219   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
    220                                              "lookup_instances",
    221                                              params,
    222                                              &lookup_instances_cb,
    223                                              &lic);
    224   if (0 > lic.qs)
    225     return lic.qs;
    226   return qs;
    227 }
    228 
    229 
    230 enum GNUNET_DB_QueryStatus
    231 TALER_MERCHANTDB_lookup_instance (
    232   struct TALER_MERCHANTDB_PostgresContext *pg,
    233   const char *id,
    234   bool active_only,
    235   TALER_MERCHANTDB_InstanceCallback cb,
    236   void *cb_cls)
    237 {
    238   struct LookupInstancesContext lic = {
    239     .cb = cb,
    240     .cb_cls = cb_cls,
    241     .pg = pg
    242   };
    243   struct GNUNET_PQ_QueryParam params[] = {
    244     GNUNET_PQ_query_param_bool (active_only),
    245     GNUNET_PQ_query_param_string (id),
    246     GNUNET_PQ_query_param_end
    247   };
    248   enum GNUNET_DB_QueryStatus qs;
    249 
    250   check_connection (pg);
    251   PREPARE (pg,
    252            "lookup_instance",
    253            "SELECT"
    254            "  merchant_serial"
    255            " ,merchant_pub"
    256            " ,auth_hash"
    257            " ,auth_salt"
    258            " ,merchant_priv"
    259            " ,merchant_id"
    260            " ,merchant_name"
    261            " ,address::TEXT"
    262            " ,jurisdiction::TEXT"
    263            " ,use_stefan"
    264            " ,phone_validated"
    265            " ,email_validated"
    266            " ,default_wire_transfer_delay"
    267            " ,default_pay_delay"
    268            " ,default_refund_delay"
    269            " ,website"
    270            " ,email"
    271            " ,phone_number"
    272            " ,logo"
    273            " ,default_wire_transfer_rounding_interval::TEXT"
    274            "  FROM merchant.merchant_instances"
    275            " WHERE (merchant_id = $2)"
    276            "   AND (NOT $1 OR merchant_priv IS NOT NULL)");
    277   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
    278                                              "lookup_instance",
    279                                              params,
    280                                              &lookup_instances_cb,
    281                                              &lic);
    282   if (0 > lic.qs)
    283     return lic.qs;
    284   return qs;
    285 }