LCOV - code coverage report
Current view: top level - backend - taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 67.2 % 64 43
Test Date: 2026-09-04 23:42:01 Functions: 100.0 % 1 1

            Line data    Source code
       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           10 : TMH_private_patch_templates_ID (const struct TMH_RequestHandler *rh,
      43              :                                 struct MHD_Connection *connection,
      44              :                                 struct TMH_HandlerContext *hc)
      45              : {
      46           10 :   struct TMH_MerchantInstance *mi = hc->instance;
      47           10 :   const char *template_id = hc->infix;
      48           10 :   struct TALER_MERCHANTDB_TemplateDetails tp = {0};
      49              :   enum GNUNET_DB_QueryStatus qs;
      50              :   struct GNUNET_JSON_Specification spec[] = {
      51           10 :     GNUNET_JSON_spec_string ("template_description",
      52              :                              (const char **) &tp.template_description),
      53           10 :     GNUNET_JSON_spec_mark_optional (
      54              :       TALER_JSON_spec_slug ("otp_id",
      55              :                             (const char **) &tp.otp_id),
      56              :       NULL),
      57           10 :     GNUNET_JSON_spec_json ("template_contract",
      58              :                            &tp.template_contract),
      59           10 :     GNUNET_JSON_spec_mark_optional (
      60              :       GNUNET_JSON_spec_json ("editable_defaults",
      61              :                              &tp.editable_defaults),
      62              :       NULL),
      63           10 :     GNUNET_JSON_spec_end ()
      64              :   };
      65              : 
      66           10 :   GNUNET_assert (NULL != mi);
      67           10 :   GNUNET_assert (NULL != template_id);
      68              :   {
      69              :     enum GNUNET_GenericReturnValue res;
      70              : 
      71           10 :     res = TALER_MHD_parse_json_data (connection,
      72           10 :                                      hc->request_body,
      73              :                                      spec);
      74           10 :     if (GNUNET_OK != res)
      75              :       return (GNUNET_NO == res)
      76              :              ? MHD_YES
      77            0 :              : MHD_NO;
      78              :   }
      79              : 
      80           10 :   if (! TALER_MERCHANT_template_contract_valid (tp.template_contract))
      81              :   {
      82            2 :     GNUNET_break_op (0);
      83            2 :     GNUNET_JSON_parse_free (spec);
      84            2 :     return TALER_MHD_reply_with_error (connection,
      85              :                                        MHD_HTTP_BAD_REQUEST,
      86              :                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
      87              :                                        "template_contract");
      88              :   }
      89            8 :   if (NULL != tp.editable_defaults)
      90              :   {
      91              :     const char *key;
      92              :     json_t *val;
      93              : 
      94            0 :     json_object_foreach (tp.editable_defaults, key, val)
      95              :     {
      96            0 :       if (NULL !=
      97            0 :           json_object_get (tp.template_contract,
      98              :                            key))
      99              :       {
     100              :         char *msg;
     101              :         enum MHD_Result ret;
     102              : 
     103            0 :         GNUNET_break_op (0);
     104            0 :         GNUNET_asprintf (&msg,
     105              :                          "editable_defaults::%s conflicts with template_contract",
     106              :                          key);
     107            0 :         GNUNET_JSON_parse_free (spec);
     108            0 :         ret = TALER_MHD_reply_with_error (
     109              :           connection,
     110              :           MHD_HTTP_BAD_REQUEST,
     111              :           TALER_EC_GENERIC_PARAMETER_MALFORMED,
     112              :           msg);
     113            0 :         GNUNET_free (msg);
     114            0 :         return ret;
     115              :       }
     116              :     }
     117              :   }
     118              : 
     119            8 :   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            6 :     qs = TALER_MERCHANTDB_get_otp_device_serial (TMH_db,
     127            6 :                                                  mi->settings.id,
     128            6 :                                                  tp.otp_id,
     129              :                                                  &otp_serial);
     130            6 :     switch (qs)
     131              :     {
     132            0 :     case GNUNET_DB_STATUS_HARD_ERROR:
     133              :     case GNUNET_DB_STATUS_SOFT_ERROR:
     134            0 :       GNUNET_break (0);
     135            0 :       GNUNET_JSON_parse_free (spec);
     136            2 :       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            2 :     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     141            2 :       GNUNET_JSON_parse_free (spec);
     142            2 :       return TALER_MHD_reply_with_error (connection,
     143              :                                          MHD_HTTP_NOT_FOUND,
     144              :                                          TALER_EC_MERCHANT_GENERIC_OTP_DEVICE_UNKNOWN,
     145            2 :                                          tp.otp_id);
     146            4 :     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     147            4 :       break;
     148              :     }
     149              :   }
     150              : 
     151            6 :   qs = TALER_MERCHANTDB_update_template (TMH_db,
     152            6 :                                          mi->settings.id,
     153              :                                          template_id,
     154              :                                          &tp);
     155              :   {
     156            6 :     enum MHD_Result ret = MHD_NO;
     157              : 
     158            6 :     switch (qs)
     159              :     {
     160            0 :     case GNUNET_DB_STATUS_HARD_ERROR:
     161            0 :       GNUNET_break (0);
     162            0 :       ret = TALER_MHD_reply_with_error (
     163              :         connection,
     164              :         MHD_HTTP_INTERNAL_SERVER_ERROR,
     165              :         TALER_EC_GENERIC_DB_STORE_FAILED,
     166              :         NULL);
     167            0 :       break;
     168            0 :     case GNUNET_DB_STATUS_SOFT_ERROR:
     169            0 :       GNUNET_break (0);
     170            0 :       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            0 :       break;
     176            2 :     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     177            2 :       ret = TALER_MHD_reply_with_error (
     178              :         connection,
     179              :         MHD_HTTP_NOT_FOUND,
     180              :         TALER_EC_MERCHANT_GENERIC_TEMPLATE_UNKNOWN,
     181              :         template_id);
     182            2 :       break;
     183            4 :     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     184            4 :       ret = TALER_MHD_reply_static (connection,
     185              :                                     MHD_HTTP_NO_CONTENT,
     186              :                                     NULL,
     187              :                                     NULL,
     188              :                                     0);
     189            4 :       break;
     190              :     }
     191            6 :     GNUNET_JSON_parse_free (spec);
     192            6 :     return ret;
     193              :   }
     194              : }
     195              : 
     196              : 
     197              : /* end of taler-merchant-httpd_patch-private-templates-TEMPLATE_ID.c */
        

Generated by: LCOV version 2.0-1