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 }