taler-merchant-httpd_patch-private-units-UNIT.c (8085B)
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 src/backend/taler-merchant-httpd_patch-private-units-UNIT.c 18 * @brief implement PATCH /private/units/$UNIT 19 * @author Bohdan Potuzhnyi 20 */ 21 #include "platform.h" 22 #include "taler-merchant-httpd_patch-private-units-UNIT.h" 23 #include "taler-merchant-httpd_helper.h" 24 #include <taler/taler_json_lib.h> 25 #include "merchant-database/update_unit.h" 26 27 #define TMH_MAX_UNIT_PRECISION_LEVEL 6 28 29 30 enum MHD_Result 31 TMH_private_patch_units_ID (const struct TMH_RequestHandler *rh, 32 struct MHD_Connection *connection, 33 struct TMH_HandlerContext *hc) 34 { 35 struct TMH_MerchantInstance *mi = hc->instance; 36 const char *unit_id = hc->infix; 37 struct TALER_MERCHANTDB_UnitDetails nud = { 0 }; 38 bool unit_allow_fraction_missing = true; 39 bool unit_precision_missing = true; 40 bool unit_active_missing = true; 41 struct GNUNET_JSON_Specification spec[] = { 42 GNUNET_JSON_spec_mark_optional ( 43 GNUNET_JSON_spec_string ("unit_name_long", 44 (const char **) &nud.unit_name_long), 45 NULL), 46 GNUNET_JSON_spec_mark_optional ( 47 GNUNET_JSON_spec_json ("unit_name_long_i18n", 48 &nud.unit_name_long_i18n), 49 NULL), 50 GNUNET_JSON_spec_mark_optional ( 51 GNUNET_JSON_spec_string ("unit_name_short", 52 (const char **) &nud.unit_name_short), 53 NULL), 54 GNUNET_JSON_spec_mark_optional ( 55 GNUNET_JSON_spec_json ("unit_name_short_i18n", 56 &nud.unit_name_short_i18n), 57 NULL), 58 GNUNET_JSON_spec_mark_optional ( 59 GNUNET_JSON_spec_bool ("unit_allow_fraction", 60 &nud.unit_allow_fraction), 61 &unit_allow_fraction_missing), 62 GNUNET_JSON_spec_mark_optional ( 63 GNUNET_JSON_spec_uint32 ("unit_precision_level", 64 &nud.unit_precision_level), 65 &unit_precision_missing), 66 GNUNET_JSON_spec_mark_optional ( 67 GNUNET_JSON_spec_bool ("unit_active", 68 &nud.unit_active), 69 &unit_active_missing), 70 GNUNET_JSON_spec_end () 71 }; 72 enum GNUNET_GenericReturnValue res; 73 const bool *unit_allow_fraction_ptr = NULL; 74 const uint32_t *unit_precision_ptr = NULL; 75 const bool *unit_active_ptr = NULL; 76 enum GNUNET_DB_QueryStatus qs; 77 bool no_unit = false; 78 bool builtin_conflict = false; 79 enum 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 = TALER_MERCHANTDB_update_unit (TMH_db, 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_unit, 172 &builtin_conflict); 173 switch (qs) 174 { 175 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: 176 break; 177 case GNUNET_DB_STATUS_SOFT_ERROR: 178 GNUNET_break (0); 179 ret = TALER_MHD_reply_with_error (connection, 180 MHD_HTTP_INTERNAL_SERVER_ERROR, 181 TALER_EC_GENERIC_DB_SOFT_FAILURE, 182 "update_unit"); 183 goto cleanup; 184 case GNUNET_DB_STATUS_HARD_ERROR: 185 default: 186 GNUNET_break (0); 187 ret = TALER_MHD_reply_with_error (connection, 188 MHD_HTTP_INTERNAL_SERVER_ERROR, 189 TALER_EC_GENERIC_DB_STORE_FAILED, 190 "update_unit"); 191 goto cleanup; 192 } 193 194 if (no_unit) 195 { 196 ret = TALER_MHD_reply_with_error (connection, 197 MHD_HTTP_NOT_FOUND, 198 TALER_EC_MERCHANT_GENERIC_UNIT_UNKNOWN, 199 unit_id); 200 goto cleanup; 201 } 202 if (builtin_conflict) 203 { 204 ret = TALER_MHD_reply_with_error (connection, 205 MHD_HTTP_CONFLICT, 206 TALER_EC_MERCHANT_GENERIC_UNIT_BUILTIN, 207 unit_id); 208 goto cleanup; 209 } 210 211 ret = TALER_MHD_reply_static (connection, 212 MHD_HTTP_NO_CONTENT, 213 NULL, 214 NULL, 215 0); 216 217 cleanup: 218 if (NULL != nud.unit_name_long_i18n) 219 { 220 json_decref (nud.unit_name_long_i18n); 221 nud.unit_name_long_i18n = NULL; 222 } 223 if (NULL != nud.unit_name_short_i18n) 224 { 225 json_decref (nud.unit_name_short_i18n); 226 nud.unit_name_short_i18n = NULL; 227 } 228 GNUNET_JSON_parse_free (spec); 229 return ret; 230 } 231 232 233 /* end of taler-merchant-httpd_patch-private-units-UNIT.c */