LCOV - code coverage report
Current view: top level - lib - merchant_api_common.c (source / functions) Hit Total Coverage
Test: GNU Taler merchant coverage report Lines: 113 175 64.6 %
Date: 2022-08-25 06:17:04 Functions: 4 6 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2020 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_common.c
      19             :  * @brief Implementation of common logic for libtalermerchant
      20             :  * @author Christian Grothoff
      21             :  */
      22             : #include "platform.h"
      23             : #include <curl/curl.h>
      24             : #include "taler_merchant_service.h"
      25             : #include <gnunet/gnunet_uri_lib.h>
      26             : #include <taler/taler_json_lib.h>
      27             : 
      28             : 
      29             : void
      30           0 : TALER_MERCHANT_parse_error_details_ (const json_t *response,
      31             :                                      unsigned int http_status,
      32             :                                      struct TALER_MERCHANT_HttpResponse *hr)
      33             : {
      34             :   const json_t *jc;
      35             : 
      36           0 :   memset (hr, 0, sizeof (*hr));
      37           0 :   hr->reply = response;
      38           0 :   hr->http_status = http_status;
      39           0 :   if (NULL == response)
      40             :   {
      41           0 :     hr->ec = TALER_EC_GENERIC_INVALID_RESPONSE;
      42           0 :     return;
      43             :   }
      44           0 :   hr->ec = TALER_JSON_get_error_code (response);
      45           0 :   hr->hint = TALER_JSON_get_error_hint (response);
      46             : 
      47             :   /* handle 'exchange_http_status' */
      48           0 :   jc = json_object_get (response,
      49             :                         "exchange_http_status");
      50             :   /* The caller already knows that the JSON represents an error,
      51             :      so we are dealing with a missing error code here.  */
      52           0 :   if (NULL == jc)
      53           0 :     return; /* no need to bother with exchange_code/hint if we had no status */
      54           0 :   if (! json_is_integer (jc))
      55             :   {
      56           0 :     GNUNET_break_op (0);
      57           0 :     return;
      58             :   }
      59           0 :   hr->exchange_http_status = (unsigned int) json_integer_value (jc);
      60             : 
      61             :   /* handle 'exchange_reply' */
      62           0 :   jc = json_object_get (response,
      63             :                         "exchange_reply");
      64           0 :   if (! json_is_object (jc))
      65             :   {
      66           0 :     GNUNET_break_op (0);
      67             :   }
      68             :   else
      69             :   {
      70           0 :     hr->exchange_reply = jc;
      71             :   }
      72             : 
      73             :   /* handle 'exchange_code' */
      74           0 :   jc = json_object_get (response,
      75             :                         "exchange_code");
      76             :   /* The caller already knows that the JSON represents an error,
      77             :      so we are dealing with a missing error code here.  */
      78           0 :   if (NULL == jc)
      79           0 :     return; /* no need to bother with exchange-hint if we had no code */
      80           0 :   if (! json_is_integer (jc))
      81             :   {
      82           0 :     GNUNET_break_op (0);
      83           0 :     hr->exchange_code = TALER_EC_INVALID;
      84             :   }
      85             :   else
      86             :   {
      87           0 :     hr->exchange_code = (enum TALER_ErrorCode) json_integer_value (jc);
      88             :   }
      89             : 
      90             :   /* handle 'exchange-hint' */
      91           0 :   jc = json_object_get (response,
      92             :                         "exchange-hint");
      93             :   /* The caller already knows that the JSON represents an error,
      94             :      so we are dealing with a missing error code here.  */
      95           0 :   if (NULL == jc)
      96           0 :     return;
      97           0 :   if (! json_is_string (jc))
      98             :   {
      99           0 :     GNUNET_break_op (0);
     100             :   }
     101             :   else
     102             :   {
     103           0 :     hr->exchange_hint = json_string_value (jc);
     104             :   }
     105             : }
     106             : 
     107             : 
     108             : char *
     109           0 : TALER_MERCHANT_baseurl_add_instance (const char *base_url,
     110             :                                      const char *instance_id)
     111             : {
     112             :   char *ret;
     113             :   bool end_sl;
     114             : 
     115           0 :   if ('\0' == *base_url)
     116             :   {
     117           0 :     GNUNET_break (0);
     118           0 :     return NULL;
     119             :   }
     120           0 :   end_sl = '/' == base_url[strlen (base_url) - 1];
     121             : 
     122           0 :   GNUNET_asprintf (&ret,
     123             :                    (end_sl)
     124             :                    ? "%sinstances/%s/"
     125             :                    : "%s/instances/%s/",
     126             :                    base_url,
     127             :                    instance_id);
     128           0 :   return ret;
     129             : }
     130             : 
     131             : 
     132             : int
     133           7 : TALER_MERCHANT_parse_pay_uri (const char *pay_uri,
     134             :                               struct TALER_MERCHANT_PayUriData *parse_data)
     135             : {
     136           7 :   char *cp = GNUNET_strdup (pay_uri);
     137             :   struct GNUNET_Uri u;
     138             : 
     139           7 :   if (0 !=
     140           7 :       GNUNET_uri_parse (&u,
     141             :                         cp))
     142             :   {
     143           0 :     GNUNET_free (cp);
     144           0 :     GNUNET_break_op (0);
     145           0 :     return GNUNET_SYSERR;
     146             :   }
     147           7 :   if ((0 != strcasecmp ("taler",
     148           7 :                         u.scheme)) &&
     149           3 :       (0 != strcasecmp ("taler+http",
     150           3 :                         u.scheme)))
     151             :   {
     152           1 :     fprintf (stderr,
     153             :              "Bad schema %s\n",
     154             :              u.scheme);
     155           1 :     GNUNET_free (cp);
     156           1 :     GNUNET_break_op (0);
     157           1 :     return GNUNET_SYSERR;
     158             :   }
     159           6 :   parse_data->use_http = (0 == strcasecmp ("taler+http",
     160           6 :                                            u.scheme));
     161           6 :   if (0 != strcasecmp ("pay",
     162           6 :                        u.host))
     163             :   {
     164           1 :     GNUNET_break_op (0);
     165           1 :     GNUNET_free (cp);
     166           1 :     return GNUNET_SYSERR;
     167             :   }
     168             : 
     169             :   {
     170             :     char *order_id;
     171             :     char *mpp;
     172           5 :     char *session_id = strrchr (u.path,
     173             :                                 '/');
     174           5 :     struct TALER_ClaimTokenP *claim_token = NULL;
     175             : 
     176           5 :     if (NULL == session_id)
     177             :     {
     178           0 :       GNUNET_break_op (0);
     179           0 :       GNUNET_free (cp);
     180           0 :       return GNUNET_SYSERR;
     181             :     }
     182           5 :     *session_id = '\0';
     183           5 :     ++session_id;
     184             : 
     185           5 :     order_id = strrchr (u.path,
     186             :                         '/');
     187           5 :     if (NULL == order_id)
     188             :     {
     189           1 :       GNUNET_break_op (0);
     190           1 :       GNUNET_free (cp);
     191           1 :       return GNUNET_SYSERR;
     192             :     }
     193           4 :     *order_id = '\0';
     194           4 :     ++order_id;
     195           4 :     mpp = strchr (u.path,
     196             :                   '/');
     197           4 :     if (NULL != mpp)
     198             :     {
     199           1 :       *mpp = '\0';
     200           1 :       ++mpp;
     201             :     }
     202             : 
     203             :     {
     204           4 :       char *ct_str = u.query;
     205             :       char *ct_data;
     206             : 
     207           4 :       if (NULL != ct_str)
     208             :       {
     209           1 :         ct_data = strchr (u.query,
     210             :                           '=');
     211           1 :         if (NULL == ct_data)
     212             :         {
     213           0 :           GNUNET_break_op (0);
     214           0 :           GNUNET_free (cp);
     215           0 :           return GNUNET_SYSERR;
     216             :         }
     217           1 :         *ct_data = '\0';
     218           1 :         ++ct_data;
     219           1 :         claim_token = GNUNET_new (struct TALER_ClaimTokenP);
     220           1 :         if ( (0 != strcmp ("c",
     221           2 :                            u.query)) ||
     222             :              (GNUNET_OK !=
     223           1 :               GNUNET_STRINGS_string_to_data (ct_data,
     224             :                                              strlen (ct_data),
     225             :                                              claim_token,
     226             :                                              sizeof (*claim_token))) )
     227             :         {
     228           0 :           GNUNET_break_op (0);
     229           0 :           GNUNET_free (claim_token);
     230           0 :           GNUNET_free (cp);
     231           0 :           return GNUNET_SYSERR;
     232             :         }
     233             :       }
     234             :     }
     235             : 
     236             :     parse_data->merchant_prefix_path
     237           4 :       = (NULL == mpp)
     238             :         ? NULL
     239           4 :         : GNUNET_strdup (mpp);
     240           4 :     parse_data->merchant_host = GNUNET_strdup (u.path);
     241           4 :     parse_data->order_id = GNUNET_strdup (order_id);
     242             :     parse_data->session_id
     243           8 :       = (0 < strlen (session_id))
     244           2 :         ? GNUNET_strdup (session_id)
     245           4 :         : NULL;
     246           4 :     parse_data->claim_token = claim_token;
     247             :     parse_data->ssid
     248           8 :       = (NULL == u.fragment)
     249             :         ? NULL
     250           4 :         : GNUNET_strdup (u.fragment);
     251             :   }
     252           4 :   GNUNET_free (cp);
     253           4 :   return GNUNET_OK;
     254             : }
     255             : 
     256             : 
     257             : void
     258           4 : TALER_MERCHANT_parse_pay_uri_free (
     259             :   struct TALER_MERCHANT_PayUriData *parse_data)
     260             : {
     261           4 :   GNUNET_free (parse_data->merchant_host);
     262           4 :   GNUNET_free (parse_data->merchant_prefix_path);
     263           4 :   GNUNET_free (parse_data->order_id);
     264           4 :   GNUNET_free (parse_data->session_id);
     265           4 :   GNUNET_free (parse_data->claim_token);
     266           4 :   GNUNET_free (parse_data->ssid);
     267           4 : }
     268             : 
     269             : 
     270             : int
     271           5 : TALER_MERCHANT_parse_refund_uri (
     272             :   const char *refund_uri,
     273             :   struct TALER_MERCHANT_RefundUriData *parse_data)
     274             : {
     275           5 :   char *cp = GNUNET_strdup (refund_uri);
     276             :   struct GNUNET_Uri u;
     277             : 
     278           5 :   if (0 !=
     279           5 :       GNUNET_uri_parse (&u,
     280             :                         cp))
     281             :   {
     282           0 :     GNUNET_free (cp);
     283           0 :     GNUNET_break_op (0);
     284           0 :     return GNUNET_SYSERR;
     285             :   }
     286           5 :   if ((0 != strcasecmp ("taler",
     287           5 :                         u.scheme)) &&
     288           2 :       (0 != strcasecmp ("taler+http",
     289           2 :                         u.scheme)))
     290             :   {
     291           1 :     GNUNET_free (cp);
     292           1 :     GNUNET_break_op (0);
     293           1 :     return GNUNET_SYSERR;
     294             :   }
     295           4 :   parse_data->use_http = (0 == strcasecmp ("taler+http",
     296           4 :                                            u.scheme));
     297             : 
     298           4 :   if (0 != strcasecmp ("refund",
     299           4 :                        u.host))
     300             :   {
     301           1 :     GNUNET_break_op (0);
     302           1 :     GNUNET_free (cp);
     303           1 :     return GNUNET_SYSERR;
     304             :   }
     305             : 
     306             :   {
     307             :     char *order_id;
     308           3 :     char *last_seg = strrchr (u.path,
     309             :                               '/');
     310             : 
     311           3 :     if (NULL == last_seg)
     312             :     {
     313           0 :       GNUNET_break_op (0);
     314           0 :       GNUNET_free (cp);
     315           0 :       return GNUNET_SYSERR;
     316             :     }
     317           3 :     *last_seg = '\0';
     318           3 :     ++last_seg;
     319             : 
     320           3 :     order_id = strrchr (u.path,
     321             :                         '/');
     322           3 :     if (NULL == order_id)
     323             :     {
     324           1 :       GNUNET_break_op (0);
     325           1 :       GNUNET_free (cp);
     326           1 :       return GNUNET_SYSERR;
     327             :     }
     328           2 :     *order_id = '\0';
     329           2 :     ++order_id;
     330           2 :     if (0 != strlen (last_seg))
     331             :     {
     332           0 :       GNUNET_break_op (0);
     333           0 :       GNUNET_free (cp);
     334           0 :       return GNUNET_SYSERR;
     335             :     }
     336             : 
     337             :     {
     338             :       char *mpp;
     339             : 
     340           2 :       mpp = strchr (u.path,
     341             :                     '/');
     342           2 :       if (NULL != mpp)
     343             :       {
     344           1 :         *mpp = '\0';
     345           1 :         ++mpp;
     346             :       }
     347             : 
     348             :       parse_data->merchant_prefix_path
     349           2 :         = (NULL == mpp)
     350             :           ? NULL
     351           2 :           : GNUNET_strdup (mpp);
     352             :     }
     353           2 :     parse_data->merchant_host = GNUNET_strdup (u.path);
     354           2 :     parse_data->order_id = GNUNET_strdup (order_id);
     355             :     parse_data->ssid
     356           4 :       = (NULL == u.fragment)
     357             :         ? NULL
     358           2 :         : GNUNET_strdup (u.fragment);
     359             :   }
     360           2 :   GNUNET_free (cp);
     361           2 :   return GNUNET_OK;
     362             : }
     363             : 
     364             : 
     365             : void
     366           2 : TALER_MERCHANT_parse_refund_uri_free (
     367             :   struct TALER_MERCHANT_RefundUriData *parse_data)
     368             : {
     369           2 :   GNUNET_free (parse_data->merchant_host);
     370           2 :   GNUNET_free (parse_data->merchant_prefix_path);
     371           2 :   GNUNET_free (parse_data->order_id);
     372           2 :   GNUNET_free (parse_data->ssid);
     373           2 : }

Generated by: LCOV version 1.14