merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

taler-merchant-httpd_get-private-products.c (5400B)


      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/lookup_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 add_product (void *cls,
     35              uint64_t product_serial,
     36              const char *product_id)
     37 {
     38   json_t *pa = cls;
     39 
     40   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 }
     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 tr (const char *input)
     61 {
     62   char *out;
     63   size_t slen;
     64   size_t wpos;
     65 
     66   if (NULL == input)
     67     return NULL;
     68   slen = strlen (input);
     69   out = GNUNET_malloc (slen * 2 + 3);
     70   wpos = 0;
     71   out[wpos++] = '%';
     72   for (size_t i = 0; i<slen; i++)
     73   {
     74     char c = input[i];
     75 
     76     if ( (c == '%') ||
     77          (c == '_') )
     78       out[wpos++] = '\\';
     79     out[wpos++] = c;
     80   }
     81   out[wpos++] = '%';
     82   GNUNET_assert (wpos < slen * 2 + 3);
     83   return out;
     84 }
     85 
     86 
     87 enum MHD_Result
     88 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   uint64_t product_group_id_filter = 0;
    100 
    101   limit = 20; /* default */
    102   TALER_MHD_parse_request_snumber (connection,
    103                                    "limit",
    104                                    &limit);
    105   if (limit < 0)
    106     offset = INT64_MAX;
    107   else
    108     offset = 0;
    109   TALER_MHD_parse_request_number (connection,
    110                                   "offset",
    111                                   &offset);
    112   TALER_MHD_parse_request_number (connection,
    113                                   "product_group_filter",
    114                                   &product_group_id_filter);
    115   category_filter = tr (MHD_lookup_connection_value (connection,
    116                                                      MHD_GET_ARGUMENT_KIND,
    117                                                      "category_filter"));
    118   name_filter = tr (MHD_lookup_connection_value (connection,
    119                                                  MHD_GET_ARGUMENT_KIND,
    120                                                  "name_filter"));
    121   description_filter = tr (MHD_lookup_connection_value (connection,
    122                                                         MHD_GET_ARGUMENT_KIND,
    123                                                         "description_filter"));
    124   pa = json_array ();
    125   GNUNET_assert (NULL != pa);
    126   qs = TALER_MERCHANTDB_lookup_products (TMH_db,
    127                                          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   GNUNET_free (category_filter);
    137   GNUNET_free (name_filter);
    138   GNUNET_free (description_filter);
    139   if (0 > qs)
    140   {
    141     GNUNET_break (0);
    142     json_decref (pa);
    143     return TALER_MHD_reply_with_error (connection,
    144                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
    145                                        TALER_EC_GENERIC_DB_FETCH_FAILED,
    146                                        NULL);
    147   }
    148   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 */