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