taler-merchant-httpd_helper.h (14755B)
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 * Compute the total transfer amount the merchant expects to have received 123 * for an order, taking into account refunds and the merchant's maximum 124 * deposit fee. 125 * 126 * The merchant only ever pays up to @a max_fee when one was specified; 127 * the customer covers any excess deposit fees. 128 * 129 * @param contract_amount order amount 130 * @param refund_amount total refunds (must not exceed @a contract_amount) 131 * @param deposit_fees_total sum of all deposit fees 132 * @param deposit_fees_refunded_total sum of refunded deposit fees 133 * @param max_fee maximum deposit fee the merchant pays (may be NULL) 134 * @param has_max_fee true if @a max_fee is valid 135 * @param[out] expected_total set to the expected transfer amount 136 * @return #GNUNET_OK on success, 137 * #GNUNET_SYSERR if refunds exceed the contract value or if refunded 138 * deposit fees exceed total deposit fees, 139 * #GNUNET_NO if the merchant's share of deposit fees exceeds the 140 * amount minus refunds. 141 */ 142 enum GNUNET_GenericReturnValue 143 TMH_compute_expected_transfer (const struct TALER_Amount *contract_amount, 144 const struct TALER_Amount *refund_amount, 145 const struct TALER_Amount *deposit_fees_total, 146 const struct TALER_Amount *deposit_fees_refunded_total, 147 const struct TALER_Amount *max_fee, 148 bool has_max_fee, 149 struct TALER_Amount *expected_total); 150 151 152 /** 153 * Set of category IDs. 154 */ 155 struct TMH_CategorySet 156 { 157 /** 158 * Category IDs. 159 */ 160 uint64_t *ids; 161 162 /** 163 * Number of entries in @e ids. 164 */ 165 unsigned int len; 166 }; 167 168 /** 169 * Set of unit identifiers. 170 */ 171 struct TMH_UnitSet 172 { 173 /** 174 * Unit identifiers. 175 */ 176 char **units; 177 178 /** 179 * Number of entries in @e units. 180 */ 181 unsigned int len; 182 }; 183 /** 184 * Check if a category set already contains a given ID. 185 * 186 * @param set category set 187 * @param id category id 188 * @return true if present 189 */ 190 bool 191 TMH_category_set_contains (const struct TMH_CategorySet *set, 192 uint64_t id); 193 194 /** 195 * Add a category ID to a set if not already present. 196 * 197 * @param set category set 198 * @param id category id 199 */ 200 void 201 TMH_category_set_add (struct TMH_CategorySet *set, 202 uint64_t id); 203 204 /** 205 * Check if a unit set already contains a given unit. 206 * 207 * @param set unit set 208 * @param unit unit identifier 209 * @return true if present 210 */ 211 bool 212 TMH_unit_set_contains (const struct TMH_UnitSet *set, 213 const char *unit); 214 215 /** 216 * Add a unit identifier to a set if not already present. 217 * 218 * @param set unit set 219 * @param unit unit identifier 220 */ 221 void 222 TMH_unit_set_add (struct TMH_UnitSet *set, 223 const char *unit); 224 225 /** 226 * Clear a unit set and free its contents. 227 * 228 * @param set unit set to clear 229 */ 230 void 231 TMH_unit_set_clear (struct TMH_UnitSet *set); 232 233 234 /** 235 * Lookup the defaults for @a unit within @a mi and fall back to sane 236 * values (disallow fractional quantities, zero precision) if no data 237 * is available. 238 * 239 * @param mi merchant instance whose defaults should be consulted (must not be NULL) 240 * @param unit textual unit name (must not be NULL or empty) 241 * @param allow_fractional updated with whether fractional quantities are allowed (must not be NULL) 242 * @param precision_level updated with the supported precision (must not be NULL) 243 */ 244 void 245 TMH_quantity_defaults_from_unit (const struct TMH_MerchantInstance *mi, 246 const char *unit, 247 bool *allow_fractional, 248 uint32_t *precision_level); 249 250 /** 251 * Query the database for precision defaults tied to @a unit within 252 * @a mi. Returns #GNUNET_OK even if no unit information exists, in 253 * which case the out-parameters remain at their implicit defaults. 254 * 255 * @param mi merchant instance whose unit table is inspected (must not be NULL) 256 * @param unit textual unit name (must not be NULL or empty) 257 * @param allow_fractional updated with whether fractional quantities are allowed (must not be NULL) 258 * @param precision_level updated with the supported precision (must not be NULL) 259 * @return #GNUNET_OK on success, #GNUNET_SYSERR on database failure 260 */ 261 enum GNUNET_GenericReturnValue 262 TMH_unit_defaults_for_instance (const struct TMH_MerchantInstance *mi, 263 const char *unit, 264 bool *allow_fractional, 265 uint32_t *precision_level); 266 267 268 /** 269 * Setup new wire method for the given @ payto_uri. 270 * 271 * @param payto_uri already validated payto URI 272 * @param credit_facade_url where to download credit information for this account (can be NULL) 273 * @param credit_facade_credentials credentials for the @a credit_facade_url 274 * @return new wire method object, never fails 275 */ 276 struct TMH_WireMethod * 277 TMH_setup_wire_account ( 278 struct TALER_FullPayto payto_uri, 279 const char *credit_facade_url, 280 const json_t *credit_facade_credentials); 281 282 283 /** 284 * Test if JSON spec @a account for a wire method is equal to the given @a wm. 285 * 286 * @param account JSON spec for a merchant account 287 * @param wm known wire method 288 * @return #GNUNET_YES if both specifications are equal 289 * #GNUNET_NO if the specifications are for 290 * the same account but differ in the credit facade 291 * #GNUNET_SYSERR if the specs are for different accounts 292 * or if @a account is malformed 293 */ 294 enum GNUNET_GenericReturnValue 295 TMH_cmp_wire_account ( 296 const json_t *account, 297 const struct TMH_WireMethod *wm); 298 299 300 /** 301 * Check that the provided authentication configuration 302 * is valid. 303 * 304 * @param connection connection to use for returning errors 305 * @param jauth JSON with authentication data 306 * @param[out] auth_token set to the authentication token 307 * @return #GNUNET_OK on success, 308 * #GNUNET_NO if an error was returned on @a connection 309 * #GNUNET_SYSERR if we failed to return an error on @a connection 310 */ 311 enum GNUNET_GenericReturnValue 312 TMH_check_auth_config (struct MHD_Connection *connection, 313 const json_t *jauth, 314 const char **auth_token); 315 316 317 /** 318 * Generate binary UUID from client-provided UUID-string. 319 * 320 * @param uuids string intpu 321 * @param[out] uuid set to binary UUID 322 */ 323 void 324 TMH_uuid_from_string (const char *uuids, 325 struct GNUNET_Uuid *uuid); 326 327 328 /** 329 * Initializes a buffer with 330 * the ``http[s]://$HOST/[$PATH/][instances/$INSTANCE/]`` 331 * string using $HOST and $PATH from @a connection. 332 * 333 * @param[in] connection connection to base the construction on 334 * @param instance instance to set, NULL for none 335 * @param[out] buf buffer to initialize 336 * @return #GNUNET_OK on success 337 */ 338 enum GNUNET_GenericReturnValue 339 TMH_base_url_by_connection (struct MHD_Connection *connection, 340 const char *instance, 341 struct GNUNET_Buffer *buf); 342 343 344 /** 345 * Initializes a buffer with 346 * the ``taler[+http]://$METHOD/$HOST/[instances/$INSTANCE/]`` 347 * string using $HOST from @a connection. 348 * 349 * @param[in] connection connection to base the construction on 350 * @param method taler-URI method to inject 351 * @param instance instance to set, NULL for none 352 * @param[out] buf buffer to initialize 353 * @return #GNUNET_OK on success 354 */ 355 enum GNUNET_GenericReturnValue 356 TMH_taler_uri_by_connection (struct MHD_Connection *connection, 357 const char *method, 358 const char *instance, 359 struct GNUNET_Buffer *buf); 360 361 362 /** 363 * Create a taler://pay/ URI for the given @a con and @a order_id 364 * and @a session_id and @a instance_id. 365 * 366 * @param con HTTP connection 367 * @param order_id the order id 368 * @param session_id session, may be NULL 369 * @param instance_id instance, may be "default" 370 * @param claim_token claim token for the order, may be NULL 371 * @return corresponding taler://pay/ URI, or NULL on missing "host" 372 */ 373 char * 374 TMH_make_taler_pay_uri (struct MHD_Connection *con, 375 const char *order_id, 376 const char *session_id, 377 const char *instance_id, 378 struct TALER_ClaimTokenP *claim_token); 379 380 /** 381 * Create a http(s) URL for the given @a con and @a order_id 382 * and @a instance_id to display the /orders/{order_id} page. 383 * 384 * @param con HTTP connection 385 * @param order_id the order id 386 * @param session_id session, may be NULL 387 * @param instance_id instance, may be "default" 388 * @param claim_token claim token for the order, may be NULL 389 * @param h_contract contract hash for authentication, may be NULL 390 * @return corresponding http(s):// URL, or NULL on missing "host" 391 */ 392 char * 393 TMH_make_order_status_url (struct MHD_Connection *con, 394 const char *order_id, 395 const char *session_id, 396 const char *instance_id, 397 struct TALER_ClaimTokenP *claim_token, 398 struct TALER_PrivateContractHashP *h_contract); 399 400 401 /** 402 * Put data from an exchange's HTTP response into 403 * a JSON reply 404 * 405 * @param hr a `TALER_EXCHANGE_HttpResponse` 406 */ 407 #define TMH_pack_exchange_reply(hr) \ 408 GNUNET_JSON_pack_uint64 ("exchange_code", (hr)->ec), \ 409 GNUNET_JSON_pack_uint64 ("exchange_http_status", (hr)->http_status), \ 410 GNUNET_JSON_pack_uint64 ("exchange_ec", (hr)->ec), /* LEGACY */ \ 411 GNUNET_JSON_pack_uint64 ("exchange_hc", (hr)->http_status), /* LEGACY */ \ 412 GNUNET_JSON_pack_allow_null ( \ 413 GNUNET_JSON_pack_object_incref ("exchange_reply", (json_t *) (hr)-> \ 414 reply)) 415 416 417 /** 418 * TMH_trigger_webhook is a function that need to be use when someone 419 * pay. Merchant need to have a notification. 420 * 421 * @param instance that we need to send the webhook as a notification 422 * @param event of the webhook 423 * @param args argument of the function 424 */ 425 enum GNUNET_DB_QueryStatus 426 TMH_trigger_webhook (const char *instance, 427 const char *action, 428 const json_t *args); 429 430 431 /** 432 * Return JSON array with all of the exchange accounts 433 * that support the given @a wire_method. 434 * 435 * @param master_pub master public key to match exchange by 436 * @param wire_method NULL for any 437 * @return JSON array with information about all matching accounts 438 */ 439 json_t * 440 TMH_exchange_accounts_by_method ( 441 const struct TALER_MasterPublicKeyP *master_pub, 442 const char *wire_method); 443 444 /** 445 * Check validity of login @a token for the given @a instance_id. 446 * 447 * @param token the login token given in the request 448 * @param instance_id the instance the login is to be checked against 449 * @param[out] as set to scope of the token if it is valid 450 * @return TALER_EC_NONE on success 451 */ 452 enum TALER_ErrorCode 453 TMH_check_token (const char *token, 454 const char *instance_id, 455 enum TMH_AuthScope *as); 456 457 #endif