merchant

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

taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.c (6673B)


      1 /*
      2   This file is part of TALER
      3   (C) 2022, 2024 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU Affero General Public License as
      7   published by the Free Software Foundation; either version 3,
      8   or (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but
     11   WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU General Public License for more details.
     14 
     15   You should have received a copy of the GNU General Public
     16   License along with TALER; see the file COPYING.  If not,
     17   see <http://www.gnu.org/licenses/>
     18 */
     19 
     20 /**
     21  * @file src/backend/taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.c
     22  * @brief implementing PATCH /templates/$ID request handling
     23  * @author Priscilla HUANG
     24  */
     25 #include "platform.h"
     26 #include "taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.h"
     27 #include "taler-merchant-httpd_helper.h"
     28 #include <taler/taler_json_lib.h>
     29 #include "merchant-database/get_otp_device_serial.h"
     30 #include "merchant-database/update_template.h"
     31 
     32 
     33 /**
     34  * PATCH configuration of an existing instance, given its configuration.
     35  *
     36  * @param rh context of the handler
     37  * @param connection the MHD connection to handle
     38  * @param[in,out] hc context with further information about the request
     39  * @return MHD result code
     40  */
     41 enum MHD_Result
     42 TMH_private_patch_templates_ID (const struct TMH_RequestHandler *rh,
     43                                 struct MHD_Connection *connection,
     44                                 struct TMH_HandlerContext *hc)
     45 {
     46   struct TMH_MerchantInstance *mi = hc->instance;
     47   const char *template_id = hc->infix;
     48   struct TALER_MERCHANTDB_TemplateDetails tp = {0};
     49   enum GNUNET_DB_QueryStatus qs;
     50   struct GNUNET_JSON_Specification spec[] = {
     51     GNUNET_JSON_spec_string ("template_description",
     52                              (const char **) &tp.template_description),
     53     GNUNET_JSON_spec_mark_optional (
     54       TALER_JSON_spec_slug ("otp_id",
     55                             (const char **) &tp.otp_id),
     56       NULL),
     57     GNUNET_JSON_spec_object_copy ("template_contract",
     58                                   &tp.template_contract),
     59     GNUNET_JSON_spec_mark_optional (
     60       GNUNET_JSON_spec_object_copy ("editable_defaults",
     61                                     &tp.editable_defaults),
     62       NULL),
     63     GNUNET_JSON_spec_end ()
     64   };
     65 
     66   GNUNET_assert (NULL != mi);
     67   GNUNET_assert (NULL != template_id);
     68   {
     69     enum GNUNET_GenericReturnValue res;
     70 
     71     res = TALER_MHD_parse_json_data (connection,
     72                                      hc->request_body,
     73                                      spec);
     74     if (GNUNET_OK != res)
     75       return (GNUNET_NO == res)
     76              ? MHD_YES
     77              : MHD_NO;
     78   }
     79   if (! TALER_MERCHANT_template_contract_valid (tp.template_contract))
     80   {
     81     GNUNET_break_op (0);
     82     GNUNET_JSON_parse_free (spec);
     83     return TALER_MHD_reply_with_error (connection,
     84                                        MHD_HTTP_BAD_REQUEST,
     85                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     86                                        "template_contract");
     87   }
     88   if (NULL != tp.editable_defaults)
     89   {
     90     const char *key;
     91     json_t *val;
     92 
     93     json_object_foreach (tp.editable_defaults, key, val)
     94     {
     95       if (NULL !=
     96           json_object_get (tp.template_contract,
     97                            key))
     98       {
     99         char *msg;
    100         enum MHD_Result ret;
    101 
    102         GNUNET_break_op (0);
    103         GNUNET_asprintf (&msg,
    104                          "editable_defaults::%s conflicts with template_contract",
    105                          key);
    106         GNUNET_JSON_parse_free (spec);
    107         ret = TALER_MHD_reply_with_error (
    108           connection,
    109           MHD_HTTP_BAD_REQUEST,
    110           TALER_EC_GENERIC_PARAMETER_MALFORMED,
    111           msg);
    112         GNUNET_free (msg);
    113         return ret;
    114       }
    115     }
    116   }
    117 
    118   if (NULL != tp.otp_id)
    119   {
    120     uint64_t otp_serial;
    121 
    122     /* Note: without this pre-check, an unknown @e otp_id would
    123        simply resolve to NULL in the UPDATE and thus *silently*
    124        remove the OTP device binding of the template. */
    125     qs = TALER_MERCHANTDB_get_otp_device_serial (TMH_db,
    126                                                  mi->settings.id,
    127                                                  tp.otp_id,
    128                                                  &otp_serial);
    129     switch (qs)
    130     {
    131     case GNUNET_DB_STATUS_HARD_ERROR:
    132     case GNUNET_DB_STATUS_SOFT_ERROR:
    133       GNUNET_break (0);
    134       GNUNET_JSON_parse_free (spec);
    135       return TALER_MHD_reply_with_error (connection,
    136                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
    137                                          TALER_EC_GENERIC_DB_FETCH_FAILED,
    138                                          "get_otp_device_serial");
    139     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    140       GNUNET_JSON_parse_free (spec);
    141       return TALER_MHD_reply_with_error (connection,
    142                                          MHD_HTTP_NOT_FOUND,
    143                                          TALER_EC_MERCHANT_GENERIC_OTP_DEVICE_UNKNOWN,
    144                                          tp.otp_id);
    145     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    146       break;
    147     }
    148   }
    149 
    150   qs = TALER_MERCHANTDB_update_template (TMH_db,
    151                                          mi->settings.id,
    152                                          template_id,
    153                                          &tp);
    154   {
    155     enum MHD_Result ret = MHD_NO;
    156 
    157     switch (qs)
    158     {
    159     case GNUNET_DB_STATUS_HARD_ERROR:
    160       GNUNET_break (0);
    161       ret = TALER_MHD_reply_with_error (
    162         connection,
    163         MHD_HTTP_INTERNAL_SERVER_ERROR,
    164         TALER_EC_GENERIC_DB_STORE_FAILED,
    165         NULL);
    166       break;
    167     case GNUNET_DB_STATUS_SOFT_ERROR:
    168       GNUNET_break (0);
    169       ret = TALER_MHD_reply_with_error (
    170         connection,
    171         MHD_HTTP_INTERNAL_SERVER_ERROR,
    172         TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
    173         "unexpected serialization problem");
    174       break;
    175     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    176       ret = TALER_MHD_reply_with_error (
    177         connection,
    178         MHD_HTTP_NOT_FOUND,
    179         TALER_EC_MERCHANT_GENERIC_TEMPLATE_UNKNOWN,
    180         template_id);
    181       break;
    182     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    183       ret = TALER_MHD_reply_static (connection,
    184                                     MHD_HTTP_NO_CONTENT,
    185                                     NULL,
    186                                     NULL,
    187                                     0);
    188       break;
    189     }
    190     GNUNET_JSON_parse_free (spec);
    191     return ret;
    192   }
    193 }
    194 
    195 
    196 /* end of taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.c */