taler-merchant-httpd_patch-private-tokenfamilies-TOKEN_FAMILY_SLUG.c (5908B)
1 /* 2 This file is part of TALER 3 (C) 2023, 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-tokenfamilies-TOKEN_FAMILY_SLUG.c 22 * @brief implementing PATCH /tokenfamilies/$SLUG request handling 23 * @author Christian Blättler 24 */ 25 #include "platform.h" 26 #include "taler-merchant-httpd_patch-private-tokenfamilies-TOKEN_FAMILY_SLUG.h" 27 #include "taler-merchant-httpd_helper.h" 28 #include <taler/taler_json_lib.h> 29 #include "merchant-database/update_token_family.h" 30 31 32 /** 33 * How often do we retry the simple INSERT database transaction? 34 */ 35 #define MAX_RETRIES 3 36 37 38 /** 39 * Handle a PATCH "/tokenfamilies/$slug" request. 40 * 41 * @param rh context of the handler 42 * @param connection the MHD connection to handle 43 * @param[in,out] hc context with further information about the request 44 * @return MHD result code 45 */ 46 enum MHD_Result 47 TMH_private_patch_token_family_SLUG (const struct TMH_RequestHandler *rh, 48 struct MHD_Connection *connection, 49 struct TMH_HandlerContext *hc) 50 { 51 struct TMH_MerchantInstance *mi = hc->instance; 52 const char *slug = hc->infix; 53 struct TALER_MERCHANTDB_TokenFamilyDetails details = { 54 .valid_before = GNUNET_TIME_UNIT_FOREVER_TS 55 }; 56 struct GNUNET_JSON_Specification spec[] = { 57 GNUNET_JSON_spec_string ("name", 58 (const char **) &details.name), 59 GNUNET_JSON_spec_string ("description", 60 (const char **) &details.description), 61 GNUNET_JSON_spec_mark_optional ( 62 GNUNET_JSON_spec_json ("description_i18n", 63 &details.description_i18n), 64 NULL), 65 GNUNET_JSON_spec_mark_optional ( 66 GNUNET_JSON_spec_json ("extra_data", 67 &details.extra_data), 68 NULL), 69 GNUNET_JSON_spec_timestamp ("valid_after", 70 &details.valid_after), 71 GNUNET_JSON_spec_mark_optional ( 72 GNUNET_JSON_spec_timestamp ("valid_before", 73 &details.valid_before), 74 NULL), 75 GNUNET_JSON_spec_end () 76 }; 77 78 GNUNET_assert (NULL != mi); 79 GNUNET_assert (NULL != slug); 80 { 81 enum GNUNET_GenericReturnValue res; 82 83 res = TALER_MHD_parse_json_data (connection, 84 hc->request_body, 85 spec); 86 if (GNUNET_OK != res) 87 return (GNUNET_NO == res) 88 ? MHD_YES 89 : MHD_NO; 90 } 91 92 /* Ensure that valid_after is before valid_before */ 93 if (GNUNET_TIME_timestamp_cmp (details.valid_after, 94 >=, 95 details.valid_before)) 96 { 97 GNUNET_break_op (0); 98 GNUNET_JSON_parse_free (spec); 99 return TALER_MHD_reply_with_error (connection, 100 MHD_HTTP_BAD_REQUEST, 101 TALER_EC_GENERIC_PARAMETER_MALFORMED, 102 "valid_after >= valid_before"); 103 } 104 105 if (NULL == details.description_i18n) 106 { 107 details.description_i18n = json_object (); 108 GNUNET_assert (NULL != details.description_i18n); 109 } 110 if (! TALER_JSON_check_i18n (details.description_i18n)) 111 { 112 GNUNET_break_op (0); 113 GNUNET_JSON_parse_free (spec); 114 return TALER_MHD_reply_with_error (connection, 115 MHD_HTTP_BAD_REQUEST, 116 TALER_EC_GENERIC_PARAMETER_MALFORMED, 117 "description_i18n"); 118 } 119 120 { 121 enum GNUNET_DB_QueryStatus qs; 122 enum MHD_Result ret = MHD_NO; 123 124 qs = TALER_MERCHANTDB_update_token_family (TMH_db, 125 mi->settings.id, 126 slug, 127 &details); 128 switch (qs) 129 { 130 case GNUNET_DB_STATUS_HARD_ERROR: 131 GNUNET_break (0); 132 ret = TALER_MHD_reply_with_error (connection, 133 MHD_HTTP_INTERNAL_SERVER_ERROR, 134 TALER_EC_GENERIC_DB_STORE_FAILED, 135 NULL); 136 break; 137 case GNUNET_DB_STATUS_SOFT_ERROR: 138 GNUNET_break (0); 139 ret = TALER_MHD_reply_with_error (connection, 140 MHD_HTTP_INTERNAL_SERVER_ERROR, 141 TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, 142 "unexpected serialization problem"); 143 break; 144 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: 145 ret = TALER_MHD_reply_with_error (connection, 146 MHD_HTTP_NOT_FOUND, 147 TALER_EC_MERCHANT_PATCH_TOKEN_FAMILY_NOT_FOUND, 148 slug); 149 break; 150 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: 151 ret = TALER_MHD_reply_static (connection, 152 MHD_HTTP_NO_CONTENT, 153 NULL, 154 NULL, 155 0); 156 break; 157 } 158 GNUNET_JSON_parse_free (spec); 159 return ret; 160 } 161 } 162 163 164 /* end of taler-merchant-httpd_patch-private-tokenfamilies-TOKEN_FAMILY_SLUG.c */