merchant

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

taler-merchant-httpd_private-patch-units-ID.c (8272B)


      1 /*
      2   This file is part of TALER
      3   (C) 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 taler-merchant-httpd_private-patch-units-ID.c
     18  * @brief implement PATCH /private/units/$UNIT
     19  * @author Bohdan Potuzhnyi
     20  */
     21 #include "platform.h"
     22 #include "taler-merchant-httpd_private-patch-units-ID.h"
     23 #include "taler-merchant-httpd_helper.h"
     24 #include <taler/taler_json_lib.h>
     25 
     26 #define TMH_MAX_UNIT_PRECISION_LEVEL 6
     27 
     28 
     29 MHD_RESULT
     30 TMH_private_patch_units_ID (const struct TMH_RequestHandler *rh,
     31                             struct MHD_Connection *connection,
     32                             struct TMH_HandlerContext *hc)
     33 {
     34   struct TMH_MerchantInstance *mi = hc->instance;
     35   const char *unit_id = hc->infix;
     36   struct TALER_MERCHANTDB_UnitDetails nud = { 0 };
     37   bool unit_allow_fraction_missing = true;
     38   bool unit_precision_missing = true;
     39   bool unit_active_missing = true;
     40   struct GNUNET_JSON_Specification spec[] = {
     41     GNUNET_JSON_spec_mark_optional (
     42       GNUNET_JSON_spec_string ("unit_name_long",
     43                                (const char **) &nud.unit_name_long),
     44       NULL),
     45     GNUNET_JSON_spec_mark_optional (
     46       GNUNET_JSON_spec_json ("unit_name_long_i18n",
     47                              &nud.unit_name_long_i18n),
     48       NULL),
     49     GNUNET_JSON_spec_mark_optional (
     50       GNUNET_JSON_spec_string ("unit_name_short",
     51                                (const char **) &nud.unit_name_short),
     52       NULL),
     53     GNUNET_JSON_spec_mark_optional (
     54       GNUNET_JSON_spec_json ("unit_name_short_i18n",
     55                              &nud.unit_name_short_i18n),
     56       NULL),
     57     GNUNET_JSON_spec_mark_optional (
     58       GNUNET_JSON_spec_bool ("unit_allow_fraction",
     59                              &nud.unit_allow_fraction),
     60       &unit_allow_fraction_missing),
     61     GNUNET_JSON_spec_mark_optional (
     62       GNUNET_JSON_spec_uint32 ("unit_precision_level",
     63                                &nud.unit_precision_level),
     64       &unit_precision_missing),
     65     GNUNET_JSON_spec_mark_optional (
     66       GNUNET_JSON_spec_bool ("unit_active",
     67                              &nud.unit_active),
     68       &unit_active_missing),
     69     GNUNET_JSON_spec_end ()
     70   };
     71   enum GNUNET_GenericReturnValue res;
     72   const bool *unit_allow_fraction_ptr = NULL;
     73   const uint32_t *unit_precision_ptr = NULL;
     74   const bool *unit_active_ptr = NULL;
     75   enum GNUNET_DB_QueryStatus qs;
     76   bool no_instance = false;
     77   bool no_unit = false;
     78   bool builtin_conflict = false;
     79   MHD_RESULT ret = MHD_YES;
     80 
     81   (void) rh;
     82   GNUNET_assert (NULL != mi);
     83   GNUNET_assert (NULL != unit_id);
     84 
     85   res = TALER_MHD_parse_json_data (connection,
     86                                    hc->request_body,
     87                                    spec);
     88   if (GNUNET_OK != res)
     89     return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
     90 
     91   if (NULL == nud.unit_name_long &&
     92       NULL == nud.unit_name_long_i18n &&
     93       NULL == nud.unit_name_short &&
     94       NULL == nud.unit_name_short_i18n &&
     95       unit_allow_fraction_missing &&
     96       unit_precision_missing &&
     97       unit_active_missing)
     98   {
     99     ret = TALER_MHD_reply_static (connection,
    100                                   MHD_HTTP_NO_CONTENT,
    101                                   NULL,
    102                                   NULL,
    103                                   0);
    104     goto cleanup;
    105   }
    106 
    107   if (! unit_precision_missing)
    108   {
    109     if (nud.unit_precision_level > TMH_MAX_UNIT_PRECISION_LEVEL)
    110     {
    111       GNUNET_break_op (0);
    112       ret = TALER_MHD_reply_with_error (connection,
    113                                         MHD_HTTP_BAD_REQUEST,
    114                                         TALER_EC_GENERIC_PARAMETER_MALFORMED,
    115                                         "unit_precision_level");
    116       goto cleanup;
    117     }
    118     unit_precision_ptr = &nud.unit_precision_level;
    119   }
    120 
    121   if (! unit_allow_fraction_missing)
    122   {
    123     unit_allow_fraction_ptr = &nud.unit_allow_fraction;
    124     if (! nud.unit_allow_fraction)
    125     {
    126       nud.unit_precision_level = 0;
    127       unit_precision_missing = false;
    128       unit_precision_ptr = &nud.unit_precision_level;
    129     }
    130   }
    131 
    132   if (! unit_active_missing)
    133     unit_active_ptr = &nud.unit_active;
    134 
    135   if (NULL != nud.unit_name_long_i18n)
    136   {
    137     if (! TALER_JSON_check_i18n (nud.unit_name_long_i18n))
    138     {
    139       GNUNET_break_op (0);
    140       ret = TALER_MHD_reply_with_error (connection,
    141                                         MHD_HTTP_BAD_REQUEST,
    142                                         TALER_EC_GENERIC_PARAMETER_MALFORMED,
    143                                         "unit_name_long_i18n");
    144       goto cleanup;
    145     }
    146   }
    147 
    148   if (NULL != nud.unit_name_short_i18n)
    149   {
    150     if (! TALER_JSON_check_i18n (nud.unit_name_short_i18n))
    151     {
    152       GNUNET_break_op (0);
    153       ret = TALER_MHD_reply_with_error (connection,
    154                                         MHD_HTTP_BAD_REQUEST,
    155                                         TALER_EC_GENERIC_PARAMETER_MALFORMED,
    156                                         "unit_name_short_i18n");
    157       goto cleanup;
    158     }
    159   }
    160 
    161   qs = TMH_db->update_unit (TMH_db->cls,
    162                             mi->settings.id,
    163                             unit_id,
    164                             nud.unit_name_long,
    165                             nud.unit_name_long_i18n,
    166                             nud.unit_name_short,
    167                             nud.unit_name_short_i18n,
    168                             unit_allow_fraction_ptr,
    169                             unit_precision_ptr,
    170                             unit_active_ptr,
    171                             &no_instance,
    172                             &no_unit,
    173                             &builtin_conflict);
    174   switch (qs)
    175   {
    176   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    177     break;
    178   case GNUNET_DB_STATUS_SOFT_ERROR:
    179     GNUNET_break (0);
    180     ret = TALER_MHD_reply_with_error (connection,
    181                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
    182                                       TALER_EC_GENERIC_DB_SOFT_FAILURE,
    183                                       "update_unit");
    184     goto cleanup;
    185   case GNUNET_DB_STATUS_HARD_ERROR:
    186   default:
    187     GNUNET_break (0);
    188     ret = TALER_MHD_reply_with_error (connection,
    189                                       MHD_HTTP_INTERNAL_SERVER_ERROR,
    190                                       TALER_EC_GENERIC_DB_STORE_FAILED,
    191                                       "update_unit");
    192     goto cleanup;
    193   }
    194 
    195   if (no_instance)
    196   {
    197     ret = TALER_MHD_reply_with_error (connection,
    198                                       MHD_HTTP_NOT_FOUND,
    199                                       TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN,
    200                                       mi->settings.id);
    201     goto cleanup;
    202   }
    203   if (no_unit)
    204   {
    205     ret = TALER_MHD_reply_with_error (connection,
    206                                       MHD_HTTP_NOT_FOUND,
    207                                       TALER_EC_MERCHANT_GENERIC_UNIT_UNKNOWN,
    208                                       unit_id);
    209     goto cleanup;
    210   }
    211   if (builtin_conflict)
    212   {
    213     ret = TALER_MHD_reply_with_error (connection,
    214                                       MHD_HTTP_CONFLICT,
    215                                       TALER_EC_MERCHANT_GENERIC_UNIT_BUILTIN,
    216                                       unit_id);
    217     goto cleanup;
    218   }
    219 
    220   ret = TALER_MHD_reply_static (connection,
    221                                 MHD_HTTP_NO_CONTENT,
    222                                 NULL,
    223                                 NULL,
    224                                 0);
    225 
    226 cleanup:
    227   if (NULL != nud.unit_name_long_i18n)
    228   {
    229     json_decref (nud.unit_name_long_i18n);
    230     nud.unit_name_long_i18n = NULL;
    231   }
    232   if (NULL != nud.unit_name_short_i18n)
    233   {
    234     json_decref (nud.unit_name_short_i18n);
    235     nud.unit_name_short_i18n = NULL;
    236   }
    237   GNUNET_JSON_parse_free (spec);
    238   return ret;
    239 }
    240 
    241 
    242 /* end of taler-merchant-httpd_private-patch-units-ID.c */