merchant

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

testing_api_cmd_claim_order.c (8156B)


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