taler-merchant-httpd.h (19362B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2025 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU 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 General Public License for more details. 12 13 You should have received a copy of the GNU 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.h 18 * @brief HTTP serving layer mainly intended to communicate with the frontend 19 * @author Marcello Stanisci 20 */ 21 #ifndef TALER_MERCHANT_HTTPD_H 22 #define TALER_MERCHANT_HTTPD_H 23 24 #include "platform.h" 25 #include "merchantdb_lib.h" 26 #include <taler/taler_mhd_lib.h> 27 #include <gnunet/gnunet_mhd_compat.h> 28 #include "taler/taler_merchant_bank_lib.h" 29 #include <regex.h> 30 31 32 /** 33 * Shorthand for exit jumps. 34 */ 35 #define EXITIF(cond) \ 36 do { \ 37 if (cond) { GNUNET_break (0); goto EXITIF_exit; } \ 38 } while (0) 39 40 41 /** 42 * Possible authorization scopes. This is a bit mask. 43 */ 44 enum TMH_AuthScope 45 { 46 /** 47 * Nothing is authorized. 48 */ 49 TMH_AS_NONE = 0, 50 51 /** 52 * Read-only access is OK. Any GET request is 53 * automatically OK. 54 */ 55 TMH_AS_READ_ONLY = 1, 56 57 /** 58 * 2 is Reserved. Was refreshable pre v42 59 */ 60 61 /** 62 * Order creation and payment status check only 63 */ 64 TMH_AS_ORDER_SIMPLE = 3, 65 66 /** 67 * Order creation and inventory locking, 68 * includes #TMH_AS_ORDER_SIMPLE 69 */ 70 TMH_AS_ORDER_POS = 4, 71 72 /** 73 * Order creation and refund 74 */ 75 TMH_AS_ORDER_MGMT = 5, 76 77 /** 78 * Order full 79 * Includes #TMH_AS_ORDER_POS and #TMH_AS_ORDER_MGMT 80 */ 81 TMH_AS_ORDER_FULL = 6, 82 83 /** 84 * Full access is granted to everything. 85 * We want to deprecate and remove this! 86 * Old scope "write" 87 */ 88 TMH_AS_ALL = 7 | 1 << 30, 89 90 /** 91 * Full access is granted to everything. 92 */ 93 TMH_AS_SPA = 8, 94 95 /** 96 * /login access to renew the token is OK. 97 * This is actually combined with other scopes 98 * and not (usually) used as a scope itself. 99 */ 100 TMH_AS_REFRESHABLE = 1 << 30, 101 102 }; 103 104 105 /** 106 * Supported wire method. Kept in a DLL. 107 */ 108 struct TMH_WireMethod 109 { 110 /** 111 * Next entry in DLL. 112 */ 113 struct TMH_WireMethod *next; 114 115 /** 116 * Previous entry in DLL. 117 */ 118 struct TMH_WireMethod *prev; 119 120 /** 121 * Which wire method / payment target identifier is @e payto_uri using? 122 */ 123 char *wire_method; 124 125 /** 126 * Wire details for this instance 127 */ 128 struct TALER_FullPayto payto_uri; 129 130 /** 131 * Salt to use when computing @e h_wire from @e payto_uri. 132 */ 133 struct TALER_WireSaltP wire_salt; 134 135 /** 136 * Hash of our wire format details as given in @e payto_uri 137 */ 138 struct TALER_MerchantWireHashP h_wire; 139 140 /** 141 * Base URL of the credit facade. 142 */ 143 char *credit_facade_url; 144 145 /** 146 * Authentication data to access the credit facade. 147 * May be uninitialized if not provided by the client. 148 */ 149 json_t *credit_facade_credentials; 150 151 /** 152 * Additional metadata to pass in the wire subject. NULL for none. 153 */ 154 char *extra_wire_subject_metadata; 155 156 /** 157 * Is this wire method active (should it be included in new contracts)? 158 */ 159 bool active; 160 161 /** 162 * Are we currently in a transaction to delete this account? 163 */ 164 bool deleting; 165 166 /** 167 * Are we currently in a transaction to enable this account? 168 */ 169 bool enabling; 170 171 }; 172 173 174 /** 175 * A pending GET /orders request that is in long polling mode. 176 */ 177 struct TMH_PendingOrder; 178 179 180 /** 181 * Information that defines a merchant "instance". That way, a single 182 * backend can account for several merchants, as used to do in donation 183 * shops 184 */ 185 struct TMH_MerchantInstance 186 { 187 188 /** 189 * Next entry in DLL. 190 */ 191 struct TMH_WireMethod *wm_head; 192 193 /** 194 * Previous entry in DLL. 195 */ 196 struct TMH_WireMethod *wm_tail; 197 198 /** 199 * Hash of the instance ID, key for the DHT. 200 */ 201 struct GNUNET_HashCode h_instance; 202 203 /** 204 * Head of DLL of long-polling GET /orders requests of this instance. 205 */ 206 struct TMH_PendingOrder *po_head; 207 208 /** 209 * Tail of DLL of long-polling GET /orders requests of this instance. 210 */ 211 struct TMH_PendingOrder *po_tail; 212 213 /** 214 * Database event we are waiting on to be resuming 215 * long-polling requests from the @e po_head. 216 */ 217 struct GNUNET_DB_EventHandler *po_eh; 218 219 /** 220 * Merchant's private key. 221 */ 222 struct TALER_MerchantPrivateKeyP merchant_priv; 223 224 /** 225 * Merchant's public key 226 */ 227 struct TALER_MerchantPublicKeyP merchant_pub; 228 229 /** 230 * General settings for an instance. 231 */ 232 struct TALER_MERCHANTDB_InstanceSettings settings; 233 234 /** 235 * General settings for an instance. 236 */ 237 struct TALER_MERCHANTDB_InstanceAuthSettings auth; 238 239 /** 240 * Reference counter on this structure. Only destroyed if the 241 * counter hits zero. 242 */ 243 unsigned int rc; 244 245 /** 246 * True if this instance was deleted (but not yet purged). 247 */ 248 bool deleted; 249 }; 250 251 252 GNUNET_NETWORK_STRUCT_BEGIN 253 254 255 /** 256 * Event triggered when a fulfillment URL is 257 * bound to a session (as paid). 258 */ 259 struct TMH_SessionEventP 260 { 261 /** 262 * Type is #TALER_DBEVENT_MERCHANT_SESSION_CAPTURED 263 */ 264 struct GNUNET_DB_EventHeaderP header; 265 266 /** 267 * Always zero (for alignment). 268 */ 269 uint32_t reserved GNUNET_PACKED; 270 271 /** 272 * Merchant's public key 273 */ 274 struct TALER_MerchantPublicKeyP merchant_pub; 275 276 /** 277 * Hash of the fulfillment URL. 278 */ 279 struct GNUNET_HashCode h_fulfillment_url; 280 281 /** 282 * Hash of the session ID 283 */ 284 struct GNUNET_HashCode h_session_id; 285 }; 286 287 288 /** 289 * Event triggered when an order's refund is increased 290 * or obtained by the respective wallet. 291 * 292 * Extra arguments are the amount (as a string). 293 */ 294 struct TMH_OrderRefundEventP 295 { 296 /** 297 * Type is #TALER_DBEVENT_MERCHANT_ORDER_REFUND or 298 * #TALER_DBEVENT_MERCHANT_REFUND_OBTAINED 299 */ 300 struct GNUNET_DB_EventHeaderP header; 301 302 /** 303 * Always zero (for alignment). 304 */ 305 uint32_t reserved GNUNET_PACKED; 306 307 /** 308 * Merchant's public key 309 */ 310 struct TALER_MerchantPublicKeyP merchant_pub; 311 312 /** 313 * Hash of the order ID. 314 */ 315 struct GNUNET_HashCode h_order_id; 316 }; 317 318 319 /** 320 * Event generated when a client picks up a reward. 321 */ 322 struct TMH_RewardPickupEventP 323 { 324 /** 325 * Type is #TALER_DBEVENT_MERCHANT_REWARD_PICKUP. 326 */ 327 struct GNUNET_DB_EventHeaderP header; 328 329 /** 330 * Always zero (for alignment). 331 */ 332 uint32_t reserved GNUNET_PACKED; 333 334 /** 335 * Reward ID. 336 */ 337 struct TALER_RewardIdentifierP reward_id; 338 339 /** 340 * Hash of the instance ID. 341 */ 342 struct GNUNET_HashCode h_instance; 343 344 }; 345 346 /** 347 * Possible flags indicating the state of an order. 348 */ 349 enum TMH_OrderStateFlags 350 { 351 TMH_OSF_NONE = 0, 352 353 /** 354 * Not yet used. 355 */ 356 TMH_OSF_CLAIMED = 1, 357 358 /** 359 * Customer paid the order. 360 */ 361 TMH_OSF_PAID = 2, 362 363 /** 364 * Merchant granted (possibly partial) refund. 365 */ 366 TMH_OSF_REFUNDED = 4, 367 368 /** 369 * Merchant received the payment from the exchange. 370 * FIXME: not triggered yet! 371 */ 372 TMH_OSF_WIRED = 8 373 }; 374 375 376 /** 377 * Extra information passed for a 378 * #TALER_DBEVENT_MERCHANT_ORDERS_CHANGE. 379 */ 380 struct TMH_OrderChangeEventDetailsP 381 { 382 /** 383 * Order ID, in NBO. 384 */ 385 uint64_t order_serial_id GNUNET_PACKED; 386 387 /** 388 * Execution date of the order. 389 */ 390 struct GNUNET_TIME_TimestampNBO execution_date; 391 392 /** 393 * See `enum TMH_OrderStateFlags`. In NBO. 394 */ 395 uint32_t order_state GNUNET_PACKED; 396 397 }; 398 399 400 /** 401 * Event triggered when an order's refund is increased 402 * or obtained by the respective wallet. 403 * 404 * Extra arguments are the amount (as a string). 405 */ 406 struct TMH_OrderChangeEventP 407 { 408 /** 409 * Type is #TALER_DBEVENT_MERCHANT_ORDERS_CHANGE. 410 */ 411 struct GNUNET_DB_EventHeaderP header; 412 413 /** 414 * Always zero (for alignment). 415 */ 416 uint32_t reserved GNUNET_PACKED; 417 418 /** 419 * Merchant's public key 420 */ 421 struct TALER_MerchantPublicKeyP merchant_pub; 422 }; 423 424 425 GNUNET_NETWORK_STRUCT_END 426 427 /** 428 * @brief Struct describing an URL and the handler for it. 429 * 430 * The overall URL is always @e url_prefix, optionally followed by the 431 * id_segment, which is optionally followed by the @e url_suffix. It is NOT 432 * allowed for the @e url_prefix to be directly followed by the @e url_suffix. 433 * A @e url_suffix SHOULD only be used with a @e method of #MHD_HTTP_METHOD_POST. 434 */ 435 struct TMH_RequestHandler; 436 437 /** 438 * This information is stored in the "connection_cls" of MHD for 439 * every request that we process. 440 * Individual handlers can evaluate its members and 441 * are allowed to update @e cc and @e ctx to store and clean up 442 * handler-specific data. 443 */ 444 struct TMH_HandlerContext; 445 446 447 /** 448 * @brief Struct describing an URL and the handler for it. 449 * 450 * The overall URL is always @e url_prefix, optionally followed by the 451 * id_segment, which is optionally followed by the @e url_suffix. It is NOT 452 * allowed for the @e url_prefix to be directly followed by the @e url_suffix. 453 * A @e url_suffix SHOULD only be used with a @e method of #MHD_HTTP_METHOD_POST. 454 */ 455 struct TMH_RequestHandler 456 { 457 458 /** 459 * URL prefix the handler is for, includes the '/', 460 * so "/orders", "/templates", "/webhooks" or "/products". Does *not* include 461 * "/private", that is controlled by the array in which 462 * the handler is defined. Must not contain any 463 * '/' except for the leading '/'. 464 */ 465 const char *url_prefix; 466 467 /** 468 * Required access permission for this request. 469 */ 470 const char *permission; 471 472 /** 473 * Does this request include an identifier segment 474 * (product_id, reserve_pub, order_id, reward_id, template_id, webhook_id) in the 475 * second segment? 476 */ 477 bool have_id_segment; 478 479 /** 480 * Does this request handler work without an instance? 481 */ 482 bool skip_instance; 483 484 /** 485 * Does this endpoint ONLY apply for the admin instance? 486 */ 487 bool default_only; 488 489 /** 490 * Does this request handler work with a deleted instance? 491 */ 492 bool allow_deleted_instance; 493 494 /** 495 * URL suffix the handler is for, excludes the '/', 496 * so "pay" or "claim", not "/pay". 497 */ 498 const char *url_suffix; 499 500 /** 501 * HTTP method the handler is for, NULL for "all". 502 */ 503 const char *method; 504 505 /** 506 * Mime type to use in reply (hint, can be NULL). 507 */ 508 const char *mime_type; 509 510 /** 511 * Raw data for the @e handler (can be NULL). 512 */ 513 const void *data; 514 515 /** 516 * Number of bytes in @e data. 517 */ 518 size_t data_size; 519 520 /** 521 * Maximum upload size allowed for this handler. 522 * 0 for #DEFAULT_MAX_UPLOAD_SIZE. 523 */ 524 size_t max_upload; 525 526 /** 527 * Handler to be called for this URL/METHOD combination. 528 * 529 * @param rh this struct 530 * @param connection the MHD connection to handle 531 * @param[in,out] hc context with further information about the request 532 * @return MHD result code 533 */ 534 enum MHD_Result 535 (*handler)(const struct TMH_RequestHandler *rh, 536 struct MHD_Connection *connection, 537 struct TMH_HandlerContext *hc); 538 539 /** 540 * Default response code to use. 541 */ 542 unsigned int response_code; 543 }; 544 545 546 /** 547 * Signature of a function used to clean up the context 548 * we keep in the "connection_cls" of MHD when handling 549 * a request. 550 * 551 * @param ctx the context to clean up. 552 */ 553 typedef void 554 (*TMH_ContextCleanup)(void *ctx); 555 556 557 /** 558 * This information is stored in the "connection_cls" of MHD for 559 * every request that we process. 560 * Individual handlers can evaluate its members and 561 * are allowed to update @e cc and @e ctx to store and clean up 562 * handler-specific data. 563 */ 564 struct TMH_HandlerContext 565 { 566 567 /** 568 * Function to execute the handler-specific cleanup of the 569 * (request-specific) context in @e ctx. 570 */ 571 TMH_ContextCleanup cc; 572 573 /** 574 * Client-specific context we keep. Passed to @e cc. 575 */ 576 void *ctx; 577 578 /** 579 * Which request handler is handling this request? 580 */ 581 const struct TMH_RequestHandler *rh; 582 583 /** 584 * Which instance is handling this request? 585 */ 586 struct TMH_MerchantInstance *instance; 587 588 /** 589 * Asynchronous request context id. 590 */ 591 struct GNUNET_AsyncScopeId async_scope_id; 592 593 /** 594 * Our original URL, for logging. 595 */ 596 const char *url; 597 598 /** 599 * Copy of our original full URL with query parameters. 600 */ 601 char *full_url; 602 603 /** 604 * Client-provided authentication token for this 605 * request, can be NULL. 606 * 607 * Used to check for concurrent, conflicting updates of 608 * the authentication information in the database. 609 */ 610 const char *auth_token; 611 612 /** 613 * Infix part of @a url. 614 */ 615 char *infix; 616 617 /** 618 * Which connection was suspended. 619 */ 620 struct MHD_Connection *connection; 621 622 /** 623 * JSON body that was uploaded, NULL if @e has_body is false. 624 */ 625 json_t *request_body; 626 627 /** 628 * Placeholder for #TALER_MHD_parse_post_json() to keep its internal state. 629 * Used when we parse the POSTed data. 630 */ 631 void *json_parse_context; 632 633 /** 634 * Total size of the upload so far. 635 */ 636 uint64_t total_upload; 637 638 /** 639 * Actual authentication scope of this request. 640 * Only set for ``/private/`` requests. 641 */ 642 enum TMH_AuthScope auth_scope; 643 644 /** 645 * Set to true if this is an #MHD_HTTP_METHOD_POST or #MHD_HTTP_METHOD_PATCH request. 646 * (In principle #MHD_HTTP_METHOD_PUT may also belong, but we do not have PUTs 647 * in the API today, so we do not test for PUT.) 648 */ 649 bool has_body; 650 }; 651 652 653 /** 654 * Information common for suspended requests. 655 */ 656 struct TMH_SuspendedConnection 657 { 658 /** 659 * Which connection was suspended. 660 */ 661 struct MHD_Connection *con; 662 663 /** 664 * At what time does this request expire? If set in the future, we 665 * may wait this long for a payment to arrive before responding. 666 */ 667 struct GNUNET_TIME_Absolute long_poll_timeout; 668 669 /** 670 * Minimum refund amount to be exceeded (exclusive this value!) for resume. 671 */ 672 struct TALER_Amount refund_expected; 673 674 /** 675 * true if we are waiting for a refund. 676 */ 677 bool awaiting_refund; 678 679 /** 680 * Whether we're waiting for the refunds to be obtained. 681 */ 682 bool awaiting_refund_obtained; 683 684 }; 685 686 687 /** 688 * Which currency do we use? 689 */ 690 extern char *TMH_currency; 691 692 /** 693 * What is the base URL for this merchant backend? NULL if it is not 694 * configured and is to be determined from HTTP headers (X-Forwarded-Host and 695 * X-Forwarded-Port and X-Forwarded-Prefix) of the reverse proxy. 696 */ 697 extern char *TMH_base_url; 698 699 /** 700 * Name of helper program to send e-mail. 701 */ 702 extern char *TMH_helper_email; 703 704 /** 705 * Name of helper program to send SMS. 706 */ 707 extern char *TMH_helper_sms; 708 709 /** 710 * Regex restriction acceptable set of phone numbers for instances. 711 */ 712 extern char *TMH_phone_regex; 713 714 /** 715 * Configuration data for the SPA. 716 */ 717 extern json_t *TMH_global_spa_config_data; 718 719 /** 720 * Compiled version of #TMH_phone_regex, only set if #TMH_phone_regex 721 * is not NULL. 722 */ 723 extern regex_t TMH_phone_rx; 724 725 /** 726 * Space-separated list of allowed payment target types. 727 * "*" for "all" (no restriction). 728 */ 729 extern char *TMH_allowed_payment_targets; 730 731 /** 732 * Default persona to use for new browsers. 733 */ 734 extern char *TMH_default_persona; 735 736 /** 737 * Regular expression further restricting payment target types. 738 * Can be NULL/empty for no restrictions. 739 */ 740 extern char *TMH_payment_target_regex; 741 742 /** 743 * Compiled regular expression, only valid if 744 * #TMH_payment_target_regex is not NULL! 745 */ 746 extern regex_t TMH_payment_target_re; 747 748 /** 749 * Length of the TMH_cspecs array. 750 */ 751 extern unsigned int TMH_num_cspecs; 752 753 /** 754 * Rendering specs for currencies. 755 */ 756 extern struct TALER_CurrencySpecification *TMH_cspecs; 757 758 /** 759 * Inform the auditor for all deposit confirmations (global option) 760 */ 761 extern int TMH_force_audit; 762 763 /** 764 * Our configuration. 765 */ 766 extern const struct GNUNET_CONFIGURATION_Handle *TMH_cfg; 767 768 /** 769 * Context for all CURL operations (useful to the event loop) 770 */ 771 extern struct GNUNET_CURL_Context *TMH_curl_ctx; 772 773 /** 774 * Handle to the database backend. 775 */ 776 extern struct TALER_MERCHANTDB_PostgresContext *TMH_db; 777 778 /** 779 * Hashmap pointing at merchant instances by 'id'. An 'id' is 780 * just a string that identifies a merchant instance. When a frontend 781 * needs to specify an instance to the backend, it does so by 'id' 782 */ 783 extern struct GNUNET_CONTAINER_MultiHashMap *TMH_by_id_map; 784 785 /** 786 * How long do we need to keep information on paid contracts on file for tax 787 * or other legal reasons? Used to block deletions for younger transaction 788 * data. 789 */ 790 extern struct GNUNET_TIME_Relative TMH_legal_expiration; 791 792 /** 793 * Default wire delay for new instances. 794 */ 795 extern struct GNUNET_TIME_Relative TMH_default_wire_transfer_delay; 796 797 /** 798 * Default rounding interval to be applied to new instances. 799 */ 800 extern enum GNUNET_TIME_RounderInterval 801 TMH_default_wire_transfer_rounding_interval; 802 803 /** 804 * Default payment delay for new instances. 805 */ 806 extern struct GNUNET_TIME_Relative TMH_default_pay_delay; 807 808 /** 809 * Default refund delay for new instances. 810 */ 811 extern struct GNUNET_TIME_Relative TMH_default_refund_delay; 812 813 /** 814 * #GNUNET_YES if protocol version 19 is strictly enforced. 815 * (Default is #GNUNET_NO) 816 */ 817 extern int TMH_strict_v19; 818 819 /** 820 * #GNUNET_YES if authentication is disabled (For testing only!!). 821 * (Default is #GNUNET_NO) 822 */ 823 extern int TMH_auth_disabled; 824 825 /** 826 * #GNUNET_YES if self-provisioning is enabled. 827 */ 828 extern int TMH_have_self_provisioning; 829 830 /** 831 * Set of TAN channels. 832 */ 833 enum TEH_TanChannelSet 834 { 835 TMH_TCS_NONE = 0, 836 TMH_TCS_SMS = 1, 837 TMH_TCS_EMAIL = 2, 838 TMH_TCS_EMAIL_AND_SMS = 3 839 }; 840 841 842 /** 843 * Which TAN channels are mandatory for self-provisioned 844 * accounts and password resets? Bitmask. 845 */ 846 extern enum TEH_TanChannelSet TEH_mandatory_tan_channels; 847 848 /** 849 * Callback that frees an instances removing 850 * it from the global hashmap. 851 * 852 * @param cls closure, pass NULL 853 * @param key current key (ignored) 854 * @param value a `struct TMH_MerchantInstance` 855 * @return #GNUNET_YES (always) 856 */ 857 enum GNUNET_GenericReturnValue 858 TMH_instance_free_cb (void *cls, 859 const struct GNUNET_HashCode *key, 860 void *value); 861 862 863 /** 864 * Add instance definition to our active set of instances. 865 * 866 * @param[in,out] mi merchant instance details to define 867 * @return #GNUNET_OK on success, #GNUNET_NO if the same ID is in use already 868 */ 869 enum GNUNET_GenericReturnValue 870 TMH_add_instance (struct TMH_MerchantInstance *mi); 871 872 873 /** 874 * Decrement reference counter of @a mi, and free if it hits zero. 875 * 876 * @param[in,out] mi merchant instance to update and possibly free 877 */ 878 void 879 TMH_instance_decref (struct TMH_MerchantInstance *mi); 880 881 882 /** 883 * Free memory allocated by @a wm. 884 * 885 * @param[in] wm wire method to free 886 */ 887 void 888 TMH_wire_method_free (struct TMH_WireMethod *wm); 889 890 891 /** 892 * Lookup a merchant instance by its instance ID. 893 * 894 * @param instance_id identifier of the instance to resolve 895 * @return NULL if that instance is unknown to us 896 */ 897 struct TMH_MerchantInstance * 898 TMH_lookup_instance (const char *instance_id); 899 900 901 /** 902 * A transaction modified an instance setting 903 * (or created/deleted/purged one). Notify all 904 * backends about the change. 905 * 906 * @param id ID of the instance that changed 907 */ 908 void 909 TMH_reload_instances (const char *id); 910 911 912 #endif