taler-merchant-httpd_helper.h (13207B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2021-2023 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 Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero 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_helper.h 18 * @brief helpers for shared logic 19 * @author Florian Dold 20 * @author Benedikt Mueller 21 * @author Christian Grothoff 22 */ 23 #ifndef TALER_MERCHANT_HTTPD_HELPER_H 24 #define TALER_MERCHANT_HTTPD_HELPER_H 25 26 #define TMH_MAX_FRACTIONAL_PRECISION_LEVEL 6 27 28 29 #include "taler-merchant-httpd.h" 30 #include "taler/taler_merchant_util.h" 31 32 33 /** 34 * Serialize the public merchant metadata of an instance. 35 * 36 * @param mi merchant instance 37 * @return newly allocated JSON object 38 */ 39 json_t * 40 TMH_instance_metadata_to_json (const struct TMH_MerchantInstance *mi); 41 42 /** 43 * check @a accounts for well-formedness 44 * 45 * @param accounts JSON array of merchant accounts (presumably) 46 * @return true if they are all valid accounts 47 */ 48 bool 49 TMH_accounts_array_valid (const json_t *accounts); 50 51 52 /** 53 * Check if @a location is a valid Location object in the sense of Taler's API 54 * definition. 55 * 56 * @param location object to check 57 * @return true if @a location is an object 58 * representing a Location. 59 */ 60 bool 61 TMH_location_object_valid (const json_t *location); 62 63 64 /** 65 * Check if @a products is an array of valid Product(s) in the sense of 66 * Taler's API definition. 67 * 68 * @param products array to check 69 * @return true if @a products is an array and all 70 * entries are valid Products. 71 */ 72 bool 73 TMH_products_array_valid (const json_t *products); 74 75 76 /** 77 * Parse decimal quantity expressed as string for request handling. 78 * 79 * @param value string to parse 80 * @param[out] integer_part result integer component 81 * @param[out] fractional_part result fractional component (0..MERCHANT_UNIT_FRAC_BASE-1) 82 * @return #GNUNET_OK on success, #GNUNET_SYSERR on validation failure 83 */ 84 enum GNUNET_GenericReturnValue 85 TMH_parse_fractional_string (const char *value, 86 int64_t *integer_part, 87 uint32_t *fractional_part); 88 89 /** 90 * Check that no two prices use the same currency. 91 * 92 * @param prices price list to check 93 * @param prices_len length of @a prices 94 * @return #GNUNET_OK if unique, #GNUNET_SYSERR otherwise 95 */ 96 enum GNUNET_GenericReturnValue 97 TMH_validate_unit_price_array (const struct TALER_Amount *prices, 98 size_t prices_len); 99 100 101 /** 102 * Compute the full value of an order from its contract terms. 103 * 104 * The total consists of the Taler amount of the selected choice plus all 105 * entries in "amount_external". 106 * 107 * @param contract_terms contract terms of the order 108 * @param choice_index selected choice, ignored for v0 contracts; for v1 109 * contracts it must be non-negative, as the total is undefined 110 * while no choice was selected 111 * @param[out] total set to the full order total 112 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the contract is 113 * malformed or no choice was selected for a v1 contract 114 */ 115 enum GNUNET_GenericReturnValue 116 TMH_compute_order_total (const json_t *contract_terms, 117 int16_t choice_index, 118 struct TALER_Amount *total); 119 120 121 /** 122 * Set of category IDs. 123 */ 124 struct TMH_CategorySet 125 { 126 /** 127 * Category IDs. 128 */ 129 uint64_t *ids; 130 131 /** 132 * Number of entries in @e ids. 133 */ 134 unsigned int len; 135 }; 136 137 /** 138 * Set of unit identifiers. 139 */ 140 struct TMH_UnitSet 141 { 142 /** 143 * Unit identifiers. 144 */ 145 char **units; 146 147 /** 148 * Number of entries in @e units. 149 */ 150 unsigned int len; 151 }; 152 /** 153 * Check if a category set already contains a given ID. 154 * 155 * @param set category set 156 * @param id category id 157 * @return true if present 158 */ 159 bool 160 TMH_category_set_contains (const struct TMH_CategorySet *set, 161 uint64_t id); 162 163 /** 164 * Add a category ID to a set if not already present. 165 * 166 * @param set category set 167 * @param id category id 168 */ 169 void 170 TMH_category_set_add (struct TMH_CategorySet *set, 171 uint64_t id); 172 173 /** 174 * Check if a unit set already contains a given unit. 175 * 176 * @param set unit set 177 * @param unit unit identifier 178 * @return true if present 179 */ 180 bool 181 TMH_unit_set_contains (const struct TMH_UnitSet *set, 182 const char *unit); 183 184 /** 185 * Add a unit identifier to a set if not already present. 186 * 187 * @param set unit set 188 * @param unit unit identifier 189 */ 190 void 191 TMH_unit_set_add (struct TMH_UnitSet *set, 192 const char *unit); 193 194 /** 195 * Clear a unit set and free its contents. 196 * 197 * @param set unit set to clear 198 */ 199 void 200 TMH_unit_set_clear (struct TMH_UnitSet *set); 201 202 203 /** 204 * Lookup the defaults for @a unit within @a mi and fall back to sane 205 * values (disallow fractional quantities, zero precision) if no data 206 * is available. 207 * 208 * @param mi merchant instance whose defaults should be consulted (must not be NULL) 209 * @param unit textual unit name (must not be NULL or empty) 210 * @param allow_fractional updated with whether fractional quantities are allowed (must not be NULL) 211 * @param precision_level updated with the supported precision (must not be NULL) 212 */ 213 void 214 TMH_quantity_defaults_from_unit (const struct TMH_MerchantInstance *mi, 215 const char *unit, 216 bool *allow_fractional, 217 uint32_t *precision_level); 218 219 /** 220 * Query the database for precision defaults tied to @a unit within 221 * @a mi. Returns #GNUNET_OK even if no unit information exists, in 222 * which case the out-parameters remain at their implicit defaults. 223 * 224 * @param mi merchant instance whose unit table is inspected (must not be NULL) 225 * @param unit textual unit name (must not be NULL or empty) 226 * @param allow_fractional updated with whether fractional quantities are allowed (must not be NULL) 227 * @param precision_level updated with the supported precision (must not be NULL) 228 * @return #GNUNET_OK on success, #GNUNET_SYSERR on database failure 229 */ 230 enum GNUNET_GenericReturnValue 231 TMH_unit_defaults_for_instance (const struct TMH_MerchantInstance *mi, 232 const char *unit, 233 bool *allow_fractional, 234 uint32_t *precision_level); 235 236 237 /** 238 * Setup new wire method for the given @ payto_uri. 239 * 240 * @param payto_uri already validated payto URI 241 * @param credit_facade_url where to download credit information for this account (can be NULL) 242 * @param credit_facade_credentials credentials for the @a credit_facade_url 243 * @return new wire method object, never fails 244 */ 245 struct TMH_WireMethod * 246 TMH_setup_wire_account ( 247 struct TALER_FullPayto payto_uri, 248 const char *credit_facade_url, 249 const json_t *credit_facade_credentials); 250 251 252 /** 253 * Test if JSON spec @a account for a wire method is equal to the given @a wm. 254 * 255 * @param account JSON spec for a merchant account 256 * @param wm known wire method 257 * @return #GNUNET_YES if both specifications are equal 258 * #GNUNET_NO if the specifications are for 259 * the same account but differ in the credit facade 260 * #GNUNET_SYSERR if the specs are for different accounts 261 * or if @a account is malformed 262 */ 263 enum GNUNET_GenericReturnValue 264 TMH_cmp_wire_account ( 265 const json_t *account, 266 const struct TMH_WireMethod *wm); 267 268 269 /** 270 * Check that the provided authentication configuration 271 * is valid. 272 * 273 * @param connection connection to use for returning errors 274 * @param jauth JSON with authentication data 275 * @param[out] auth_token set to the authentication token 276 * @return #GNUNET_OK on success, 277 * #GNUNET_NO if an error was returned on @a connection 278 * #GNUNET_SYSERR if we failed to return an error on @a connection 279 */ 280 enum GNUNET_GenericReturnValue 281 TMH_check_auth_config (struct MHD_Connection *connection, 282 const json_t *jauth, 283 const char **auth_token); 284 285 286 /** 287 * Generate binary UUID from client-provided UUID-string. 288 * 289 * @param uuids string intpu 290 * @param[out] uuid set to binary UUID 291 */ 292 void 293 TMH_uuid_from_string (const char *uuids, 294 struct GNUNET_Uuid *uuid); 295 296 297 /** 298 * Initializes a buffer with 299 * the ``http[s]://$HOST/[$PATH/][instances/$INSTANCE/]`` 300 * string using $HOST and $PATH from @a connection. 301 * 302 * @param[in] connection connection to base the construction on 303 * @param instance instance to set, NULL for none 304 * @param[out] buf buffer to initialize 305 * @return #GNUNET_OK on success 306 */ 307 enum GNUNET_GenericReturnValue 308 TMH_base_url_by_connection (struct MHD_Connection *connection, 309 const char *instance, 310 struct GNUNET_Buffer *buf); 311 312 313 /** 314 * Initializes a buffer with 315 * the ``taler[+http]://$METHOD/$HOST/[instances/$INSTANCE/]`` 316 * string using $HOST from @a connection. 317 * 318 * @param[in] connection connection to base the construction on 319 * @param method taler-URI method to inject 320 * @param instance instance to set, NULL for none 321 * @param[out] buf buffer to initialize 322 * @return #GNUNET_OK on success 323 */ 324 enum GNUNET_GenericReturnValue 325 TMH_taler_uri_by_connection (struct MHD_Connection *connection, 326 const char *method, 327 const char *instance, 328 struct GNUNET_Buffer *buf); 329 330 331 /** 332 * Create a taler://pay/ URI for the given @a con and @a order_id 333 * and @a session_id and @a instance_id. 334 * 335 * @param con HTTP connection 336 * @param order_id the order id 337 * @param session_id session, may be NULL 338 * @param instance_id instance, may be "default" 339 * @param claim_token claim token for the order, may be NULL 340 * @return corresponding taler://pay/ URI, or NULL on missing "host" 341 */ 342 char * 343 TMH_make_taler_pay_uri (struct MHD_Connection *con, 344 const char *order_id, 345 const char *session_id, 346 const char *instance_id, 347 struct TALER_ClaimTokenP *claim_token); 348 349 /** 350 * Create a http(s) URL for the given @a con and @a order_id 351 * and @a instance_id to display the /orders/{order_id} page. 352 * 353 * @param con HTTP connection 354 * @param order_id the order id 355 * @param session_id session, may be NULL 356 * @param instance_id instance, may be "default" 357 * @param claim_token claim token for the order, may be NULL 358 * @param h_contract contract hash for authentication, may be NULL 359 * @return corresponding http(s):// URL, or NULL on missing "host" 360 */ 361 char * 362 TMH_make_order_status_url (struct MHD_Connection *con, 363 const char *order_id, 364 const char *session_id, 365 const char *instance_id, 366 struct TALER_ClaimTokenP *claim_token, 367 struct TALER_PrivateContractHashP *h_contract); 368 369 370 /** 371 * Put data from an exchange's HTTP response into 372 * a JSON reply 373 * 374 * @param hr a `TALER_EXCHANGE_HttpResponse` 375 */ 376 #define TMH_pack_exchange_reply(hr) \ 377 GNUNET_JSON_pack_uint64 ("exchange_code", (hr)->ec), \ 378 GNUNET_JSON_pack_uint64 ("exchange_http_status", (hr)->http_status), \ 379 GNUNET_JSON_pack_uint64 ("exchange_ec", (hr)->ec), /* LEGACY */ \ 380 GNUNET_JSON_pack_uint64 ("exchange_hc", (hr)->http_status), /* LEGACY */ \ 381 GNUNET_JSON_pack_allow_null ( \ 382 GNUNET_JSON_pack_object_incref ("exchange_reply", (json_t *) (hr)-> \ 383 reply)) 384 385 386 /** 387 * TMH_trigger_webhook is a function that need to be use when someone 388 * pay. Merchant need to have a notification. 389 * 390 * @param instance that we need to send the webhook as a notification 391 * @param event of the webhook 392 * @param args argument of the function 393 */ 394 enum GNUNET_DB_QueryStatus 395 TMH_trigger_webhook (const char *instance, 396 const char *action, 397 const json_t *args); 398 399 400 /** 401 * Return JSON array with all of the exchange accounts 402 * that support the given @a wire_method. 403 * 404 * @param master_pub master public key to match exchange by 405 * @param wire_method NULL for any 406 * @return JSON array with information about all matching accounts 407 */ 408 json_t * 409 TMH_exchange_accounts_by_method ( 410 const struct TALER_MasterPublicKeyP *master_pub, 411 const char *wire_method); 412 413 /** 414 * Check validity of login @a token for the given @a instance_id. 415 * 416 * @param token the login token given in the request 417 * @param instance_id the instance the login is to be checked against 418 * @param[out] as set to scope of the token if it is valid 419 * @return TALER_EC_NONE on success 420 */ 421 enum TALER_ErrorCode 422 TMH_check_token (const char *token, 423 const char *instance_id, 424 enum TMH_AuthScope *as); 425 426 #endif