taler-merchant-httpd.h (19469B)
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 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 "taler/platform.h" 25 #include "taler/taler_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 * True if email/sms validation is needed before the 252 * instance can be used. 253 */ 254 bool validation_needed; 255 }; 256 257 258 GNUNET_NETWORK_STRUCT_BEGIN 259 260 261 /** 262 * Event triggered when a fulfillment URL is 263 * bound to a session (as paid). 264 */ 265 struct TMH_SessionEventP 266 { 267 /** 268 * Type is #TALER_DBEVENT_MERCHANT_SESSION_CAPTURED 269 */ 270 struct GNUNET_DB_EventHeaderP header; 271 272 /** 273 * Always zero (for alignment). 274 */ 275 uint32_t reserved GNUNET_PACKED; 276 277 /** 278 * Merchant's public key 279 */ 280 struct TALER_MerchantPublicKeyP merchant_pub; 281 282 /** 283 * Hash of the fulfillment URL. 284 */ 285 struct GNUNET_HashCode h_fulfillment_url; 286 287 /** 288 * Hash of the session ID 289 */ 290 struct GNUNET_HashCode h_session_id; 291 }; 292 293 294 /** 295 * Event triggered when an order's refund is increased 296 * or obtained by the respective wallet. 297 * 298 * Extra arguments are the amount (as a string). 299 */ 300 struct TMH_OrderRefundEventP 301 { 302 /** 303 * Type is #TALER_DBEVENT_MERCHANT_ORDER_REFUND or 304 * #TALER_DBEVENT_MERCHANT_REFUND_OBTAINED 305 */ 306 struct GNUNET_DB_EventHeaderP header; 307 308 /** 309 * Always zero (for alignment). 310 */ 311 uint32_t reserved GNUNET_PACKED; 312 313 /** 314 * Merchant's public key 315 */ 316 struct TALER_MerchantPublicKeyP merchant_pub; 317 318 /** 319 * Hash of the order ID. 320 */ 321 struct GNUNET_HashCode h_order_id; 322 }; 323 324 325 /** 326 * Event generated when a client picks up a reward. 327 */ 328 struct TMH_RewardPickupEventP 329 { 330 /** 331 * Type is #TALER_DBEVENT_MERCHANT_REWARD_PICKUP. 332 */ 333 struct GNUNET_DB_EventHeaderP header; 334 335 /** 336 * Always zero (for alignment). 337 */ 338 uint32_t reserved GNUNET_PACKED; 339 340 /** 341 * Reward ID. 342 */ 343 struct TALER_RewardIdentifierP reward_id; 344 345 /** 346 * Hash of the instance ID. 347 */ 348 struct GNUNET_HashCode h_instance; 349 350 }; 351 352 /** 353 * Possible flags indicating the state of an order. 354 */ 355 enum TMH_OrderStateFlags 356 { 357 TMH_OSF_NONE = 0, 358 359 /** 360 * Not yet used. 361 */ 362 TMH_OSF_CLAIMED = 1, 363 364 /** 365 * Customer paid the order. 366 */ 367 TMH_OSF_PAID = 2, 368 369 /** 370 * Merchant granted (possibly partial) refund. 371 */ 372 TMH_OSF_REFUNDED = 4, 373 374 /** 375 * Merchant received the payment from the exchange. 376 * FIXME: not triggered yet! 377 */ 378 TMH_OSF_WIRED = 8 379 }; 380 381 382 /** 383 * Extra information passed for a 384 * #TALER_DBEVENT_MERCHANT_ORDERS_CHANGE. 385 */ 386 struct TMH_OrderChangeEventDetailsP 387 { 388 /** 389 * Order ID, in NBO. 390 */ 391 uint64_t order_serial_id GNUNET_PACKED; 392 393 /** 394 * Execution date of the order. 395 */ 396 struct GNUNET_TIME_TimestampNBO execution_date; 397 398 /** 399 * See `enum TMH_OrderStateFlags`. In NBO. 400 */ 401 uint32_t order_state GNUNET_PACKED; 402 403 }; 404 405 406 /** 407 * Event triggered when an order's refund is increased 408 * or obtained by the respective wallet. 409 * 410 * Extra arguments are the amount (as a string). 411 */ 412 struct TMH_OrderChangeEventP 413 { 414 /** 415 * Type is #TALER_DBEVENT_MERCHANT_ORDERS_CHANGE. 416 */ 417 struct GNUNET_DB_EventHeaderP header; 418 419 /** 420 * Always zero (for alignment). 421 */ 422 uint32_t reserved GNUNET_PACKED; 423 424 /** 425 * Merchant's public key 426 */ 427 struct TALER_MerchantPublicKeyP merchant_pub; 428 }; 429 430 431 GNUNET_NETWORK_STRUCT_END 432 433 /** 434 * @brief Struct describing an URL and the handler for it. 435 * 436 * The overall URL is always @e url_prefix, optionally followed by the 437 * id_segment, which is optionally followed by the @e url_suffix. It is NOT 438 * allowed for the @e url_prefix to be directly followed by the @e url_suffix. 439 * A @e url_suffix SHOULD only be used with a @e method of #MHD_HTTP_METHOD_POST. 440 */ 441 struct TMH_RequestHandler; 442 443 /** 444 * This information is stored in the "connection_cls" of MHD for 445 * every request that we process. 446 * Individual handlers can evaluate its members and 447 * are allowed to update @e cc and @e ctx to store and clean up 448 * handler-specific data. 449 */ 450 struct TMH_HandlerContext; 451 452 453 /** 454 * @brief Struct describing an URL and the handler for it. 455 * 456 * The overall URL is always @e url_prefix, optionally followed by the 457 * id_segment, which is optionally followed by the @e url_suffix. It is NOT 458 * allowed for the @e url_prefix to be directly followed by the @e url_suffix. 459 * A @e url_suffix SHOULD only be used with a @e method of #MHD_HTTP_METHOD_POST. 460 */ 461 struct TMH_RequestHandler 462 { 463 464 /** 465 * URL prefix the handler is for, includes the '/', 466 * so "/orders", "/templates", "/webhooks" or "/products". Does *not* include 467 * "/private", that is controlled by the array in which 468 * the handler is defined. Must not contain any 469 * '/' except for the leading '/'. 470 */ 471 const char *url_prefix; 472 473 /** 474 * Required access permission for this request. 475 */ 476 const char *permission; 477 478 /** 479 * Does this request include an identifier segment 480 * (product_id, reserve_pub, order_id, reward_id, template_id, webhook_id) in the 481 * second segment? 482 */ 483 bool have_id_segment; 484 485 /** 486 * Does this request handler work without an instance? 487 */ 488 bool skip_instance; 489 490 /** 491 * Does this endpoint ONLY apply for the admin instance? 492 */ 493 bool default_only; 494 495 /** 496 * Does this request handler work with a deleted instance? 497 */ 498 bool allow_deleted_instance; 499 500 /** 501 * URL suffix the handler is for, excludes the '/', 502 * so "pay" or "claim", not "/pay". 503 */ 504 const char *url_suffix; 505 506 /** 507 * HTTP method the handler is for, NULL for "all". 508 */ 509 const char *method; 510 511 /** 512 * Mime type to use in reply (hint, can be NULL). 513 */ 514 const char *mime_type; 515 516 /** 517 * Raw data for the @e handler (can be NULL). 518 */ 519 const void *data; 520 521 /** 522 * Number of bytes in @e data. 523 */ 524 size_t data_size; 525 526 /** 527 * Maximum upload size allowed for this handler. 528 * 0 for #DEFAULT_MAX_UPLOAD_SIZE. 529 */ 530 size_t max_upload; 531 532 /** 533 * Handler to be called for this URL/METHOD combination. 534 * 535 * @param rh this struct 536 * @param connection the MHD connection to handle 537 * @param[in,out] hc context with further information about the request 538 * @return MHD result code 539 */ 540 MHD_RESULT 541 (*handler)(const struct TMH_RequestHandler *rh, 542 struct MHD_Connection *connection, 543 struct TMH_HandlerContext *hc); 544 545 /** 546 * Default response code to use. 547 */ 548 unsigned int response_code; 549 }; 550 551 552 /** 553 * Signature of a function used to clean up the context 554 * we keep in the "connection_cls" of MHD when handling 555 * a request. 556 * 557 * @param ctx the context to clean up. 558 */ 559 typedef void 560 (*TMH_ContextCleanup)(void *ctx); 561 562 563 /** 564 * This information is stored in the "connection_cls" of MHD for 565 * every request that we process. 566 * Individual handlers can evaluate its members and 567 * are allowed to update @e cc and @e ctx to store and clean up 568 * handler-specific data. 569 */ 570 struct TMH_HandlerContext 571 { 572 573 /** 574 * Function to execute the handler-specific cleanup of the 575 * (request-specific) context in @e ctx. 576 */ 577 TMH_ContextCleanup cc; 578 579 /** 580 * Client-specific context we keep. Passed to @e cc. 581 */ 582 void *ctx; 583 584 /** 585 * Which request handler is handling this request? 586 */ 587 const struct TMH_RequestHandler *rh; 588 589 /** 590 * Which instance is handling this request? 591 */ 592 struct TMH_MerchantInstance *instance; 593 594 /** 595 * Asynchronous request context id. 596 */ 597 struct GNUNET_AsyncScopeId async_scope_id; 598 599 /** 600 * Our original URL, for logging. 601 */ 602 const char *url; 603 604 /** 605 * Copy of our original full URL with query parameters. 606 */ 607 char *full_url; 608 609 /** 610 * Client-provided authentication token for this 611 * request, can be NULL. 612 * 613 * Used to check for concurrent, conflicting updates of 614 * the authentication information in the database. 615 */ 616 const char *auth_token; 617 618 /** 619 * Infix part of @a url. 620 */ 621 char *infix; 622 623 /** 624 * Which connection was suspended. 625 */ 626 struct MHD_Connection *connection; 627 628 /** 629 * JSON body that was uploaded, NULL if @e has_body is false. 630 */ 631 json_t *request_body; 632 633 /** 634 * Placeholder for #TALER_MHD_parse_post_json() to keep its internal state. 635 * Used when we parse the POSTed data. 636 */ 637 void *json_parse_context; 638 639 /** 640 * Total size of the upload so far. 641 */ 642 uint64_t total_upload; 643 644 /** 645 * Actual authentication scope of this request. 646 * Only set for ``/private/`` requests. 647 */ 648 enum TMH_AuthScope auth_scope; 649 650 /** 651 * Set to true if this is an #MHD_HTTP_METHOD_POST or #MHD_HTTP_METHOD_PATCH request. 652 * (In principle #MHD_HTTP_METHOD_PUT may also belong, but we do not have PUTs 653 * in the API today, so we do not test for PUT.) 654 */ 655 bool has_body; 656 }; 657 658 659 /** 660 * Information common for suspended requests. 661 */ 662 struct TMH_SuspendedConnection 663 { 664 /** 665 * Which connection was suspended. 666 */ 667 struct MHD_Connection *con; 668 669 /** 670 * At what time does this request expire? If set in the future, we 671 * may wait this long for a payment to arrive before responding. 672 */ 673 struct GNUNET_TIME_Absolute long_poll_timeout; 674 675 /** 676 * Minimum refund amount to be exceeded (exclusive this value!) for resume. 677 */ 678 struct TALER_Amount refund_expected; 679 680 /** 681 * true if we are waiting for a refund. 682 */ 683 bool awaiting_refund; 684 685 /** 686 * Whether we're waiting for the refunds to be obtained. 687 */ 688 bool awaiting_refund_obtained; 689 690 }; 691 692 693 /** 694 * Which currency do we use? 695 */ 696 extern char *TMH_currency; 697 698 /** 699 * What is the base URL for this merchant backend? NULL if it is not 700 * configured and is to be determined from HTTP headers (X-Forwarded-Host and 701 * X-Forwarded-Port and X-Forwarded-Prefix) of the reverse proxy. 702 */ 703 extern char *TMH_base_url; 704 705 /** 706 * Name of helper program to send e-mail. 707 */ 708 extern char *TMH_helper_email; 709 710 /** 711 * Name of helper program to send SMS. 712 */ 713 extern char *TMH_helper_sms; 714 715 /** 716 * Regex restriction acceptable set of phone numbers for instances. 717 */ 718 extern char *TMH_phone_regex; 719 720 /** 721 * Configuration data for the SPA. 722 */ 723 extern json_t *TMH_global_spa_config_data; 724 725 /** 726 * Compiled version of #TMH_phone_regex, only set if #TMH_phone_regex 727 * is not NULL. 728 */ 729 extern regex_t TMH_phone_rx; 730 731 /** 732 * Space-separated list of allowed payment target types. 733 * "*" for "all" (no restriction). 734 */ 735 extern char *TMH_allowed_payment_targets; 736 737 /** 738 * Default persona to use for new browsers. 739 */ 740 extern char *TMH_default_persona; 741 742 /** 743 * Regular expression further restricting payment target types. 744 * Can be NULL/empty for no restrictions. 745 */ 746 extern char *TMH_payment_target_regex; 747 748 /** 749 * Compiled regular expression, only valid if 750 * #TMH_payment_target_regex is not NULL! 751 */ 752 extern regex_t TMH_payment_target_re; 753 754 /** 755 * Length of the TMH_cspecs array. 756 */ 757 extern unsigned int TMH_num_cspecs; 758 759 /** 760 * Rendering specs for currencies. 761 */ 762 extern struct TALER_CurrencySpecification *TMH_cspecs; 763 764 /** 765 * Inform the auditor for all deposit confirmations (global option) 766 */ 767 extern int TMH_force_audit; 768 769 /** 770 * Our configuration. 771 */ 772 extern const struct GNUNET_CONFIGURATION_Handle *TMH_cfg; 773 774 /** 775 * Context for all CURL operations (useful to the event loop) 776 */ 777 extern struct GNUNET_CURL_Context *TMH_curl_ctx; 778 779 /** 780 * Handle to the database backend. 781 */ 782 extern struct TALER_MERCHANTDB_Plugin *TMH_db; 783 784 /** 785 * Hashmap pointing at merchant instances by 'id'. An 'id' is 786 * just a string that identifies a merchant instance. When a frontend 787 * needs to specify an instance to the backend, it does so by 'id' 788 */ 789 extern struct GNUNET_CONTAINER_MultiHashMap *TMH_by_id_map; 790 791 /** 792 * How long do we need to keep information on paid contracts on file for tax 793 * or other legal reasons? Used to block deletions for younger transaction 794 * data. 795 */ 796 extern struct GNUNET_TIME_Relative TMH_legal_expiration; 797 798 /** 799 * Default wire delay for new instances. 800 */ 801 extern struct GNUNET_TIME_Relative TMH_default_wire_transfer_delay; 802 803 /** 804 * Default rounding interval to be applied to new instances. 805 */ 806 extern enum GNUNET_TIME_RounderInterval 807 TMH_default_wire_transfer_rounding_interval; 808 809 /** 810 * Default payment delay for new instances. 811 */ 812 extern struct GNUNET_TIME_Relative TMH_default_pay_delay; 813 814 /** 815 * Default refund delay for new instances. 816 */ 817 extern struct GNUNET_TIME_Relative TMH_default_refund_delay; 818 819 /** 820 * #GNUNET_YES if protocol version 19 is strictly enforced. 821 * (Default is #GNUNET_NO) 822 */ 823 extern int TMH_strict_v19; 824 825 /** 826 * #GNUNET_YES if authentication is disabled (For testing only!!). 827 * (Default is #GNUNET_NO) 828 */ 829 extern int TMH_auth_disabled; 830 831 /** 832 * #GNUNET_YES if self-provisioning is enabled. 833 */ 834 extern int TMH_have_self_provisioning; 835 836 /** 837 * Set of TAN channels. 838 */ 839 enum TEH_TanChannelSet 840 { 841 TMH_TCS_NONE = 0, 842 TMH_TCS_SMS = 1, 843 TMH_TCS_EMAIL = 2, 844 TMH_TCS_EMAIL_AND_SMS = 3 845 }; 846 847 848 /** 849 * Which TAN channels are mandatory for self-provisioned 850 * accounts and password resets? Bitmask. 851 */ 852 extern enum TEH_TanChannelSet TEH_mandatory_tan_channels; 853 854 /** 855 * Callback that frees an instances removing 856 * it from the global hashmap. 857 * 858 * @param cls closure, pass NULL 859 * @param key current key (ignored) 860 * @param value a `struct TMH_MerchantInstance` 861 * @return #GNUNET_YES (always) 862 */ 863 enum GNUNET_GenericReturnValue 864 TMH_instance_free_cb (void *cls, 865 const struct GNUNET_HashCode *key, 866 void *value); 867 868 869 /** 870 * Add instance definition to our active set of instances. 871 * 872 * @param[in,out] mi merchant instance details to define 873 * @return #GNUNET_OK on success, #GNUNET_NO if the same ID is in use already 874 */ 875 enum GNUNET_GenericReturnValue 876 TMH_add_instance (struct TMH_MerchantInstance *mi); 877 878 879 /** 880 * Decrement reference counter of @a mi, and free if it hits zero. 881 * 882 * @param[in,out] mi merchant instance to update and possibly free 883 */ 884 void 885 TMH_instance_decref (struct TMH_MerchantInstance *mi); 886 887 888 /** 889 * Free memory allocated by @a wm. 890 * 891 * @param[in] wm wire method to free 892 */ 893 void 894 TMH_wire_method_free (struct TMH_WireMethod *wm); 895 896 897 /** 898 * Lookup a merchant instance by its instance ID. 899 * 900 * @param instance_id identifier of the instance to resolve 901 * @return NULL if that instance is unknown to us 902 */ 903 struct TMH_MerchantInstance * 904 TMH_lookup_instance (const char *instance_id); 905 906 907 /** 908 * A transaction modified an instance setting 909 * (or created/deleted/purged one). Notify all 910 * backends about the change. 911 * 912 * @param id ID of the instance that changed 913 */ 914 void 915 TMH_reload_instances (const char *id); 916 917 918 #endif