taler-merchant-httpd_private-delete-instances-ID-token.c (5981B)
1 /* 2 This file is part of GNU Taler 3 (C) 2023 Taler Systems SA 4 5 GNU 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 GNU 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 taler-merchant-httpd_private-post-instances-ID-token.c 22 * @brief implementing DELETE /instances/$ID/token request handling 23 * @author Christian Grothoff 24 */ 25 #include "platform.h" 26 #include "taler-merchant-httpd_private-delete-instances-ID-token.h" 27 #include "taler-merchant-httpd_helper.h" 28 #include <taler/taler_json_lib.h> 29 30 31 MHD_RESULT 32 TMH_private_delete_instances_ID_token_SERIAL (const struct TMH_RequestHandler * 33 rh, 34 struct MHD_Connection *connection, 35 struct TMH_HandlerContext *hc) 36 { 37 struct TMH_MerchantInstance *mi = hc->instance; 38 enum GNUNET_DB_QueryStatus qs; 39 unsigned long long serial; 40 char dummy; 41 42 GNUNET_assert (NULL != mi); 43 GNUNET_assert (NULL != hc->infix); 44 if (1 != sscanf (hc->infix, 45 "%llu%c", 46 &serial, 47 &dummy)) 48 { 49 GNUNET_break_op (0); 50 return TALER_MHD_reply_with_error (connection, 51 MHD_HTTP_BAD_REQUEST, 52 TALER_EC_GENERIC_PARAMETER_MALFORMED, 53 "serial must be a number"); 54 } 55 56 57 qs = TMH_db->delete_login_token_serial (TMH_db->cls, 58 mi->settings.id, 59 serial); 60 switch (qs) 61 { 62 case GNUNET_DB_STATUS_HARD_ERROR: 63 case GNUNET_DB_STATUS_SOFT_ERROR: 64 GNUNET_break (0); 65 return TALER_MHD_reply_with_ec (connection, 66 TALER_EC_GENERIC_DB_STORE_FAILED, 67 "delete_login_token_by_serial"); 68 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: 69 return TALER_MHD_reply_with_error (connection, 70 MHD_HTTP_NOT_FOUND, 71 TALER_EC_MERCHANT_GENERIC_CATEGORY_UNKNOWN, 72 hc->infix); 73 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: 74 return TALER_MHD_reply_static (connection, 75 MHD_HTTP_NO_CONTENT, 76 NULL, 77 NULL, 78 0); 79 } 80 GNUNET_break (0); 81 return MHD_NO; 82 } 83 84 85 MHD_RESULT 86 TMH_private_delete_instances_ID_token (const struct TMH_RequestHandler *rh, 87 struct MHD_Connection *connection, 88 struct TMH_HandlerContext *hc) 89 { 90 const char *bearer = "Bearer "; 91 struct TMH_MerchantInstance *mi = hc->instance; 92 const char *tok; 93 struct TALER_MERCHANTDB_LoginTokenP btoken; 94 enum GNUNET_DB_QueryStatus qs; 95 96 tok = MHD_lookup_connection_value (connection, 97 MHD_HEADER_KIND, 98 MHD_HTTP_HEADER_AUTHORIZATION); 99 /* This was presumably checked before... */ 100 if (0 != 101 strncmp (tok, 102 bearer, 103 strlen (bearer))) 104 { 105 GNUNET_break_op (0); 106 return TALER_MHD_reply_with_ec (connection, 107 TALER_EC_GENERIC_PARAMETER_MALFORMED, 108 "login token (in 'Authorization' header)"); 109 } 110 tok += strlen (bearer); 111 while (' ' == *tok) 112 tok++; 113 if (0 != strncasecmp (tok, 114 RFC_8959_PREFIX, 115 strlen (RFC_8959_PREFIX))) 116 { 117 GNUNET_break_op (0); 118 return TALER_MHD_reply_with_ec (connection, 119 TALER_EC_GENERIC_PARAMETER_MALFORMED, 120 "login token (in 'Authorization' header)"); 121 } 122 tok += strlen (RFC_8959_PREFIX); 123 124 if (GNUNET_OK != 125 GNUNET_STRINGS_string_to_data (tok, 126 strlen (tok), 127 &btoken, 128 sizeof (btoken))) 129 { 130 GNUNET_break_op (0); 131 return TALER_MHD_reply_with_ec (connection, 132 TALER_EC_GENERIC_PARAMETER_MALFORMED, 133 "login token (in 'Authorization' header)"); 134 } 135 qs = TMH_db->delete_login_token (TMH_db->cls, 136 mi->settings.id, 137 &btoken); 138 switch (qs) 139 { 140 case GNUNET_DB_STATUS_HARD_ERROR: 141 case GNUNET_DB_STATUS_SOFT_ERROR: 142 GNUNET_break (0); 143 return TALER_MHD_reply_with_ec (connection, 144 TALER_EC_GENERIC_DB_STORE_FAILED, 145 "delete_login_token"); 146 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: 147 /* No 404, as the login token must have existed 148 when we got the request as it was accepted as 149 valid. So we can only get here due to concurrent 150 modification, and then the client should still 151 simply see the success. Hence, fall-through */ 152 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: 153 return TALER_MHD_reply_static (connection, 154 MHD_HTTP_NO_CONTENT, 155 NULL, 156 NULL, 157 0); 158 } 159 GNUNET_break (0); 160 return MHD_NO; 161 } 162 163 164 /* end of taler-merchant-httpd_private-delete-instances-ID-login.c */