summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_get-rewards-ID.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/taler-merchant-httpd_get-rewards-ID.c')
-rw-r--r--src/backend/taler-merchant-httpd_get-rewards-ID.c235
1 files changed, 235 insertions, 0 deletions
diff --git a/src/backend/taler-merchant-httpd_get-rewards-ID.c b/src/backend/taler-merchant-httpd_get-rewards-ID.c
new file mode 100644
index 00000000..31ee2afa
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_get-rewards-ID.c
@@ -0,0 +1,235 @@
+/*
+ This file is part of TALER
+ (C) 2014-2021 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler-merchant-httpd_get-rewards-ID.c
+ * @brief implementation of GET /rewards/$ID
+ * @author Marcello Stanisci
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include <jansson.h>
+#include <taler/taler_signatures.h>
+#include <taler/taler_json_lib.h>
+#include <taler/taler_templating_lib.h>
+#include "taler-merchant-httpd_get-rewards-ID.h"
+#include "taler-merchant-httpd_helper.h"
+#include "taler-merchant-httpd_mhd.h"
+#include "taler-merchant-httpd_qr.h"
+
+
+char *
+TMH_make_taler_reward_uri (struct MHD_Connection *con,
+ const struct TALER_RewardIdentifierP *reward_id,
+ const char *instance_id)
+{
+ struct GNUNET_Buffer buf = { 0 };
+
+ GNUNET_assert (NULL != instance_id);
+ GNUNET_assert (NULL != reward_id);
+ if (GNUNET_OK !=
+ TMH_taler_uri_by_connection (con,
+ "reward",
+ instance_id,
+ &buf))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ /* Ensure previous part is slash-terminated */
+ GNUNET_buffer_write_path (&buf,
+ "");
+ GNUNET_buffer_write_data_encoded (&buf,
+ reward_id,
+ sizeof (*reward_id));
+ return GNUNET_buffer_reap_str (&buf);
+}
+
+
+char *
+TMH_make_reward_status_url (struct MHD_Connection *con,
+ const struct TALER_RewardIdentifierP *reward_id,
+ const char *instance_id)
+{
+ struct GNUNET_Buffer buf;
+
+ GNUNET_assert (NULL != instance_id);
+ GNUNET_assert (NULL != reward_id);
+ if (GNUNET_OK !=
+ TMH_base_url_by_connection (con,
+ instance_id,
+ &buf))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ GNUNET_buffer_write_path (&buf,
+ "rewards/");
+ GNUNET_buffer_write_data_encoded (&buf,
+ reward_id,
+ sizeof (*reward_id));
+ return GNUNET_buffer_reap_str (&buf);
+}
+
+
+MHD_RESULT
+TMH_get_rewards_ID (const struct TMH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ struct TMH_HandlerContext *hc)
+{
+ struct TALER_RewardIdentifierP reward_id;
+ enum GNUNET_DB_QueryStatus qs;
+ struct TALER_Amount total_authorized;
+ struct TALER_Amount total_picked_up;
+ struct GNUNET_TIME_Timestamp expiration;
+ char *exchange_url;
+ char *next_url;
+ struct TALER_ReservePrivateKeyP reserve_priv;
+
+ (void) rh;
+ if (GNUNET_OK !=
+ GNUNET_CRYPTO_hash_from_string (hc->infix,
+ &reward_id.hash))
+ {
+ /* reward_id has wrong encoding */
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_GENERIC_PARAMETER_MALFORMED,
+ hc->infix);
+ }
+
+ TMH_db->preflight (TMH_db->cls);
+ qs = TMH_db->lookup_reward (TMH_db->cls,
+ hc->instance->settings.id,
+ &reward_id,
+ &total_authorized,
+ &total_picked_up,
+ &expiration,
+ &exchange_url,
+ &next_url,
+ &reserve_priv);
+ if (0 > qs)
+ {
+ /* single, read-only SQL statements should never cause
+ serialization problems */
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
+ /* Always report on hard error as well to enable diagnostics */
+ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ NULL);
+ }
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Unknown reward id given: `%s'\n",
+ hc->infix);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_MERCHANT_GENERIC_REWARD_ID_UNKNOWN,
+ hc->infix);
+ }
+
+ /* Build response */
+ {
+ struct TALER_Amount remaining;
+ MHD_RESULT ret;
+
+ GNUNET_break (0 <=
+ TALER_amount_subtract (&remaining,
+ &total_authorized,
+ &total_picked_up));
+ if (TMH_MHD_test_html_desired (connection))
+ {
+ char *qr;
+ char *uri;
+ char *reward_status_url;
+
+ uri = TMH_make_taler_reward_uri (connection,
+ &reward_id,
+ hc->instance->settings.id);
+ reward_status_url = TMH_make_reward_status_url (connection,
+ &reward_id,
+ hc->instance->settings.id);
+ qr = TMH_create_qrcode (uri);
+ if (NULL == qr)
+ {
+ GNUNET_break (0);
+ GNUNET_free (uri);
+ ret = TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_ALLOCATION_FAILURE,
+ "during QR code generation");
+ }
+ else
+ {
+ json_t *context;
+
+ context = GNUNET_JSON_PACK (
+ TALER_JSON_pack_amount ("remaining_reward",
+ &remaining),
+ GNUNET_JSON_pack_string ("taler_reward_uri",
+ uri),
+ GNUNET_JSON_pack_string ("next_url",
+ next_url),
+ GNUNET_JSON_pack_string ("taler_reward_qrcode_svg",
+ qr));
+ ret = TALER_TEMPLATING_reply (connection,
+ ( (0 == remaining.value) &&
+ (0 == remaining.fraction) )
+ ? MHD_HTTP_GONE
+ : MHD_HTTP_OK,
+ ( (0 == remaining.value) &&
+ (0 == remaining.fraction) )
+ ? "depleted_reward"
+ : "offer_reward",
+ hc->instance->settings.id,
+ uri,
+ context);
+ json_decref (context);
+ }
+ GNUNET_free (reward_status_url);
+ GNUNET_free (uri);
+ GNUNET_free (qr);
+ }
+ else
+ {
+ ret = TALER_MHD_REPLY_JSON_PACK (
+ connection,
+ TALER_amount_is_zero (&remaining)
+ ? MHD_HTTP_GONE
+ : MHD_HTTP_OK,
+ GNUNET_JSON_pack_string ("exchange_url",
+ exchange_url),
+ GNUNET_JSON_pack_string ("next_url",
+ next_url),
+ TALER_JSON_pack_amount ("reward_amount",
+ &remaining),
+ // FIXME: tip_amount is for legacy compatibility, to be removed "later"
+ TALER_JSON_pack_amount ("tip_amount",
+ &remaining),
+ GNUNET_JSON_pack_timestamp ("expiration",
+ expiration));
+ }
+ GNUNET_free (exchange_url);
+ GNUNET_free (next_url);
+ return ret;
+ }
+}
+
+
+/* end of taler-merchant-httpd_get-rewards-ID.c */