merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_claim_order.c (7974B)


      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
      6   it under the terms of the GNU General Public License as
      7   published by the Free Software Foundation; either version 3, or
      8   (at your option) any later version.
      9 
     10   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, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 
     20 /**
     21  * @file testing_api_cmd_claim_order.c
     22  * @brief command to claim an order
     23  * @author Marcello Stanisci
     24  */
     25 #include "platform.h"
     26 #include <taler/taler_exchange_service.h>
     27 #include <taler/taler_testing_lib.h>
     28 #include "taler_merchant_service.h"
     29 #include "taler_merchant_testing_lib.h"
     30 
     31 /**
     32  * State for a "order claim" CMD.  Not used by
     33  * the initial claim operation.
     34  */
     35 struct OrderClaimState
     36 {
     37   /**
     38    * The interpreter state.
     39    */
     40   struct TALER_TESTING_Interpreter *is;
     41 
     42   /**
     43    * URL of the merchant backend.
     44    */
     45   const char *merchant_url;
     46 
     47   /**
     48    * Contract terms we downloaded. Only set if we got #MHD_HTTP_OK.
     49    */
     50   json_t *contract_terms;
     51 
     52   /**
     53    * Hash over the contract terms. Only set if we got #MHD_HTTP_OK.
     54    */
     55   struct TALER_PrivateContractHashP contract_terms_hash;
     56 
     57   /**
     58    * Signature of the merchant. Only set if we got #MHD_HTTP_OK.
     59    */
     60   struct TALER_MerchantSignatureP merchant_sig;
     61 
     62   /**
     63    * Public key of the merchant. Only set if we got #MHD_HTTP_OK.
     64    */
     65   struct TALER_MerchantPublicKeyP merchant_pub;
     66 
     67   /**
     68    * Expected status code.
     69    */
     70   unsigned int http_status;
     71 
     72   /**
     73    * /order/claim operation handle.
     74    */
     75   struct TALER_MERCHANT_OrderClaimHandle *och;
     76 
     77   /**
     78    * Reference to a order operation.  Will offer the
     79    * nonce for the operation.
     80    */
     81   const char *order_reference;
     82 
     83   /**
     84    * Order id to claim upon.  If null, the @a order_reference
     85    * will offer this value.
     86    */
     87   const char *order_id;
     88 };
     89 
     90 
     91 /**
     92  * Free the state of a "order claim" CMD, and possibly
     93  * cancel it if it did not complete.
     94  *
     95  * @param cls closure.
     96  * @param cmd command being freed.
     97  */
     98 static void
     99 order_claim_cleanup (void *cls,
    100                      const struct TALER_TESTING_Command *cmd)
    101 {
    102   struct OrderClaimState *pls = cls;
    103 
    104   if (NULL != pls->och)
    105   {
    106     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    107                 "Command '%s' did not complete\n",
    108                 cmd->label);
    109     TALER_MERCHANT_order_claim_cancel (pls->och);
    110     pls->och = NULL;
    111   }
    112   if (NULL != pls->contract_terms)
    113   {
    114     json_decref (pls->contract_terms);
    115     pls->contract_terms = NULL;
    116   }
    117   GNUNET_free (pls);
    118 }
    119 
    120 
    121 /**
    122  * Callback for "order claim" operation, to check the
    123  * response code is as expected.
    124  *
    125  * @param cls closure
    126  * @param ocr response we got
    127  */
    128 static void
    129 order_claim_cb (void *cls,
    130                 const struct TALER_MERCHANT_OrderClaimResponse *ocr)
    131 {
    132   struct OrderClaimState *pls = cls;
    133 
    134   pls->och = NULL;
    135   if (pls->http_status != ocr->hr.http_status)
    136     TALER_TESTING_FAIL (pls->is);
    137   if (MHD_HTTP_OK == ocr->hr.http_status)
    138   {
    139     pls->contract_terms
    140       = json_incref ((json_t *) ocr->details.ok.contract_terms);
    141     pls->contract_terms_hash = ocr->details.ok.h_contract_terms;
    142     pls->merchant_sig = ocr->details.ok.sig;
    143     {
    144       const char *error_name;
    145       unsigned int error_line;
    146       struct GNUNET_JSON_Specification spec[] = {
    147         GNUNET_JSON_spec_fixed_auto ("merchant_pub",
    148                                      &pls->merchant_pub),
    149         GNUNET_JSON_spec_end ()
    150       };
    151 
    152       if (GNUNET_OK !=
    153           GNUNET_JSON_parse (pls->contract_terms,
    154                              spec,
    155                              &error_name,
    156                              &error_line))
    157         TALER_TESTING_FAIL (pls->is);
    158     }
    159   }
    160   TALER_TESTING_interpreter_next (pls->is);
    161 }
    162 
    163 
    164 /**
    165  * Run the "order claim" CMD.
    166  *
    167  * @param cls closure.
    168  * @param cmd command currently being run.
    169  * @param is interpreter state.
    170  */
    171 static void
    172 order_claim_run (void *cls,
    173                  const struct TALER_TESTING_Command *cmd,
    174                  struct TALER_TESTING_Interpreter *is)
    175 {
    176   struct OrderClaimState *pls = cls;
    177   const char *order_id;
    178   const struct GNUNET_CRYPTO_EddsaPublicKey *nonce;
    179   /* Only used if we do NOT use the nonce/token from traits.  */
    180   struct GNUNET_CRYPTO_EddsaPublicKey dummy_nonce;
    181   const struct TALER_ClaimTokenP *claim_token;
    182 
    183   pls->is = is;
    184   if (NULL != pls->order_id)
    185   {
    186     order_id = pls->order_id;
    187     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
    188                                 &dummy_nonce,
    189                                 sizeof (dummy_nonce));
    190     nonce = &dummy_nonce;
    191     claim_token = NULL;
    192   }
    193   else
    194   {
    195     const struct TALER_TESTING_Command *order_cmd;
    196 
    197     order_cmd
    198       = TALER_TESTING_interpreter_lookup_command (is,
    199                                                   pls->order_reference);
    200     if (NULL == order_cmd)
    201       TALER_TESTING_FAIL (is);
    202     if (GNUNET_OK !=
    203         TALER_TESTING_get_trait_claim_nonce (order_cmd,
    204                                              &nonce))
    205     {
    206       GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
    207                                   &dummy_nonce,
    208                                   sizeof (dummy_nonce));
    209       nonce = &dummy_nonce;
    210     }
    211     if (GNUNET_OK !=
    212         TALER_TESTING_get_trait_claim_token (order_cmd,
    213                                              &claim_token))
    214       claim_token = NULL;
    215     if (GNUNET_OK !=
    216         TALER_TESTING_get_trait_order_id (order_cmd,
    217                                           &order_id))
    218       TALER_TESTING_FAIL (is);
    219   }
    220   pls->och = TALER_MERCHANT_order_claim (TALER_TESTING_interpreter_get_context (
    221                                            is),
    222                                          pls->merchant_url,
    223                                          order_id,
    224                                          nonce,
    225                                          claim_token,
    226                                          &order_claim_cb,
    227                                          pls);
    228   if (NULL == pls->och)
    229     TALER_TESTING_FAIL (is);
    230 }
    231 
    232 
    233 /**
    234  * Offer internal data to other commands.
    235  *
    236  * @param cls closure
    237  * @param[out] ret result (could be anything)
    238  * @param trait name of the trait
    239  * @param index index number of the object to extract.
    240  * @return #GNUNET_OK on success
    241  */
    242 static enum GNUNET_GenericReturnValue
    243 order_claim_traits (void *cls,
    244                     const void **ret,
    245                     const char *trait,
    246                     unsigned int index)
    247 {
    248   struct OrderClaimState *pls = cls;
    249 
    250   struct TALER_TESTING_Trait traits[] = {
    251     TALER_TESTING_make_trait_contract_terms (pls->contract_terms),
    252     TALER_TESTING_make_trait_h_contract_terms (&pls->contract_terms_hash),
    253     TALER_TESTING_make_trait_merchant_sig (&pls->merchant_sig),
    254     TALER_TESTING_make_trait_merchant_pub (&pls->merchant_pub),
    255     TALER_TESTING_trait_end ()
    256   };
    257 
    258   return TALER_TESTING_get_trait (traits,
    259                                   ret,
    260                                   trait,
    261                                   index);
    262 }
    263 
    264 
    265 struct TALER_TESTING_Command
    266 TALER_TESTING_cmd_merchant_claim_order (
    267   const char *label,
    268   const char *merchant_url,
    269   unsigned int http_status,
    270   const char *order_reference,
    271   const char *order_id)
    272 {
    273   struct OrderClaimState *pls;
    274 
    275   pls = GNUNET_new (struct OrderClaimState);
    276   pls->http_status = http_status;
    277   pls->order_reference = order_reference;
    278   pls->merchant_url = merchant_url;
    279   pls->order_id = order_id;
    280   {
    281     struct TALER_TESTING_Command cmd = {
    282       .cls = pls,
    283       .label = label,
    284       .run = &order_claim_run,
    285       .cleanup = &order_claim_cleanup,
    286       .traits = &order_claim_traits
    287     };
    288 
    289     return cmd;
    290   }
    291 }