merchant

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

merchant_api_post_donau_instance.c (6239B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2024 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU Lesser General Public License as
      7   published by the Free Software Foundation; either version 2.1,
      8   or (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful,
     11   but WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU Lesser General Public License for more details.
     14 
     15   You should have received a copy of the GNU Lesser General
     16   Public License along with TALER; see the file COPYING.LGPL.
     17   If not, see <http://www.gnu.org/licenses/>
     18 */
     19 /**
     20  * @file merchant_api_post_donau_instance.c
     21  * @brief Implementation of the POST /donau request
     22  *        of the merchant's HTTP API
     23  * @author Bohdan Potuzhnyi
     24  * @author Vlada Svirsh
     25  */
     26 #include "platform.h"
     27 #include <curl/curl.h>
     28 #include <jansson.h>
     29 #include <microhttpd.h> /* just for HTTP status codes */
     30 #include <gnunet/gnunet_util_lib.h>
     31 #include "taler_merchant_service.h"
     32 #include "merchant_api_curl_defaults.h"
     33 #include "merchant_api_common.h"
     34 #include <taler/taler_json_lib.h>
     35 #include <taler/taler_signatures.h>
     36 #include <taler/taler_curl_lib.h>
     37 #include <taler/taler_kyclogic_lib.h>
     38 /* DONAU RELATED IMPORTS */
     39 #include "taler_merchant_donau.h"
     40 #include <donau/donau_service.h>
     41 
     42 
     43 /**
     44  * Handle for a POST /donau operation.
     45  */
     46 struct TALER_MERCHANT_DonauInstancePostHandle
     47 {
     48   /**
     49    * URL for this request.
     50    */
     51   char *url;
     52 
     53   /**
     54    * Handle for the CURL job.
     55    */
     56   struct GNUNET_CURL_Job *job;
     57 
     58   /**
     59    * Function to call with the result.
     60    */
     61   TALER_MERCHANT_DonauInstancePostCallback cb;
     62 
     63   /**
     64    * Closure for @a cb.
     65    */
     66   void *cb_cls;
     67 
     68   /**
     69    * Reference to the execution context.
     70    */
     71   struct GNUNET_CURL_Context *ctx;
     72 
     73   /**
     74    * Minor context that holds body and headers.
     75    */
     76   struct TALER_CURL_PostContext post_ctx;
     77 };
     78 
     79 
     80 /**
     81  * Function called when the POST /donau operation is finished.
     82  *
     83  * @param cls the `struct TALER_MERCHANT_DonauInstancePostHandle`
     84  * @param response_code HTTP response code, 0 on error
     85  * @param response response body, NULL if not in JSON
     86  */
     87 static void
     88 handle_post_donau_finished (void *cls,
     89                             long response_code,
     90                             const void *response)
     91 {
     92   struct TALER_MERCHANT_DonauInstancePostHandle *dph = cls;
     93   const json_t *json = response;
     94   struct TALER_MERCHANT_HttpResponse hr = {
     95     .http_status = (unsigned int) response_code,
     96     .reply = json
     97   };
     98 
     99   dph->job = NULL;
    100   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    101               "POST /donau completed with response code %u\n",
    102               (unsigned int) response_code);
    103 
    104   switch (response_code)
    105   {
    106   case 0:
    107     hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
    108     break;
    109   case MHD_HTTP_NO_CONTENT:
    110     break;
    111   case MHD_HTTP_BAD_REQUEST:
    112   case MHD_HTTP_INTERNAL_SERVER_ERROR:
    113   default:
    114     TALER_MERCHANT_parse_error_details_ (json,
    115                                          response_code,
    116                                          &hr);
    117     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    118                 "Unexpected response code %u/%d\n",
    119                 (unsigned int) response_code,
    120                 (int) hr.ec);
    121     break;
    122   }
    123 
    124   dph->cb (dph->cb_cls,
    125            &hr);
    126   TALER_MERCHANT_donau_instances_post_cancel (dph);
    127 }
    128 
    129 
    130 struct TALER_MERCHANT_DonauInstancePostHandle *
    131 TALER_MERCHANT_donau_instances_post (
    132   struct GNUNET_CURL_Context *ctx,
    133   const char *backend_url,
    134   const struct TALER_MERCHANT_DONAU_Charity *charity,
    135   const char *auth_token,
    136   TALER_MERCHANT_DonauInstancePostCallback cb,
    137   void *cb_cls)
    138 {
    139   struct TALER_MERCHANT_DonauInstancePostHandle *dph;
    140   json_t *req_obj;
    141   json_t *auth_obj;
    142 
    143   if (NULL != auth_token)
    144   {
    145     if (0 != strncasecmp (RFC_8959_PREFIX,
    146                           auth_token,
    147                           strlen (RFC_8959_PREFIX)))
    148     {
    149       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    150                   "Authentication token must start with `%s'\n",
    151                   RFC_8959_PREFIX);
    152       return NULL;
    153     }
    154     auth_obj = GNUNET_JSON_PACK (
    155       GNUNET_JSON_pack_string ("method",
    156                                "token"),
    157       GNUNET_JSON_pack_string ("token",
    158                                auth_token));
    159   }
    160   else
    161   {
    162     auth_obj = GNUNET_JSON_PACK (
    163       GNUNET_JSON_pack_string ("method",
    164                                "external"));
    165   }
    166   if (NULL == auth_obj)
    167   {
    168     GNUNET_break (0);
    169     return NULL;
    170   }
    171 
    172   req_obj = GNUNET_JSON_PACK (
    173     GNUNET_JSON_pack_string ("donau_url",
    174                              charity->charity_url),
    175     GNUNET_JSON_pack_uint64 ("charity_id",
    176                              charity->charity_id)
    177     );
    178 
    179   dph = GNUNET_new (struct TALER_MERCHANT_DonauInstancePostHandle);
    180   dph->ctx = ctx;
    181   dph->cb = cb;
    182   dph->cb_cls = cb_cls;
    183   dph->url = TALER_url_join (backend_url,
    184                              "private/donau",
    185                              NULL);
    186 
    187   if (NULL == dph->url)
    188   {
    189     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    190                 "Failed to construct request URL\n");
    191     json_decref (req_obj);
    192     GNUNET_free (dph);
    193     return NULL;
    194   }
    195   {
    196     CURL *eh;
    197 
    198     eh = TALER_MERCHANT_curl_easy_get_ (dph->url);
    199     if (GNUNET_OK != TALER_curl_easy_post (&dph->post_ctx,
    200                                            eh,
    201                                            req_obj))
    202     {
    203       GNUNET_break (0);
    204       curl_easy_cleanup (eh);
    205       json_decref (req_obj);
    206       GNUNET_free (dph);
    207       return NULL;
    208     }
    209 
    210     json_decref (req_obj);
    211 
    212     dph->job = GNUNET_CURL_job_add2 (ctx,
    213                                      eh,
    214                                      dph->post_ctx.headers,
    215                                      &handle_post_donau_finished,
    216                                      dph);
    217   }
    218   return dph;
    219 }
    220 
    221 
    222 void
    223 TALER_MERCHANT_donau_instances_post_cancel (
    224   struct TALER_MERCHANT_DonauInstancePostHandle *dph)
    225 {
    226   if (NULL != dph->job)
    227   {
    228     GNUNET_CURL_job_cancel (dph->job);
    229     dph->job = NULL;
    230   }
    231   TALER_curl_easy_post_finished (&dph->post_ctx);
    232   GNUNET_free (dph->url);
    233   GNUNET_free (dph);
    234 }
    235 
    236 
    237 /* end of merchant_api_post_donau_instance.c */