LCOV - code coverage report
Current view: top level - backend - taler-merchant-httpd_get-tips-ID.c (source / functions) Hit Total Coverage
Test: GNU Taler merchant coverage report Lines: 0 91 0.0 %
Date: 2022-08-25 06:17:04 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   (C) 2014-2021 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify it under the
       6             :   terms of the GNU Affero General Public License as published by the Free Software
       7             :   Foundation; either version 3, 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 General Public License for more details.
      12             : 
      13             :   You should have received a copy of the GNU General Public License along with
      14             :   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
      15             : */
      16             : /**
      17             :  * @file taler-merchant-httpd_get-tips-ID.c
      18             :  * @brief implementation of GET /tips/$ID
      19             :  * @author Marcello Stanisci
      20             :  * @author Christian Grothoff
      21             :  */
      22             : #include "platform.h"
      23             : #include <jansson.h>
      24             : #include <taler/taler_signatures.h>
      25             : #include <taler/taler_json_lib.h>
      26             : #include <taler/taler_templating_lib.h>
      27             : #include "taler-merchant-httpd_get-tips-ID.h"
      28             : #include "taler-merchant-httpd_mhd.h"
      29             : #include "taler-merchant-httpd_qr.h"
      30             : 
      31             : 
      32             : char *
      33           0 : TMH_make_taler_tip_uri (struct MHD_Connection *con,
      34             :                         const struct TALER_TipIdentifierP *tip_id,
      35             :                         const char *instance_id)
      36             : {
      37             :   const char *host;
      38             :   const char *forwarded_host;
      39             :   const char *uri_path;
      40           0 :   struct GNUNET_Buffer buf = { 0 };
      41             : 
      42           0 :   host = MHD_lookup_connection_value (con,
      43             :                                       MHD_HEADER_KIND,
      44             :                                       "Host");
      45           0 :   forwarded_host = MHD_lookup_connection_value (con,
      46             :                                                 MHD_HEADER_KIND,
      47             :                                                 "X-Forwarded-Host");
      48             : 
      49           0 :   uri_path = MHD_lookup_connection_value (con,
      50             :                                           MHD_HEADER_KIND,
      51             :                                           "X-Forwarded-Prefix");
      52           0 :   if (NULL != forwarded_host)
      53           0 :     host = forwarded_host;
      54             : 
      55           0 :   if (NULL == host)
      56             :   {
      57           0 :     GNUNET_break (0);
      58           0 :     return NULL;
      59             :   }
      60             : 
      61           0 :   GNUNET_assert (NULL != instance_id);
      62           0 :   GNUNET_assert (NULL != tip_id);
      63             : 
      64           0 :   GNUNET_buffer_write_str (&buf,
      65             :                            "taler");
      66           0 :   if (GNUNET_NO == TALER_mhd_is_https (con))
      67           0 :     GNUNET_buffer_write_str (&buf,
      68             :                              "+http");
      69           0 :   GNUNET_buffer_write_str (&buf,
      70             :                            "://tip/");
      71           0 :   GNUNET_buffer_write_str (&buf,
      72             :                            host);
      73           0 :   if (NULL != uri_path)
      74           0 :     GNUNET_buffer_write_path (&buf,
      75             :                               uri_path);
      76           0 :   if (0 != strcmp ("default",
      77             :                    instance_id))
      78             :   {
      79           0 :     GNUNET_buffer_write_path (&buf,
      80             :                               "instances");
      81           0 :     GNUNET_buffer_write_path (&buf,
      82             :                               instance_id);
      83             :   }
      84             :   /* Ensure previous part is slash-terminated */
      85           0 :   GNUNET_buffer_write_path (&buf,
      86             :                             "");
      87           0 :   GNUNET_buffer_write_data_encoded (&buf,
      88             :                                     tip_id,
      89             :                                     sizeof (*tip_id));
      90           0 :   return GNUNET_buffer_reap_str (&buf);
      91             : }
      92             : 
      93             : 
      94             : char *
      95           0 : TMH_make_tip_status_url (struct MHD_Connection *con,
      96             :                          const struct TALER_TipIdentifierP *tip_id,
      97             :                          const char *instance_id)
      98             : {
      99             :   const char *host;
     100             :   const char *forwarded_host;
     101             :   const char *uri_path;
     102           0 :   struct GNUNET_Buffer buf = { 0 };
     103             : 
     104           0 :   host = MHD_lookup_connection_value (con,
     105             :                                       MHD_HEADER_KIND,
     106             :                                       "Host");
     107           0 :   forwarded_host = MHD_lookup_connection_value (con,
     108             :                                                 MHD_HEADER_KIND,
     109             :                                                 "X-Forwarded-Host");
     110             : 
     111           0 :   uri_path = MHD_lookup_connection_value (con,
     112             :                                           MHD_HEADER_KIND,
     113             :                                           "X-Forwarded-Prefix");
     114           0 :   if (NULL != forwarded_host)
     115           0 :     host = forwarded_host;
     116             : 
     117           0 :   if (NULL == host)
     118             :   {
     119           0 :     GNUNET_break (0);
     120           0 :     return NULL;
     121             :   }
     122             : 
     123           0 :   GNUNET_assert (NULL != instance_id);
     124           0 :   GNUNET_assert (NULL != tip_id);
     125             : 
     126           0 :   if (GNUNET_NO == TALER_mhd_is_https (con))
     127           0 :     GNUNET_buffer_write_str (&buf,
     128             :                              "http://");
     129             :   else
     130           0 :     GNUNET_buffer_write_str (&buf,
     131             :                              "https://");
     132           0 :   GNUNET_buffer_write_str (&buf,
     133             :                            host);
     134           0 :   if (NULL != uri_path)
     135           0 :     GNUNET_buffer_write_path (&buf,
     136             :                               uri_path);
     137           0 :   if (0 != strcmp ("default",
     138             :                    instance_id))
     139             :   {
     140           0 :     GNUNET_buffer_write_path (&buf,
     141             :                               "instances");
     142           0 :     GNUNET_buffer_write_path (&buf,
     143             :                               instance_id);
     144             :   }
     145           0 :   GNUNET_buffer_write_path (&buf,
     146             :                             "tips/");
     147           0 :   GNUNET_buffer_write_data_encoded (&buf,
     148             :                                     tip_id,
     149             :                                     sizeof (*tip_id));
     150           0 :   return GNUNET_buffer_reap_str (&buf);
     151             : }
     152             : 
     153             : 
     154             : MHD_RESULT
     155           0 : TMH_get_tips_ID (const struct TMH_RequestHandler *rh,
     156             :                  struct MHD_Connection *connection,
     157             :                  struct TMH_HandlerContext *hc)
     158             : {
     159             :   struct TALER_TipIdentifierP tip_id;
     160             :   enum GNUNET_DB_QueryStatus qs;
     161             :   struct TALER_Amount total_authorized;
     162             :   struct TALER_Amount total_picked_up;
     163             :   struct GNUNET_TIME_Timestamp expiration;
     164             :   char *exchange_url;
     165             :   struct TALER_ReservePrivateKeyP reserve_priv;
     166             : 
     167             :   (void) rh;
     168           0 :   if (GNUNET_OK !=
     169           0 :       GNUNET_CRYPTO_hash_from_string (hc->infix,
     170             :                                       &tip_id.hash))
     171             :   {
     172             :     /* tip_id has wrong encoding */
     173           0 :     GNUNET_break_op (0);
     174           0 :     return TALER_MHD_reply_with_error (connection,
     175             :                                        MHD_HTTP_BAD_REQUEST,
     176             :                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     177           0 :                                        hc->infix);
     178             :   }
     179             : 
     180           0 :   TMH_db->preflight (TMH_db->cls);
     181           0 :   qs = TMH_db->lookup_tip (TMH_db->cls,
     182           0 :                            hc->instance->settings.id,
     183             :                            &tip_id,
     184             :                            &total_authorized,
     185             :                            &total_picked_up,
     186             :                            &expiration,
     187             :                            &exchange_url,
     188             :                            &reserve_priv);
     189           0 :   if (0 > qs)
     190             :   {
     191             :     /* single, read-only SQL statements should never cause
     192             :        serialization problems */
     193           0 :     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
     194             :     /* Always report on hard error as well to enable diagnostics */
     195           0 :     GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
     196           0 :     return TALER_MHD_reply_with_error (connection,
     197             :                                        MHD_HTTP_INTERNAL_SERVER_ERROR,
     198             :                                        TALER_EC_GENERIC_DB_FETCH_FAILED,
     199             :                                        NULL);
     200             :   }
     201           0 :   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
     202             :   {
     203           0 :     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     204             :                 "Unknown tip id given: `%s'\n",
     205             :                 hc->infix);
     206           0 :     return TALER_MHD_reply_with_error (connection,
     207             :                                        MHD_HTTP_NOT_FOUND,
     208             :                                        TALER_EC_MERCHANT_GENERIC_TIP_ID_UNKNOWN,
     209           0 :                                        hc->infix);
     210             :   }
     211             : 
     212             :   /* Build response */
     213             :   {
     214             :     struct TALER_Amount remaining;
     215             :     MHD_RESULT ret;
     216             : 
     217           0 :     GNUNET_break (0 <=
     218             :                   TALER_amount_subtract (&remaining,
     219             :                                          &total_authorized,
     220             :                                          &total_picked_up));
     221           0 :     if (TMH_MHD_test_html_desired (connection))
     222             :     {
     223             :       char *qr;
     224             :       char *uri;
     225             :       char *tip_status_url;
     226             : 
     227           0 :       uri = TMH_make_taler_tip_uri (connection,
     228             :                                     &tip_id,
     229           0 :                                     hc->instance->settings.id);
     230           0 :       tip_status_url = TMH_make_tip_status_url (connection,
     231             :                                                 &tip_id,
     232           0 :                                                 hc->instance->settings.id);
     233           0 :       qr = TMH_create_qrcode (uri);
     234           0 :       if (NULL == qr)
     235             :       {
     236           0 :         GNUNET_break (0);
     237           0 :         GNUNET_free (uri);
     238           0 :         ret = TALER_MHD_reply_with_error (connection,
     239             :                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
     240             :                                           TALER_EC_GENERIC_ALLOCATION_FAILURE,
     241             :                                           "during QR code generation");
     242             :       }
     243             :       else
     244             :       {
     245             :         json_t *context;
     246             : 
     247           0 :         context = GNUNET_JSON_PACK (
     248             :           TALER_JSON_pack_amount ("remaining_tip",
     249             :                                   &remaining),
     250             :           GNUNET_JSON_pack_string ("taler_tip_uri",
     251             :                                    uri),
     252             :           GNUNET_JSON_pack_string ("taler_tip_qrcode_svg",
     253             :                                    qr));
     254           0 :         ret = TALER_TEMPLATING_reply (connection,
     255           0 :                                       ( (0 == remaining.value) &&
     256           0 :                                         (0 == remaining.fraction) )
     257             :                                         ? MHD_HTTP_GONE
     258             :                                         : MHD_HTTP_OK,
     259           0 :                                       ( (0 == remaining.value) &&
     260           0 :                                         (0 == remaining.fraction) )
     261             :                                         ? "depleted_tip"
     262             :                                         : "offer_tip",
     263           0 :                                       hc->instance->settings.id,
     264             :                                       uri,
     265             :                                       context);
     266           0 :         json_decref (context);
     267             :       }
     268           0 :       GNUNET_free (tip_status_url);
     269           0 :       GNUNET_free (uri);
     270           0 :       GNUNET_free (qr);
     271             :     }
     272             :     else
     273             :     {
     274           0 :       ret = TALER_MHD_REPLY_JSON_PACK (
     275             :         connection,
     276             :         TALER_amount_is_zero (&remaining)
     277             :         ? MHD_HTTP_GONE
     278             :         : MHD_HTTP_OK,
     279             :         GNUNET_JSON_pack_string ("exchange_url",
     280             :                                  exchange_url),
     281             :         TALER_JSON_pack_amount ("tip_amount",
     282             :                                 &remaining),
     283             :         GNUNET_JSON_pack_timestamp ("expiration",
     284             :                                     expiration));
     285             :     }
     286           0 :     GNUNET_free (exchange_url);
     287           0 :     return ret;
     288             :   }
     289             : }
     290             : 
     291             : 
     292             : /* end of taler-merchant-httpd_get-tips-ID.c */

Generated by: LCOV version 1.14