taler-merchant-httpd_private-get-products.c (4989B)
1 /* 2 This file is part of TALER 3 (C) 2019, 2020, 2021, 2024, 2025 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 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 taler-merchant-httpd_private-get-products.c 18 * @brief implement GET /products 19 * @author Christian Grothoff 20 */ 21 #include "platform.h" 22 #include "taler-merchant-httpd_private-get-products.h" 23 24 25 /** 26 * Add product details to our JSON array. 27 * 28 * @param cls a `json_t *` JSON array to build 29 * @param product_serial serial (row) number of the product in the database 30 * @param product_id ID of the product 31 */ 32 static void 33 add_product (void *cls, 34 uint64_t product_serial, 35 const char *product_id) 36 { 37 json_t *pa = cls; 38 39 GNUNET_assert (0 == 40 json_array_append_new ( 41 pa, 42 GNUNET_JSON_PACK ( 43 GNUNET_JSON_pack_uint64 ("product_serial", 44 product_serial), 45 GNUNET_JSON_pack_string ("product_id", 46 product_id)))); 47 } 48 49 50 /** 51 * Transforms an (untrusted) input filter into a Postgresql LIKE filter. 52 * Escapes "%" and "_" in the @a input and adds "%" at the beginning 53 * and the end to turn the @a input into a suitable Postgresql argument. 54 * 55 * @param input text to turn into a substring match expression, or NULL 56 * @return NULL if @a input was NULL, otherwise transformed @a input 57 */ 58 static char * 59 tr (const char *input) 60 { 61 char *out; 62 size_t slen; 63 size_t wpos; 64 65 if (NULL == input) 66 return NULL; 67 slen = strlen (input); 68 out = GNUNET_malloc (slen * 2 + 3); 69 wpos = 0; 70 out[wpos++] = '%'; 71 for (size_t i = 0; i<slen; i++) 72 { 73 char c = input[i]; 74 75 if ( (c == '%') || 76 (c == '_') ) 77 out[wpos++] = '\\'; 78 out[wpos++] = c; 79 } 80 out[wpos++] = '%'; 81 GNUNET_assert (wpos < slen * 2 + 3); 82 return out; 83 } 84 85 86 MHD_RESULT 87 TMH_private_get_products (const struct TMH_RequestHandler *rh, 88 struct MHD_Connection *connection, 89 struct TMH_HandlerContext *hc) 90 { 91 json_t *pa; 92 enum GNUNET_DB_QueryStatus qs; 93 char *category_filter; 94 char *name_filter; 95 char *description_filter; 96 int64_t limit; 97 uint64_t offset; 98 99 limit = 20; /* default */ 100 TALER_MHD_parse_request_snumber (connection, 101 "limit", 102 &limit); 103 if (limit < 0) 104 offset = INT64_MAX; 105 else 106 offset = 0; 107 TALER_MHD_parse_request_number (connection, 108 "offset", 109 &offset); 110 category_filter = tr (MHD_lookup_connection_value (connection, 111 MHD_GET_ARGUMENT_KIND, 112 "category_filter")); 113 name_filter = tr (MHD_lookup_connection_value (connection, 114 MHD_GET_ARGUMENT_KIND, 115 "name_filter")); 116 description_filter = tr (MHD_lookup_connection_value (connection, 117 MHD_GET_ARGUMENT_KIND, 118 "description_filter")); 119 pa = json_array (); 120 GNUNET_assert (NULL != pa); 121 qs = TMH_db->lookup_products (TMH_db->cls, 122 hc->instance->settings.id, 123 offset, 124 limit, 125 category_filter, 126 name_filter, 127 description_filter, 128 &add_product, 129 pa); 130 GNUNET_free (category_filter); 131 GNUNET_free (name_filter); 132 GNUNET_free (description_filter); 133 if (0 > qs) 134 { 135 GNUNET_break (0); 136 json_decref (pa); 137 return TALER_MHD_reply_with_error (connection, 138 MHD_HTTP_INTERNAL_SERVER_ERROR, 139 TALER_EC_GENERIC_DB_FETCH_FAILED, 140 NULL); 141 } 142 return TALER_MHD_REPLY_JSON_PACK (connection, 143 MHD_HTTP_OK, 144 GNUNET_JSON_pack_array_steal ("products", 145 pa)); 146 } 147 148 149 /* end of taler-merchant-httpd_private-get-products.c */