LCOV - code coverage report
Current view: top level - exchange - taler-exchange-httpd_responses.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 16 64 25.0 %
Date: 2025-07-03 11:36:01 Functions: 7 12 58.3 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2014-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 taler-exchange-httpd_responses.c
      18             :  * @brief API for generating generic replies of the exchange; these
      19             :  *        functions are called TEH_RESPONSE_reply_ and they generate
      20             :  *        and queue MHD response objects for a given connection.
      21             :  * @author Florian Dold
      22             :  * @author Benedikt Mueller
      23             :  * @author Christian Grothoff
      24             :  */
      25             : #include "taler/platform.h"
      26             : #include <gnunet/gnunet_json_lib.h>
      27             : #include <microhttpd.h>
      28             : #include <zlib.h>
      29             : #include "taler-exchange-httpd_responses.h"
      30             : #include "taler/taler_exchangedb_plugin.h"
      31             : #include "taler/taler_util.h"
      32             : #include "taler/taler_json_lib.h"
      33             : #include "taler/taler_mhd_lib.h"
      34             : #include "taler-exchange-httpd_keys.h"
      35             : 
      36             : 
      37             : MHD_RESULT
      38           0 : TEH_RESPONSE_reply_unknown_denom_pub_hash (
      39             :   struct MHD_Connection *connection,
      40             :   const struct TALER_DenominationHashP *dph)
      41             : {
      42             :   struct TALER_ExchangePublicKeyP epub;
      43             :   struct TALER_ExchangeSignatureP esig;
      44             :   struct GNUNET_TIME_Timestamp now;
      45             :   enum TALER_ErrorCode ec;
      46             : 
      47           0 :   now = GNUNET_TIME_timestamp_get ();
      48           0 :   ec = TALER_exchange_online_denomination_unknown_sign (
      49             :     &TEH_keys_exchange_sign_,
      50             :     now,
      51             :     dph,
      52             :     &epub,
      53             :     &esig);
      54           0 :   if (TALER_EC_NONE != ec)
      55             :   {
      56           0 :     GNUNET_break (0);
      57           0 :     return TALER_MHD_reply_with_error (connection,
      58             :                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
      59             :                                        ec,
      60             :                                        NULL);
      61             :   }
      62           0 :   return TALER_MHD_REPLY_JSON_PACK (
      63             :     connection,
      64             :     MHD_HTTP_NOT_FOUND,
      65             :     TALER_JSON_pack_ec (TALER_EC_EXCHANGE_GENERIC_DENOMINATION_KEY_UNKNOWN),
      66             :     GNUNET_JSON_pack_timestamp ("timestamp",
      67             :                                 now),
      68             :     GNUNET_JSON_pack_data_auto ("exchange_pub",
      69             :                                 &epub),
      70             :     GNUNET_JSON_pack_data_auto ("exchange_sig",
      71             :                                 &esig),
      72             :     GNUNET_JSON_pack_data_auto ("h_denom_pub",
      73             :                                 dph));
      74             : }
      75             : 
      76             : 
      77             : MHD_RESULT
      78           0 : TEH_RESPONSE_reply_expired_denom_pub_hash (
      79             :   struct MHD_Connection *connection,
      80             :   const struct TALER_DenominationHashP *dph,
      81             :   enum TALER_ErrorCode ec,
      82             :   const char *oper)
      83             : {
      84             :   struct TALER_ExchangePublicKeyP epub;
      85             :   struct TALER_ExchangeSignatureP esig;
      86             :   enum TALER_ErrorCode ecr;
      87             :   struct GNUNET_TIME_Timestamp now
      88           0 :     = GNUNET_TIME_timestamp_get ();
      89             : 
      90           0 :   GNUNET_assert (NULL != oper);
      91           0 :   ecr = TALER_exchange_online_denomination_expired_sign (
      92             :     &TEH_keys_exchange_sign_,
      93             :     now,
      94             :     dph,
      95             :     oper,
      96             :     &epub,
      97             :     &esig);
      98           0 :   if (TALER_EC_NONE != ecr)
      99             :   {
     100           0 :     GNUNET_break (0);
     101           0 :     return TALER_MHD_reply_with_error (connection,
     102             :                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
     103             :                                        ec,
     104             :                                        NULL);
     105             :   }
     106           0 :   return TALER_MHD_REPLY_JSON_PACK (
     107             :     connection,
     108             :     MHD_HTTP_GONE,
     109             :     TALER_JSON_pack_ec (ec),
     110             :     GNUNET_JSON_pack_string ("oper",
     111             :                              oper),
     112             :     GNUNET_JSON_pack_timestamp ("timestamp",
     113             :                                 now),
     114             :     GNUNET_JSON_pack_data_auto ("exchange_pub",
     115             :                                 &epub),
     116             :     GNUNET_JSON_pack_data_auto ("exchange_sig",
     117             :                                 &esig),
     118             :     GNUNET_JSON_pack_data_auto ("h_denom_pub",
     119             :                                 dph));
     120             : }
     121             : 
     122             : 
     123             : MHD_RESULT
     124           0 : TEH_RESPONSE_reply_invalid_denom_cipher_for_operation (
     125             :   struct MHD_Connection *connection,
     126             :   const struct TALER_DenominationHashP *dph)
     127             : {
     128             :   struct TALER_ExchangePublicKeyP epub;
     129             :   struct TALER_ExchangeSignatureP esig;
     130             :   struct GNUNET_TIME_Timestamp now;
     131             :   enum TALER_ErrorCode ec;
     132             : 
     133           0 :   now = GNUNET_TIME_timestamp_get ();
     134           0 :   ec = TALER_exchange_online_denomination_unknown_sign (
     135             :     &TEH_keys_exchange_sign_,
     136             :     now,
     137             :     dph,
     138             :     &epub,
     139             :     &esig);
     140           0 :   if (TALER_EC_NONE != ec)
     141             :   {
     142           0 :     GNUNET_break (0);
     143           0 :     return TALER_MHD_reply_with_error (connection,
     144             :                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
     145             :                                        ec,
     146             :                                        NULL);
     147             :   }
     148           0 :   return TALER_MHD_REPLY_JSON_PACK (
     149             :     connection,
     150             :     MHD_HTTP_NOT_FOUND,
     151             :     TALER_JSON_pack_ec (
     152             :       TALER_EC_EXCHANGE_GENERIC_INVALID_DENOMINATION_CIPHER_FOR_OPERATION),
     153             :     GNUNET_JSON_pack_timestamp ("timestamp",
     154             :                                 now),
     155             :     GNUNET_JSON_pack_data_auto ("exchange_pub",
     156             :                                 &epub),
     157             :     GNUNET_JSON_pack_data_auto ("exchange_sig",
     158             :                                 &esig),
     159             :     GNUNET_JSON_pack_data_auto ("h_denom_pub",
     160             :                                 dph));
     161             : }
     162             : 
     163             : 
     164             : MHD_RESULT
     165          23 : TEH_RESPONSE_reply_coin_insufficient_funds (
     166             :   struct MHD_Connection *connection,
     167             :   enum TALER_ErrorCode ec,
     168             :   const struct TALER_DenominationHashP *h_denom_pub,
     169             :   const struct TALER_CoinSpendPublicKeyP *coin_pub)
     170             : {
     171          23 :   return TALER_MHD_REPLY_JSON_PACK (
     172             :     connection,
     173             :     TALER_ErrorCode_get_http_status_safe (ec),
     174             :     TALER_JSON_pack_ec (ec),
     175             :     GNUNET_JSON_pack_data_auto ("coin_pub",
     176             :                                 coin_pub),
     177             :     // FIXME - #7267: to be kept only for some of the error types!
     178             :     GNUNET_JSON_pack_data_auto ("h_denom_pub",
     179             :                                 h_denom_pub));
     180             : }
     181             : 
     182             : 
     183             : MHD_RESULT
     184           4 : TEH_RESPONSE_reply_coin_conflicting_contract (
     185             :   struct MHD_Connection *connection,
     186             :   enum TALER_ErrorCode ec,
     187             :   const struct TALER_MerchantWireHashP *h_wire)
     188             : {
     189           4 :   return TALER_MHD_REPLY_JSON_PACK (
     190             :     connection,
     191             :     TALER_ErrorCode_get_http_status_safe (ec),
     192             :     GNUNET_JSON_pack_data_auto ("h_wire",
     193             :                                 h_wire),
     194             :     TALER_JSON_pack_ec (ec));
     195             : }
     196             : 
     197             : 
     198             : MHD_RESULT
     199           2 : TEH_RESPONSE_reply_coin_denomination_conflict (
     200             :   struct MHD_Connection *connection,
     201             :   enum TALER_ErrorCode ec,
     202             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     203             :   const struct TALER_DenominationPublicKey *prev_denom_pub,
     204             :   const struct TALER_DenominationSignature *prev_denom_sig)
     205             : {
     206           2 :   return TALER_MHD_REPLY_JSON_PACK (
     207             :     connection,
     208             :     TALER_ErrorCode_get_http_status_safe (ec),
     209             :     TALER_JSON_pack_ec (ec),
     210             :     GNUNET_JSON_pack_data_auto ("coin_pub",
     211             :                                 coin_pub),
     212             :     TALER_JSON_pack_denom_pub ("prev_denom_pub",
     213             :                                prev_denom_pub),
     214             :     TALER_JSON_pack_denom_sig ("prev_denom_sig",
     215             :                                prev_denom_sig)
     216             :     );
     217             : 
     218             : }
     219             : 
     220             : 
     221             : MHD_RESULT
     222           0 : TEH_RESPONSE_reply_coin_age_commitment_conflict (
     223             :   struct MHD_Connection *connection,
     224             :   enum TALER_ErrorCode ec,
     225             :   enum TALER_EXCHANGEDB_CoinKnownStatus status,
     226             :   const struct TALER_DenominationHashP *h_denom_pub,
     227             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     228             :   const struct TALER_AgeCommitmentHashP *h_age_commitment)
     229             : {
     230             :   const char *conflict_detail;
     231             : 
     232           0 :   switch (status)
     233             :   {
     234             : 
     235           0 :   case TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NULL:
     236           0 :     conflict_detail = "expected NULL age commitment hash";
     237           0 :     h_age_commitment = NULL;
     238           0 :     break;
     239           0 :   case TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NON_NULL:
     240           0 :     conflict_detail = "expected non-NULL age commitment hash";
     241           0 :     break;
     242           0 :   case TALER_EXCHANGEDB_CKS_AGE_CONFLICT_VALUE_DIFFERS:
     243           0 :     conflict_detail = "expected age commitment hash differs";
     244           0 :     break;
     245           0 :   default:
     246           0 :     GNUNET_assert (0);
     247             :   }
     248             : 
     249           0 :   return TALER_MHD_REPLY_JSON_PACK (
     250             :     connection,
     251             :     TALER_ErrorCode_get_http_status_safe (ec),
     252             :     TALER_JSON_pack_ec (ec),
     253             :     GNUNET_JSON_pack_data_auto ("coin_pub",
     254             :                                 coin_pub),
     255             :     GNUNET_JSON_pack_data_auto ("h_denom_pub",
     256             :                                 h_denom_pub),
     257             :     GNUNET_JSON_pack_allow_null (
     258             :       GNUNET_JSON_pack_data_auto ("expected_age_commitment_hash",
     259             :                                   h_age_commitment)),
     260             :     GNUNET_JSON_pack_string ("conflict_detail",
     261             :                              conflict_detail)
     262             :     );
     263             : }
     264             : 
     265             : 
     266             : MHD_RESULT
     267           3 : TEH_RESPONSE_reply_reserve_insufficient_balance (
     268             :   struct MHD_Connection *connection,
     269             :   enum TALER_ErrorCode ec,
     270             :   const struct TALER_Amount *reserve_balance,
     271             :   const struct TALER_Amount *balance_required,
     272             :   const struct TALER_ReservePublicKeyP *reserve_pub)
     273             : {
     274           3 :   return TALER_MHD_REPLY_JSON_PACK (
     275             :     connection,
     276             :     MHD_HTTP_CONFLICT,
     277             :     TALER_JSON_pack_ec (ec),
     278             :     TALER_JSON_pack_amount ("balance",
     279             :                             reserve_balance),
     280             :     TALER_JSON_pack_amount ("requested_amount",
     281             :                             balance_required));
     282             : }
     283             : 
     284             : 
     285             : MHD_RESULT
     286           2 : TEH_RESPONSE_reply_reserve_age_restriction_required (
     287             :   struct MHD_Connection *connection,
     288             :   uint16_t maximum_allowed_age)
     289             : {
     290           2 :   return TALER_MHD_REPLY_JSON_PACK (
     291             :     connection,
     292             :     MHD_HTTP_CONFLICT,
     293             :     TALER_JSON_pack_ec (TALER_EC_EXCHANGE_RESERVES_AGE_RESTRICTION_REQUIRED),
     294             :     GNUNET_JSON_pack_uint64 ("maximum_allowed_age",
     295             :                              maximum_allowed_age));
     296             : }
     297             : 
     298             : 
     299             : MHD_RESULT
     300          20 : TEH_RESPONSE_reply_purse_created (
     301             :   struct MHD_Connection *connection,
     302             :   struct GNUNET_TIME_Timestamp exchange_timestamp,
     303             :   const struct TALER_Amount *purse_balance,
     304             :   const struct TEH_PurseDetails *pd)
     305             : {
     306             :   struct TALER_ExchangePublicKeyP pub;
     307             :   struct TALER_ExchangeSignatureP sig;
     308             :   enum TALER_ErrorCode ec;
     309             : 
     310          20 :   if (TALER_EC_NONE !=
     311          20 :       (ec = TALER_exchange_online_purse_created_sign (
     312             :          &TEH_keys_exchange_sign_,
     313             :          exchange_timestamp,
     314             :          pd->purse_expiration,
     315             :          &pd->target_amount,
     316             :          purse_balance,
     317             :          &pd->purse_pub,
     318             :          &pd->h_contract_terms,
     319             :          &pub,
     320             :          &sig)))
     321             :   {
     322           0 :     GNUNET_break (0);
     323           0 :     return TALER_MHD_reply_with_ec (connection,
     324             :                                     ec,
     325             :                                     NULL);
     326             :   }
     327          20 :   return TALER_MHD_REPLY_JSON_PACK (
     328             :     connection,
     329             :     MHD_HTTP_OK,
     330             :     TALER_JSON_pack_amount ("total_deposited",
     331             :                             purse_balance),
     332             :     GNUNET_JSON_pack_timestamp ("exchange_timestamp",
     333             :                                 exchange_timestamp),
     334             :     GNUNET_JSON_pack_data_auto ("exchange_sig",
     335             :                                 &sig),
     336             :     GNUNET_JSON_pack_data_auto ("exchange_pub",
     337             :                                 &pub));
     338             : }
     339             : 
     340             : 
     341             : MHD_RESULT
     342          18 : TEH_RESPONSE_reply_kyc_required (
     343             :   struct MHD_Connection *connection,
     344             :   const struct TALER_NormalizedPaytoHashP *h_payto,
     345             :   const struct TALER_EXCHANGEDB_KycStatus *kyc,
     346             :   bool bad_kyc_auth)
     347             : {
     348          18 :   return TALER_MHD_REPLY_JSON_PACK (
     349             :     connection,
     350             :     MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS,
     351             :     TALER_JSON_pack_ec (TALER_EC_EXCHANGE_GENERIC_KYC_REQUIRED),
     352             :     GNUNET_JSON_pack_data_auto ("h_payto",
     353             :                                 h_payto),
     354             :     GNUNET_JSON_pack_allow_null (
     355             :       GNUNET_JSON_pack_data_auto (
     356             :         "account_pub",
     357             :         (kyc->have_account_pub
     358             :         ? &kyc->account_pub
     359             :          : NULL))),
     360             :     GNUNET_JSON_pack_allow_null (
     361             :       bad_kyc_auth
     362             :       ? GNUNET_JSON_pack_bool ("bad_kyc_auth",
     363             :                                bad_kyc_auth)
     364             :       : GNUNET_JSON_pack_string ("bad_kyc_auth",
     365             :                                  NULL)),
     366             :     GNUNET_JSON_pack_uint64 ("requirement_row",
     367             :                              kyc->requirement_row));
     368             : }
     369             : 
     370             : 
     371             : MHD_RESULT
     372           0 : TEH_RESPONSE_reply_not_modified (
     373             :   struct MHD_Connection *connection,
     374             :   const char *etags,
     375             :   TEH_RESPONSE_SetHeaders cb,
     376             :   void *cb_cls)
     377             : {
     378             :   MHD_RESULT ret;
     379             :   struct MHD_Response *resp;
     380             : 
     381           0 :   resp = MHD_create_response_from_buffer (0,
     382             :                                           NULL,
     383             :                                           MHD_RESPMEM_PERSISTENT);
     384           0 :   if (NULL != cb)
     385           0 :     cb (cb_cls,
     386             :         resp);
     387           0 :   GNUNET_break (MHD_YES ==
     388             :                 MHD_add_response_header (resp,
     389             :                                          MHD_HTTP_HEADER_ETAG,
     390             :                                          etags));
     391           0 :   ret = MHD_queue_response (connection,
     392             :                             MHD_HTTP_NOT_MODIFIED,
     393             :                             resp);
     394           0 :   GNUNET_break (MHD_YES == ret);
     395           0 :   MHD_destroy_response (resp);
     396           0 :   return ret;
     397             : }
     398             : 
     399             : 
     400             : /* end of taler-exchange-httpd_responses.c */

Generated by: LCOV version 1.16