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