merchant

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

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


      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_json ("template_contract",
     58                            &tp.template_contract),
     59     GNUNET_JSON_spec_mark_optional (
     60       GNUNET_JSON_spec_json ("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 
     80   if (! TALER_MERCHANT_template_contract_valid (tp.template_contract))
     81   {
     82     GNUNET_break_op (0);
     83     GNUNET_JSON_parse_free (spec);
     84     return TALER_MHD_reply_with_error (connection,
     85                                        MHD_HTTP_BAD_REQUEST,
     86                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     87                                        "template_contract");
     88   }
     89   if (NULL != tp.editable_defaults)
     90   {
     91     const char *key;
     92     json_t *val;
     93 
     94     json_object_foreach (tp.editable_defaults, key, val)
     95     {
     96       if (NULL !=
     97           json_object_get (tp.template_contract,
     98                            key))
     99       {
    100         char *msg;
    101         enum MHD_Result ret;
    102 
    103         GNUNET_break_op (0);
    104         GNUNET_asprintf (&msg,
    105                          "editable_defaults::%s conflicts with template_contract",
    106                          key);
    107         GNUNET_JSON_parse_free (spec);
    108         ret = TALER_MHD_reply_with_error (
    109           connection,
    110           MHD_HTTP_BAD_REQUEST,
    111           TALER_EC_GENERIC_PARAMETER_MALFORMED,
    112           msg);
    113         GNUNET_free (msg);
    114         return ret;
    115       }
    116     }
    117   }
    118 
    119   if (NULL != tp.otp_id)
    120   {
    121     uint64_t otp_serial;
    122 
    123     /* Note: without this pre-check, an unknown @e otp_id would
    124        simply resolve to NULL in the UPDATE and thus *silently*
    125        remove the OTP device binding of the template. */
    126     qs = TALER_MERCHANTDB_get_otp_device_serial (TMH_db,
    127                                                  mi->settings.id,
    128                                                  tp.otp_id,
    129                                                  &otp_serial);
    130     switch (qs)
    131     {
    132     case GNUNET_DB_STATUS_HARD_ERROR:
    133     case GNUNET_DB_STATUS_SOFT_ERROR:
    134       GNUNET_break (0);
    135       GNUNET_JSON_parse_free (spec);
    136       return TALER_MHD_reply_with_error (connection,
    137                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
    138                                          TALER_EC_GENERIC_DB_FETCH_FAILED,
    139                                          "get_otp_device_serial");
    140     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    141       GNUNET_JSON_parse_free (spec);
    142       return TALER_MHD_reply_with_error (connection,
    143                                          MHD_HTTP_NOT_FOUND,
    144                                          TALER_EC_MERCHANT_GENERIC_OTP_DEVICE_UNKNOWN,
    145                                          tp.otp_id);
    146     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    147       break;
    148     }
    149   }
    150 
    151   qs = TALER_MERCHANTDB_update_template (TMH_db,
    152                                          mi->settings.id,
    153                                          template_id,
    154                                          &tp);
    155   {
    156     enum MHD_Result ret = MHD_NO;
    157 
    158     switch (qs)
    159     {
    160     case GNUNET_DB_STATUS_HARD_ERROR:
    161       GNUNET_break (0);
    162       ret = TALER_MHD_reply_with_error (
    163         connection,
    164         MHD_HTTP_INTERNAL_SERVER_ERROR,
    165         TALER_EC_GENERIC_DB_STORE_FAILED,
    166         NULL);
    167       break;
    168     case GNUNET_DB_STATUS_SOFT_ERROR:
    169       GNUNET_break (0);
    170       ret = TALER_MHD_reply_with_error (
    171         connection,
    172         MHD_HTTP_INTERNAL_SERVER_ERROR,
    173         TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
    174         "unexpected serialization problem");
    175       break;
    176     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    177       ret = TALER_MHD_reply_with_error (
    178         connection,
    179         MHD_HTTP_NOT_FOUND,
    180         TALER_EC_MERCHANT_GENERIC_TEMPLATE_UNKNOWN,
    181         template_id);
    182       break;
    183     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    184       ret = TALER_MHD_reply_static (connection,
    185                                     MHD_HTTP_NO_CONTENT,
    186                                     NULL,
    187                                     NULL,
    188                                     0);
    189       break;
    190     }
    191     GNUNET_JSON_parse_free (spec);
    192     return ret;
    193   }
    194 }
    195 
    196 
    197 /* end of taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.c */