taler-merchant-httpd_patch-private-accounts-H_WIRE.c (7190B)
1 /* 2 This file is part of TALER 3 (C) 2023, 2025, 2026 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-accounts-H_WIRE.c 22 * @brief implementing PATCH /accounts/$ID request handling 23 * @author Christian Grothoff 24 */ 25 #include "platform.h" 26 #include "taler-merchant-httpd_patch-private-accounts-H_WIRE.h" 27 #include "taler-merchant-httpd_helper.h" 28 #include <taler/taler_json_lib.h> 29 #include "taler-merchant-httpd_mfa.h" 30 #include "taler/taler_merchant_bank_lib.h" 31 #include "merchant-database/get_account.h" 32 #include "merchant-database/update_account.h" 33 34 35 /** 36 * PATCH configuration of an existing instance, given its configuration. 37 * 38 * @param rh context of the handler 39 * @param connection the MHD connection to handle 40 * @param[in,out] hc context with further information about the request 41 * @return MHD result code 42 */ 43 enum MHD_Result 44 TMH_private_patch_accounts_ID (const struct TMH_RequestHandler *rh, 45 struct MHD_Connection *connection, 46 struct TMH_HandlerContext *hc) 47 { 48 struct TMH_MerchantInstance *mi = hc->instance; 49 const char *h_wire_s = hc->infix; 50 enum GNUNET_DB_QueryStatus qs; 51 const json_t *cfc = NULL; 52 const char *extra_wire_subject_metadata = NULL; 53 const char *cfu = NULL; 54 struct TALER_MerchantWireHashP h_wire; 55 struct GNUNET_JSON_Specification spec[] = { 56 GNUNET_JSON_spec_mark_optional ( 57 TALER_JSON_spec_web_url ("credit_facade_url", 58 &cfu), 59 NULL), 60 GNUNET_JSON_spec_mark_optional ( 61 GNUNET_JSON_spec_string ("extra_wire_subject_metadata", 62 &extra_wire_subject_metadata), 63 NULL), 64 GNUNET_JSON_spec_mark_optional ( 65 GNUNET_JSON_spec_object_const ("credit_facade_credentials", 66 &cfc), 67 NULL), 68 GNUNET_JSON_spec_end () 69 }; 70 71 GNUNET_assert (NULL != mi); 72 GNUNET_assert (NULL != h_wire_s); 73 if (GNUNET_OK != 74 GNUNET_STRINGS_string_to_data (h_wire_s, 75 strlen (h_wire_s), 76 &h_wire, 77 sizeof (h_wire))) 78 { 79 GNUNET_break_op (0); 80 return TALER_MHD_reply_with_error (connection, 81 MHD_HTTP_BAD_REQUEST, 82 TALER_EC_MERCHANT_GENERIC_H_WIRE_MALFORMED, 83 h_wire_s); 84 } 85 { 86 enum GNUNET_GenericReturnValue res; 87 88 res = TALER_MHD_parse_json_data (connection, 89 hc->request_body, 90 spec); 91 if (GNUNET_OK != res) 92 return (GNUNET_NO == res) 93 ? MHD_YES 94 : MHD_NO; 95 } 96 if (! TALER_is_valid_subject_metadata_string ( 97 extra_wire_subject_metadata)) 98 { 99 GNUNET_break_op (0); 100 return TALER_MHD_reply_with_error ( 101 connection, 102 MHD_HTTP_BAD_REQUEST, 103 TALER_EC_GENERIC_PARAMETER_MALFORMED, 104 "extra_wire_subject_metadata"); 105 } 106 if (NULL != cfu) 107 { 108 /* The credit facade URL and the (new or preserved) credentials 109 must be usable together, as taler-merchant-wirewatch refuses 110 to start with any unusable active account configuration. */ 111 struct TALER_MERCHANTDB_AccountDetails ad = { 0 }; 112 const json_t *ecfc = cfc; 113 struct TALER_MERCHANT_BANK_AuthenticationData auth; 114 bool valid; 115 116 if (NULL == ecfc) 117 { 118 qs = TALER_MERCHANTDB_get_account (TMH_db, 119 mi->settings.id, 120 &h_wire, 121 &ad); 122 if (0 > qs) 123 { 124 GNUNET_break (0); 125 GNUNET_JSON_parse_free (spec); 126 return TALER_MHD_reply_with_error ( 127 connection, 128 MHD_HTTP_INTERNAL_SERVER_ERROR, 129 TALER_EC_GENERIC_DB_FETCH_FAILED, 130 "get_account"); 131 } 132 if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) 133 { 134 GNUNET_JSON_parse_free (spec); 135 return TALER_MHD_reply_with_error ( 136 connection, 137 MHD_HTTP_NOT_FOUND, 138 TALER_EC_MERCHANT_GENERIC_ACCOUNT_UNKNOWN, 139 h_wire_s); 140 } 141 ecfc = ad.credit_facade_credentials; 142 } 143 valid = ( (NULL != ecfc) && 144 (GNUNET_OK == 145 TALER_MERCHANT_BANK_auth_parse_json (ecfc, 146 cfu, 147 &auth)) ); 148 if (valid) 149 TALER_MERCHANT_BANK_auth_free (&auth); 150 json_decref (ad.credit_facade_credentials); 151 GNUNET_free (ad.credit_facade_url); 152 GNUNET_free (ad.extra_wire_subject_metadata); 153 GNUNET_free (ad.payto_uri.full_payto); 154 if (! valid) 155 { 156 GNUNET_break_op (0); 157 GNUNET_JSON_parse_free (spec); 158 return TALER_MHD_reply_with_error ( 159 connection, 160 MHD_HTTP_BAD_REQUEST, 161 TALER_EC_GENERIC_PARAMETER_MALFORMED, 162 "credit_facade_url or credit_facade_credentials"); 163 } 164 } 165 166 qs = TALER_MERCHANTDB_update_account (TMH_db, 167 mi->settings.id, 168 &h_wire, 169 extra_wire_subject_metadata, 170 cfu, 171 cfc); 172 { 173 enum MHD_Result ret = MHD_NO; 174 175 switch (qs) 176 { 177 case GNUNET_DB_STATUS_HARD_ERROR: 178 GNUNET_break (0); 179 ret = TALER_MHD_reply_with_error ( 180 connection, 181 MHD_HTTP_INTERNAL_SERVER_ERROR, 182 TALER_EC_GENERIC_DB_STORE_FAILED, 183 "update_account"); 184 break; 185 case GNUNET_DB_STATUS_SOFT_ERROR: 186 GNUNET_break (0); 187 ret = TALER_MHD_reply_with_error ( 188 connection, 189 MHD_HTTP_INTERNAL_SERVER_ERROR, 190 TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, 191 "unexpected serialization problem"); 192 break; 193 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: 194 ret = TALER_MHD_reply_with_error ( 195 connection, 196 MHD_HTTP_NOT_FOUND, 197 TALER_EC_MERCHANT_GENERIC_ACCOUNT_UNKNOWN, 198 h_wire_s); 199 break; 200 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: 201 ret = TALER_MHD_reply_static (connection, 202 MHD_HTTP_NO_CONTENT, 203 NULL, 204 NULL, 205 0); 206 break; 207 } 208 GNUNET_JSON_parse_free (spec); 209 return ret; 210 } 211 } 212 213 214 /* end of taler-merchant-httpd_patch-private-accounts-H_WIRE.c */