From 26d5adb7e9ea120b356f40b444f410973c8a83d4 Mon Sep 17 00:00:00 2001 From: Jonathan Buchanan Date: Wed, 10 Jun 2020 01:44:32 -0400 Subject: implementation of GET /private/tips --- .../taler-merchant-httpd_private-get-tips.c | 182 +++++++++++++++++++++ 1 file changed, 182 insertions(+) (limited to 'src/backend/taler-merchant-httpd_private-get-tips.c') diff --git a/src/backend/taler-merchant-httpd_private-get-tips.c b/src/backend/taler-merchant-httpd_private-get-tips.c index f874f5b5..a98bd110 100644 --- a/src/backend/taler-merchant-httpd_private-get-tips.c +++ b/src/backend/taler-merchant-httpd_private-get-tips.c @@ -18,3 +18,185 @@ * @brief implementation of a GET /private/tips handler * @author Jonathan Buchanan */ +#include "platform.h" +#include "taler-merchant-httpd_private-get-tips.h" + + +/** + * Add tip details to our JSON array. + * + * @param[in,out] cls a `json_t *` JSON array to build + * @param row_id row number of the tip + * @param tip_id ID of the tip + * @param amount the amount of the tip + */ +static void +add_tip (void *cls, + uint64_t row_id, + struct GNUNET_HashCode tip_id, + struct TALER_Amount amount) +{ + json_t *pa = cls; + + GNUNET_assert (0 == + json_array_append_new ( + pa, + json_pack ( + "{s:I, s:o, s:o}", + "row_id", + row_id, + "tip_id", + GNUNET_JSON_from_data_auto (&tip_id), + "amount", + TALER_JSON_from_amount (&amount)))); +} + + +/** + * Convert query argument to @a yna value. + * + * @param connection connection to take query argument from + * @param arg argument to try for + * @param[out] value to set + * @return true on success, false if the parameter was malformed + */ +static bool +arg_to_yna (struct MHD_Connection *connection, + const char *arg, + enum TALER_MERCHANTDB_YesNoAll *yna) +{ + const char *str; + + str = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + arg); + if (NULL == str) + { + *yna = TALER_MERCHANTDB_YNA_NO; + return true; + } + if (0 == strcasecmp (str, "yes")) + { + *yna = TALER_MERCHANTDB_YNA_YES; + return true; + } + if (0 == strcasecmp (str, "no")) + { + *yna = TALER_MERCHANTDB_YNA_NO; + return true; + } + if (0 == strcasecmp (str, "all")) + { + *yna = TALER_MERCHANTDB_YNA_ALL; + return true; + } + return false; +} + + +/** + * Handle a GET "/tips/$ID" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param[in,out] hc context with further information about the request + * @return MHD result code + */ +MHD_RESULT +TMH_private_get_tips (const struct TMH_RequestHandler *rh, + struct MHD_Connection *connection, + struct TMH_HandlerContext *hc) +{ + json_t *pa; + enum GNUNET_DB_QueryStatus qs; + enum TALER_MERCHANTDB_YesNoAll expired; + uint64_t offset; + int64_t limit; + + if (! (arg_to_yna (connection, /* TODO: put this method in a header somewhere */ + "expired", + &expired)) ) + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_PARAMETER_MALFORMED, + "expired"); + { + const char *offset_str; + + offset_str = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "offset"); + if (NULL == offset_str) + { + offset = UINT64_MAX; + } + else + { + char dummy[2]; + unsigned long long ull; + + if (1 != + sscanf (offset_str, + "%llu%1s", + &ull, + dummy)) + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_PARAMETER_MALFORMED, + "date"); + offset = (uint64_t) ull; + } + } + { + const char *limit_str; + + limit_str = MHD_lookup_connection_value (connection, + MHD_GET_ARGUMENT_KIND, + "limit"); + if (NULL == limit_str) + { + limit = -20; + } + else + { + char dummy[2]; + long long ll; + + if (1 != + sscanf (limit_str, + "%lld%1s", + &ll, + dummy)) + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + TALER_EC_PARAMETER_MALFORMED, + "limit"); + limit = (uint64_t) ll; + } + } + + pa = json_array (); + GNUNET_assert (NULL != pa); + qs = TMH_db->lookup_tips (TMH_db->cls, + hc->instance->settings.id, + expired, + limit, + offset, + &add_tip, + pa); + + if (0 > qs) + { + GNUNET_break (0); + json_decref (pa); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_ORDERS_GET_DB_LOOKUP_ERROR, + "failed to lookup tips in database"); + } + + return TALER_MHD_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o}", + "tips", pa); +} -- cgit v1.2.3