taler-merchant-httpd_get-private-products.c (5257B)
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_get-private-products.c 18 * @brief implement GET /products 19 * @author Christian Grothoff 20 */ 21 #include "taler/platform.h" 22 #include "taler-merchant-httpd_get-private-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 uint64_t product_group_id_filter = 0; 99 100 limit = 20; /* default */ 101 TALER_MHD_parse_request_snumber (connection, 102 "limit", 103 &limit); 104 if (limit < 0) 105 offset = INT64_MAX; 106 else 107 offset = 0; 108 TALER_MHD_parse_request_number (connection, 109 "offset", 110 &offset); 111 TALER_MHD_parse_request_number (connection, 112 "product_group_filter", 113 &product_group_id_filter); 114 category_filter = tr (MHD_lookup_connection_value (connection, 115 MHD_GET_ARGUMENT_KIND, 116 "category_filter")); 117 name_filter = tr (MHD_lookup_connection_value (connection, 118 MHD_GET_ARGUMENT_KIND, 119 "name_filter")); 120 description_filter = tr (MHD_lookup_connection_value (connection, 121 MHD_GET_ARGUMENT_KIND, 122 "description_filter")); 123 pa = json_array (); 124 GNUNET_assert (NULL != pa); 125 qs = TMH_db->lookup_products (TMH_db->cls, 126 hc->instance->settings.id, 127 offset, 128 limit, 129 category_filter, 130 name_filter, 131 description_filter, 132 product_group_id_filter, 133 &add_product, 134 pa); 135 GNUNET_free (category_filter); 136 GNUNET_free (name_filter); 137 GNUNET_free (description_filter); 138 if (0 > qs) 139 { 140 GNUNET_break (0); 141 json_decref (pa); 142 return TALER_MHD_reply_with_error (connection, 143 MHD_HTTP_INTERNAL_SERVER_ERROR, 144 TALER_EC_GENERIC_DB_FETCH_FAILED, 145 NULL); 146 } 147 return TALER_MHD_REPLY_JSON_PACK (connection, 148 MHD_HTTP_OK, 149 GNUNET_JSON_pack_array_steal ("products", 150 pa)); 151 } 152 153 154 /* end of taler-merchant-httpd_get-private-products.c */