Line data Source code
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 3 : add_product (void *cls,
34 : uint64_t product_serial,
35 : const char *product_id)
36 : {
37 3 : json_t *pa = cls;
38 :
39 3 : 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 3 : }
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 36 : tr (const char *input)
60 : {
61 : char *out;
62 : size_t slen;
63 : size_t wpos;
64 :
65 36 : if (NULL == input)
66 35 : return NULL;
67 1 : slen = strlen (input);
68 1 : out = GNUNET_malloc (slen * 2 + 3);
69 1 : wpos = 0;
70 1 : out[wpos++] = '%';
71 5 : for (size_t i = 0; i<slen; i++)
72 : {
73 4 : char c = input[i];
74 :
75 4 : if ( (c == '%') ||
76 : (c == '_') )
77 0 : out[wpos++] = '\\';
78 4 : out[wpos++] = c;
79 : }
80 1 : out[wpos++] = '%';
81 1 : GNUNET_assert (wpos < slen * 2 + 3);
82 1 : return out;
83 : }
84 :
85 :
86 : MHD_RESULT
87 12 : 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 12 : limit = 20; /* default */
100 12 : TALER_MHD_parse_request_snumber (connection,
101 : "limit",
102 : &limit);
103 12 : if (limit < 0)
104 0 : offset = INT64_MAX;
105 : else
106 12 : offset = 0;
107 12 : TALER_MHD_parse_request_number (connection,
108 : "offset",
109 : &offset);
110 12 : category_filter = tr (MHD_lookup_connection_value (connection,
111 : MHD_GET_ARGUMENT_KIND,
112 : "category_filter"));
113 12 : name_filter = tr (MHD_lookup_connection_value (connection,
114 : MHD_GET_ARGUMENT_KIND,
115 : "name_filter"));
116 12 : description_filter = tr (MHD_lookup_connection_value (connection,
117 : MHD_GET_ARGUMENT_KIND,
118 : "description_filter"));
119 12 : pa = json_array ();
120 12 : GNUNET_assert (NULL != pa);
121 12 : qs = TMH_db->lookup_products (TMH_db->cls,
122 12 : hc->instance->settings.id,
123 : offset,
124 : limit,
125 : category_filter,
126 : name_filter,
127 : description_filter,
128 : &add_product,
129 : pa);
130 12 : GNUNET_free (category_filter);
131 12 : GNUNET_free (name_filter);
132 12 : GNUNET_free (description_filter);
133 12 : if (0 > qs)
134 : {
135 0 : GNUNET_break (0);
136 0 : json_decref (pa);
137 0 : return TALER_MHD_reply_with_error (connection,
138 : MHD_HTTP_INTERNAL_SERVER_ERROR,
139 : TALER_EC_GENERIC_DB_FETCH_FAILED,
140 : NULL);
141 : }
142 12 : 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 */
|