merchant

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

taler-merchant-httpd_private-patch-templates-ID.c (7584B)


      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 taler-merchant-httpd_private-patch-templates-ID.c
     22  * @brief implementing PATCH /templates/$ID request handling
     23  * @author Priscilla HUANG
     24  */
     25 #include "platform.h"
     26 #include "taler-merchant-httpd_private-patch-templates-ID.h"
     27 #include "taler-merchant-httpd_helper.h"
     28 #include <taler/taler_json_lib.h>
     29 
     30 
     31 /**
     32  * Determine the cause of the PATCH failure in more detail and report.
     33  *
     34  * @param connection connection to report on
     35  * @param instance_id instance we are processing
     36  * @param template_id ID of the product to patch
     37  * @param tp template details we failed to set
     38  */
     39 static MHD_RESULT
     40 determine_cause (struct MHD_Connection *connection,
     41                  const char *instance_id,
     42                  const char *template_id,
     43                  const struct TALER_MERCHANTDB_TemplateDetails *tp)
     44 {
     45   struct TALER_MERCHANTDB_TemplateDetails tpx;
     46   enum GNUNET_DB_QueryStatus qs;
     47 
     48   qs = TMH_db->lookup_template (TMH_db->cls,
     49                                 instance_id,
     50                                 template_id,
     51                                 &tpx);
     52   switch (qs)
     53   {
     54   case GNUNET_DB_STATUS_HARD_ERROR:
     55     GNUNET_break (0);
     56     return TALER_MHD_reply_with_error (connection,
     57                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
     58                                        TALER_EC_GENERIC_DB_FETCH_FAILED,
     59                                        NULL);
     60   case GNUNET_DB_STATUS_SOFT_ERROR:
     61     GNUNET_break (0);
     62     return TALER_MHD_reply_with_error (connection,
     63                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
     64                                        TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
     65                                        "unexpected serialization problem");
     66   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     67     return TALER_MHD_reply_with_error (connection,
     68                                        MHD_HTTP_NOT_FOUND,
     69                                        TALER_EC_MERCHANT_GENERIC_TEMPLATE_UNKNOWN,
     70                                        template_id);
     71   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     72     break; /* do below */
     73   }
     74 
     75   {
     76     enum TALER_ErrorCode ec;
     77 
     78     ec = TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
     79     TALER_MERCHANTDB_template_details_free (&tpx);
     80     GNUNET_break (TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE != ec);
     81     return TALER_MHD_reply_with_error (connection,
     82                                        MHD_HTTP_CONFLICT,
     83                                        ec,
     84                                        NULL);
     85   }
     86 }
     87 
     88 
     89 /**
     90  * PATCH configuration of an existing instance, given its configuration.
     91  *
     92  * @param rh context of the handler
     93  * @param connection the MHD connection to handle
     94  * @param[in,out] hc context with further information about the request
     95  * @return MHD result code
     96  */
     97 MHD_RESULT
     98 TMH_private_patch_templates_ID (const struct TMH_RequestHandler *rh,
     99                                 struct MHD_Connection *connection,
    100                                 struct TMH_HandlerContext *hc)
    101 {
    102   struct TMH_MerchantInstance *mi = hc->instance;
    103   const char *template_id = hc->infix;
    104   struct TALER_MERCHANTDB_TemplateDetails tp = {0};
    105   enum GNUNET_DB_QueryStatus qs;
    106   struct GNUNET_JSON_Specification spec[] = {
    107     GNUNET_JSON_spec_string ("template_description",
    108                              (const char **) &tp.template_description),
    109     GNUNET_JSON_spec_mark_optional (
    110       GNUNET_JSON_spec_string ("otp_id",
    111                                (const char **) &tp.otp_id),
    112       NULL),
    113     GNUNET_JSON_spec_json ("template_contract",
    114                            &tp.template_contract),
    115     GNUNET_JSON_spec_mark_optional (
    116       GNUNET_JSON_spec_json ("editable_defaults",
    117                              &tp.editable_defaults),
    118       NULL),
    119     GNUNET_JSON_spec_end ()
    120   };
    121 
    122   GNUNET_assert (NULL != mi);
    123   GNUNET_assert (NULL != template_id);
    124   {
    125     enum GNUNET_GenericReturnValue res;
    126 
    127     res = TALER_MHD_parse_json_data (connection,
    128                                      hc->request_body,
    129                                      spec);
    130     if (GNUNET_OK != res)
    131       return (GNUNET_NO == res)
    132              ? MHD_YES
    133              : MHD_NO;
    134   }
    135 
    136   if (! TMH_template_contract_valid (tp.template_contract))
    137   {
    138     GNUNET_break_op (0);
    139     GNUNET_JSON_parse_free (spec);
    140     return TALER_MHD_reply_with_error (connection,
    141                                        MHD_HTTP_BAD_REQUEST,
    142                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
    143                                        "template_contract");
    144   }
    145   if (NULL != tp.editable_defaults)
    146   {
    147     const char *key;
    148     json_t *val;
    149 
    150     json_object_foreach (tp.editable_defaults, key, val)
    151     {
    152       if (NULL !=
    153           json_object_get (tp.template_contract,
    154                            key))
    155       {
    156         char *msg;
    157         MHD_RESULT ret;
    158 
    159         GNUNET_break_op (0);
    160         GNUNET_asprintf (&msg,
    161                          "editable_defaults::%s conflicts with template_contract",
    162                          key);
    163         GNUNET_JSON_parse_free (spec);
    164         ret = TALER_MHD_reply_with_error (connection,
    165                                           MHD_HTTP_BAD_REQUEST,
    166                                           TALER_EC_GENERIC_PARAMETER_MALFORMED,
    167                                           msg);
    168         GNUNET_free (msg);
    169         return ret;
    170       }
    171     }
    172   }
    173 
    174   qs = TMH_db->update_template (TMH_db->cls,
    175                                 mi->settings.id,
    176                                 template_id,
    177                                 &tp);
    178   {
    179     MHD_RESULT ret = MHD_NO;
    180 
    181     switch (qs)
    182     {
    183     case GNUNET_DB_STATUS_HARD_ERROR:
    184       GNUNET_break (0);
    185       ret = TALER_MHD_reply_with_error (connection,
    186                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
    187                                         TALER_EC_GENERIC_DB_STORE_FAILED,
    188                                         NULL);
    189       break;
    190     case GNUNET_DB_STATUS_SOFT_ERROR:
    191       GNUNET_break (0);
    192       ret = TALER_MHD_reply_with_error (connection,
    193                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
    194                                         TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
    195                                         "unexpected serialization problem");
    196       break;
    197     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    198       ret = determine_cause (connection,
    199                              mi->settings.id,
    200                              template_id,
    201                              &tp);
    202       break;
    203     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    204       ret = TALER_MHD_reply_static (connection,
    205                                     MHD_HTTP_NO_CONTENT,
    206                                     NULL,
    207                                     NULL,
    208                                     0);
    209       break;
    210     }
    211     GNUNET_JSON_parse_free (spec);
    212     return ret;
    213   }
    214 }
    215 
    216 
    217 /* end of taler-merchant-httpd_private-patch-templates-ID.c */