summaryrefslogtreecommitdiff
path: root/src/lib/merchant_api_get_orders.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/merchant_api_get_orders.c')
-rw-r--r--src/lib/merchant_api_get_orders.c233
1 files changed, 148 insertions, 85 deletions
diff --git a/src/lib/merchant_api_get_orders.c b/src/lib/merchant_api_get_orders.c
index 7f08acb6..459409fd 100644
--- a/src/lib/merchant_api_get_orders.c
+++ b/src/lib/merchant_api_get_orders.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2018, 2020, 2021 Taler Systems SA
+ Copyright (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
@@ -30,6 +30,10 @@
#include <taler/taler_json_lib.h>
#include <taler/taler_signatures.h>
+/**
+ * Maximum number of orders we return.
+ */
+#define MAX_ORDERS 1024
/**
* Handle for a GET /orders operation.
@@ -68,65 +72,64 @@ struct TALER_MERCHANT_OrdersGetHandle
* Parse order information from @a ia.
*
* @param ia JSON array (or NULL!) with order data
+ * @param[in] ogr response to fill
* @param ogh operation handle
* @return #GNUNET_OK on success
*/
static enum GNUNET_GenericReturnValue
parse_orders (const json_t *ia,
+ struct TALER_MERCHANT_OrdersGetResponse *ogr,
struct TALER_MERCHANT_OrdersGetHandle *ogh)
{
- unsigned int oes_len = json_array_size (ia);
- struct TALER_MERCHANT_OrderEntry oes[oes_len];
- size_t index;
- json_t *value;
- int ret;
-
- ret = GNUNET_OK;
- json_array_foreach (ia, index, value) {
- struct TALER_MERCHANT_OrderEntry *ie = &oes[index];
- struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_string ("order_id",
- &ie->order_id),
- GNUNET_JSON_spec_timestamp ("timestamp",
- &ie->timestamp),
- GNUNET_JSON_spec_uint64 ("row_id",
- &ie->order_serial),
- TALER_JSON_spec_amount_any ("amount",
- &ie->amount),
- GNUNET_JSON_spec_string ("summary",
- &ie->summary),
- GNUNET_JSON_spec_bool ("refundable",
- &ie->refundable),
- GNUNET_JSON_spec_bool ("paid",
- &ie->paid),
- GNUNET_JSON_spec_end ()
- };
+ unsigned int oes_len = (unsigned int) json_array_size (ia);
- if (GNUNET_OK !=
- GNUNET_JSON_parse (value,
- spec,
- NULL, NULL))
- {
- GNUNET_break_op (0);
- ret = GNUNET_SYSERR;
- continue;
- }
- if (GNUNET_SYSERR == ret)
- break;
+ if ( (json_array_size (ia) != (size_t) oes_len) ||
+ (oes_len > MAX_ORDERS) )
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
- if (GNUNET_OK == ret)
{
- struct TALER_MERCHANT_HttpResponse hr = {
- .http_status = MHD_HTTP_OK
- };
+ struct TALER_MERCHANT_OrderEntry oes[GNUNET_NZL (oes_len)];
+ size_t index;
+ json_t *value;
+
+ json_array_foreach (ia, index, value) {
+ struct TALER_MERCHANT_OrderEntry *ie = &oes[index];
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("order_id",
+ &ie->order_id),
+ GNUNET_JSON_spec_timestamp ("timestamp",
+ &ie->timestamp),
+ GNUNET_JSON_spec_uint64 ("row_id",
+ &ie->order_serial),
+ TALER_JSON_spec_amount_any ("amount",
+ &ie->amount),
+ GNUNET_JSON_spec_string ("summary",
+ &ie->summary),
+ GNUNET_JSON_spec_bool ("refundable",
+ &ie->refundable),
+ GNUNET_JSON_spec_bool ("paid",
+ &ie->paid),
+ GNUNET_JSON_spec_end ()
+ };
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (value,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ }
+ ogr->details.ok.orders_length = oes_len;
+ ogr->details.ok.orders = oes;
ogh->cb (ogh->cb_cls,
- &hr,
- oes_len,
- oes);
+ ogr);
ogh->cb = NULL; /* just to be sure */
}
- return ret;
+ return GNUNET_OK;
}
@@ -145,9 +148,9 @@ handle_get_orders_finished (void *cls,
{
struct TALER_MERCHANT_OrdersGetHandle *ogh = cls;
const json_t *json = response;
- struct TALER_MERCHANT_HttpResponse hr = {
- .http_status = (unsigned int) response_code,
- .reply = json
+ struct TALER_MERCHANT_OrdersGetResponse ogr = {
+ .hr.http_status = (unsigned int) response_code,
+ .hr.reply = json
};
ogh->job = NULL;
@@ -158,10 +161,10 @@ handle_get_orders_finished (void *cls,
{
case MHD_HTTP_OK:
{
- json_t *orders;
+ const json_t *orders;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_json ("orders",
- &orders),
+ GNUNET_JSON_spec_array_const ("orders",
+ &orders),
GNUNET_JSON_spec_end ()
};
@@ -170,52 +173,43 @@ handle_get_orders_finished (void *cls,
spec,
NULL, NULL))
{
- hr.http_status = 0;
- hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ ogr.hr.http_status = 0;
+ ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ break;
}
- else
+ if (GNUNET_OK ==
+ parse_orders (orders,
+ &ogr,
+ ogh))
{
- if ( (! json_is_array (orders)) ||
- (GNUNET_OK ==
- parse_orders (orders,
- ogh)) )
- {
- GNUNET_JSON_parse_free (spec);
- TALER_MERCHANT_orders_get_cancel (ogh);
- return;
- }
- else
- {
- hr.http_status = 0;
- hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
- }
+ TALER_MERCHANT_orders_get_cancel (ogh);
+ return;
}
- GNUNET_JSON_parse_free (spec);
+ ogr.hr.http_status = 0;
+ ogr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
break;
}
case MHD_HTTP_UNAUTHORIZED:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ ogr.hr.ec = TALER_JSON_get_error_code (json);
+ ogr.hr.hint = TALER_JSON_get_error_hint (json);
/* Nothing really to verify, merchant says we need to authenticate. */
break;
case MHD_HTTP_NOT_FOUND:
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ ogr.hr.ec = TALER_JSON_get_error_code (json);
+ ogr.hr.hint = TALER_JSON_get_error_hint (json);
break;
default:
/* unexpected response code */
- hr.ec = TALER_JSON_get_error_code (json);
- hr.hint = TALER_JSON_get_error_hint (json);
+ ogr.hr.ec = TALER_JSON_get_error_code (json);
+ ogr.hr.hint = TALER_JSON_get_error_hint (json);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unexpected response code %u/%d\n",
(unsigned int) response_code,
- (int) hr.ec);
+ (int) ogr.hr.ec);
break;
}
ogh->cb (ogh->cb_cls,
- &hr,
- 0,
- NULL);
+ &ogr);
TALER_MERCHANT_orders_get_cancel (ogh);
}
@@ -255,12 +249,51 @@ TALER_MERCHANT_orders_get2 (
TALER_MERCHANT_OrdersGetCallback cb,
void *cb_cls)
{
+ return TALER_MERCHANT_orders_get3 (
+ ctx,
+ backend_url,
+ paid,
+ refunded,
+ wired,
+ NULL,
+ NULL,
+ date,
+ start_row,
+ delta,
+ timeout,
+ cb,
+ cb_cls);
+}
+
+
+struct TALER_MERCHANT_OrdersGetHandle *
+TALER_MERCHANT_orders_get3 (
+ struct GNUNET_CURL_Context *ctx,
+ const char *backend_url,
+ enum TALER_EXCHANGE_YesNoAll paid,
+ enum TALER_EXCHANGE_YesNoAll refunded,
+ enum TALER_EXCHANGE_YesNoAll wired,
+ const char *session_id,
+ const char *fulfillment_url,
+ struct GNUNET_TIME_Timestamp date,
+ uint64_t start_row,
+ int64_t delta,
+ struct GNUNET_TIME_Relative timeout,
+ TALER_MERCHANT_OrdersGetCallback cb,
+ void *cb_cls)
+{
struct TALER_MERCHANT_OrdersGetHandle *ogh;
CURL *eh;
- unsigned int timeout_ms = timeout.rel_value_us
- / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
+ unsigned int tms = timeout.rel_value_us
+ / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
GNUNET_assert (NULL != backend_url);
+ if ( (delta > MAX_ORDERS) ||
+ (delta < -MAX_ORDERS) )
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
if (0 == delta)
{
GNUNET_break (0);
@@ -274,6 +307,8 @@ TALER_MERCHANT_orders_get2 (
/* build ogh->url with the various optional arguments */
{
char *dstr;
+ char *fec = NULL;
+ char *sid = NULL;
bool have_date;
bool have_srow;
char cbuf[30];
@@ -282,8 +317,8 @@ TALER_MERCHANT_orders_get2 (
GNUNET_snprintf (tbuf,
sizeof (tbuf),
- "%llu",
- (unsigned long long) timeout_ms);
+ "%u",
+ tms);
GNUNET_snprintf (dbuf,
sizeof (dbuf),
"%lld",
@@ -292,6 +327,14 @@ TALER_MERCHANT_orders_get2 (
sizeof (cbuf),
"%llu",
(unsigned long long) start_row);
+ if (NULL != session_id)
+ (void) GNUNET_STRINGS_urlencode (strlen (session_id),
+ session_id,
+ &sid);
+ if (NULL != fulfillment_url)
+ (void) GNUNET_STRINGS_urlencode (strlen (fulfillment_url),
+ fulfillment_url,
+ &fec);
dstr = GNUNET_strdup (GNUNET_TIME_timestamp2s (date));
if (delta > 0)
{
@@ -330,11 +373,17 @@ TALER_MERCHANT_orders_get2 (
? dbuf
: NULL,
"timeout_ms",
- (0 != timeout_ms)
+ (0 != tms)
? tbuf
: NULL,
+ "session_id",
+ sid,
+ "fulfillment_url",
+ fec,
NULL);
GNUNET_free (dstr);
+ GNUNET_free (sid);
+ GNUNET_free (fec);
}
if (NULL == ogh->url)
{
@@ -347,6 +396,20 @@ TALER_MERCHANT_orders_get2 (
"Requesting URL '%s'\n",
ogh->url);
eh = TALER_MERCHANT_curl_easy_get_ (ogh->url);
+ if (NULL == eh)
+ {
+ GNUNET_break (0);
+ GNUNET_free (ogh->url);
+ GNUNET_free (ogh);
+ return NULL;
+ }
+ if (0 != tms)
+ {
+ GNUNET_break (CURLE_OK ==
+ curl_easy_setopt (eh,
+ CURLOPT_TIMEOUT_MS,
+ (long) (tms + 100L)));
+ }
ogh->job = GNUNET_CURL_job_add (ctx,
eh,
&handle_get_orders_finished,