merchant

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

merchant_api_get-private-accounts-H_WIRE.c (7100B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2022-2026 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Lesser General Public License as published by the Free Software
      7   Foundation; either version 2.1, 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 Lesser General Public License for more details.
     12 
     13   You should have received a copy of the GNU Lesser General Public License along with
     14   TALER; see the file COPYING.LGPL.  If not, see
     15   <http://www.gnu.org/licenses/>
     16 */
     17 /**
     18  * @file merchant_api_get-private-accounts-H_WIRE-new.c
     19  * @brief Implementation of the GET /private/accounts/$H_WIRE request
     20  * @author Christian Grothoff
     21  */
     22 #include "taler/platform.h"
     23 #include <curl/curl.h>
     24 #include <jansson.h>
     25 #include <microhttpd.h> /* just for HTTP status codes */
     26 #include <gnunet/gnunet_util_lib.h>
     27 #include <gnunet/gnunet_curl_lib.h>
     28 #include <taler/taler-merchant/get-private-accounts-H_WIRE.h>
     29 #include "merchant_api_curl_defaults.h"
     30 #include <taler/taler_json_lib.h>
     31 
     32 
     33 /**
     34  * Handle for a GET /private/accounts/$H_WIRE operation.
     35  */
     36 struct TALER_MERCHANT_GetPrivateAccountHandle
     37 {
     38   /**
     39    * Base URL of the merchant backend.
     40    */
     41   char *base_url;
     42 
     43   /**
     44    * Instance identifier.
     45    */
     46   char *instance_id;
     47 
     48   /**
     49    * Hash of the wire details identifying the account.
     50    */
     51   struct TALER_MerchantWireHashP h_wire;
     52 
     53   /**
     54    * The full URL for this request.
     55    */
     56   char *url;
     57 
     58   /**
     59    * Handle for the request.
     60    */
     61   struct GNUNET_CURL_Job *job;
     62 
     63   /**
     64    * Function to call with the result.
     65    */
     66   TALER_MERCHANT_GetPrivateAccountCallback cb;
     67 
     68   /**
     69    * Closure for @a cb.
     70    */
     71   TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls;
     72 
     73   /**
     74    * Reference to the execution context.
     75    */
     76   struct GNUNET_CURL_Context *ctx;
     77 };
     78 
     79 
     80 /**
     81  * Function called when we're done processing the
     82  * HTTP GET /private/accounts/$H_WIRE request.
     83  *
     84  * @param cls the `struct TALER_MERCHANT_GetPrivateAccountHandle`
     85  * @param response_code HTTP response code, 0 on error
     86  * @param response response body, NULL if not in JSON
     87  */
     88 static void
     89 handle_get_account_finished (void *cls,
     90                              long response_code,
     91                              const void *response)
     92 {
     93   struct TALER_MERCHANT_GetPrivateAccountHandle *gpa = cls;
     94   const json_t *json = response;
     95   struct TALER_MERCHANT_GetPrivateAccountResponse agr = {
     96     .hr.http_status = (unsigned int) response_code,
     97     .hr.reply = json
     98   };
     99 
    100   gpa->job = NULL;
    101   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    102               "Got /private/accounts/$H_WIRE response with status code %u\n",
    103               (unsigned int) response_code);
    104   switch (response_code)
    105   {
    106   case MHD_HTTP_OK:
    107     {
    108       struct GNUNET_JSON_Specification spec[] = {
    109         GNUNET_JSON_spec_fixed_auto ("salt",
    110                                      &agr.details.ok.ad.salt),
    111         GNUNET_JSON_spec_mark_optional (
    112           TALER_JSON_spec_web_url ("credit_facade_url",
    113                                    &agr.details.ok.ad.credit_facade_url),
    114           NULL),
    115         TALER_JSON_spec_full_payto_uri ("payto_uri",
    116                                         &agr.details.ok.ad.payto_uri),
    117         GNUNET_JSON_spec_fixed_auto ("h_wire",
    118                                      &agr.details.ok.ad.h_wire),
    119         GNUNET_JSON_spec_bool ("active",
    120                                &agr.details.ok.ad.active),
    121         GNUNET_JSON_spec_mark_optional (
    122           GNUNET_JSON_spec_object_const (
    123             "extra_wire_subject_metadata",
    124             &agr.details.ok.ad.extra_wire_subject_metadata),
    125           NULL),
    126         GNUNET_JSON_spec_end ()
    127       };
    128 
    129       if (GNUNET_OK ==
    130           GNUNET_JSON_parse (json,
    131                              spec,
    132                              NULL, NULL))
    133       {
    134         gpa->cb (gpa->cb_cls,
    135                  &agr);
    136         TALER_MERCHANT_get_private_account_cancel (gpa);
    137         return;
    138       }
    139       agr.hr.http_status = 0;
    140       agr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
    141       break;
    142     }
    143   case MHD_HTTP_UNAUTHORIZED:
    144     agr.hr.ec = TALER_JSON_get_error_code (json);
    145     agr.hr.hint = TALER_JSON_get_error_hint (json);
    146     break;
    147   case MHD_HTTP_NOT_FOUND:
    148     agr.hr.ec = TALER_JSON_get_error_code (json);
    149     agr.hr.hint = TALER_JSON_get_error_hint (json);
    150     break;
    151   default:
    152     agr.hr.ec = TALER_JSON_get_error_code (json);
    153     agr.hr.hint = TALER_JSON_get_error_hint (json);
    154     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    155                 "Unexpected response code %u/%d\n",
    156                 (unsigned int) response_code,
    157                 (int) agr.hr.ec);
    158     break;
    159   }
    160   gpa->cb (gpa->cb_cls,
    161            &agr);
    162   TALER_MERCHANT_get_private_account_cancel (gpa);
    163 }
    164 
    165 
    166 struct TALER_MERCHANT_GetPrivateAccountHandle *
    167 TALER_MERCHANT_get_private_account_create (
    168   struct GNUNET_CURL_Context *ctx,
    169   const char *url,
    170   const char *instance_id,
    171   const struct TALER_MerchantWireHashP *h_wire)
    172 {
    173   struct TALER_MERCHANT_GetPrivateAccountHandle *gpa;
    174 
    175   gpa = GNUNET_new (struct TALER_MERCHANT_GetPrivateAccountHandle);
    176   gpa->ctx = ctx;
    177   gpa->base_url = GNUNET_strdup (url);
    178   gpa->instance_id = GNUNET_strdup (instance_id);
    179   gpa->h_wire = *h_wire;
    180   return gpa;
    181 }
    182 
    183 
    184 enum TALER_ErrorCode
    185 TALER_MERCHANT_get_private_account_start (
    186   struct TALER_MERCHANT_GetPrivateAccountHandle *gpa,
    187   TALER_MERCHANT_GetPrivateAccountCallback cb,
    188   TALER_MERCHANT_GET_PRIVATE_ACCOUNT_RESULT_CLOSURE *cb_cls)
    189 {
    190   CURL *eh;
    191 
    192   gpa->cb = cb;
    193   gpa->cb_cls = cb_cls;
    194   {
    195     char w_str[sizeof (gpa->h_wire) * 2];
    196     char *path;
    197     char *end;
    198 
    199     end = GNUNET_STRINGS_data_to_string (&gpa->h_wire,
    200                                          sizeof (gpa->h_wire),
    201                                          w_str,
    202                                          sizeof (w_str));
    203     *end = '\0';
    204     GNUNET_asprintf (&path,
    205                      "private/accounts/%s",
    206                      w_str);
    207     gpa->url = TALER_url_join (gpa->base_url,
    208                                path,
    209                                NULL);
    210     GNUNET_free (path);
    211   }
    212   if (NULL == gpa->url)
    213     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
    214   eh = TALER_MERCHANT_curl_easy_get_ (gpa->url);
    215   if (NULL == eh)
    216     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
    217   gpa->job = GNUNET_CURL_job_add (gpa->ctx,
    218                                   eh,
    219                                   &handle_get_account_finished,
    220                                   gpa);
    221   if (NULL == gpa->job)
    222     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
    223   return TALER_EC_NONE;
    224 }
    225 
    226 
    227 void
    228 TALER_MERCHANT_get_private_account_cancel (
    229   struct TALER_MERCHANT_GetPrivateAccountHandle *gpa)
    230 {
    231   if (NULL != gpa->job)
    232   {
    233     GNUNET_CURL_job_cancel (gpa->job);
    234     gpa->job = NULL;
    235   }
    236   GNUNET_free (gpa->url);
    237   GNUNET_free (gpa->instance_id);
    238   GNUNET_free (gpa->base_url);
    239   GNUNET_free (gpa);
    240 }
    241 
    242 
    243 /* end of merchant_api_get-private-accounts-H_WIRE-new.c */