commit 40ed79e41cc691e257ebc8ee5b974003f7bed1b0
parent ecfb6f19b1f9e113bc0ead00db9fde8188581084
Author: Christian Grothoff <christian@grothoff.org>
Date: Mon, 20 Apr 2026 00:34:03 +0200
expand consistency check logic
Diffstat:
2 files changed, 86 insertions(+), 9 deletions(-)
diff --git a/src/backend/paivana-httpd.c b/src/backend/paivana-httpd.c
@@ -169,8 +169,11 @@ create_response (void *cls,
}
// FIXME: check if url is one that we require payment for,
// if not set 'do_forward = true'.
- // (also should eventually determine WHICH payment template
- // we use...)
+ // (also should determine WHICH payment template
+ // we use => load *all* templates of the instance,
+ // pre-compile *all* regexes and then match!)
+ // -> Then needs *restart* on template changes!
+ // -> in future: long-poll on GET /private/templates?
if (rc->do_forward)
{
diff --git a/src/backend/paivana-httpd_pay.c b/src/backend/paivana-httpd_pay.c
@@ -21,7 +21,6 @@
/**
* @author Christian Grothoff
* @file paivana-httpd_pay.c
- *
* @brief payment processing logic
*/
#include <gnunet/gnunet_util_lib.h>
@@ -143,6 +142,84 @@ PAIVANA_HTTPD_payment_create (struct MHD_Connection *connection)
/**
+ * Check that the @a contract that was paid is reasonable for the
+ * request in @a ph, that is that we would indeed consider this
+ * contract to apply for the website and duration indicated
+ * in @a ph. If it does not apply, a response must be set in
+ * @a ph.
+ *
+ * @param[in,out] ph request to check
+ * @param contract contract to check
+ * @return true if the contract is good for the request,
+ * false if not and thus a response object was created in @a ph
+ */
+static bool
+check_contract (struct PayRequest *ph,
+ const json_t *contract)
+{
+ struct GNUNET_TIME_Timestamp max_time
+ = GNUNET_TIME_UNIT_FOREVER_TS;
+ const char *regex_s = NULL;
+ // FIXME: expand Paivana contract template specifications with
+ // these fields!
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("website_regex",
+ ®ex_s),
+ NULL),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_timestamp ("max_time",
+ &max_time),
+ NULL),
+ GNUNET_JSON_spec_end ()
+ };
+ enum GNUNET_GenericReturnValue ret;
+ const char *ename;
+ unsigned int eline;
+
+ ret = GNUNET_JSON_parse (contract,
+ spec,
+ &ename,
+ &eline);
+ if (GNUNET_OK != ret)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Encountered contract with unexpected fields: %s@%u\n",
+ ename,
+ eline);
+ return true;
+ }
+ if (NULL != regex_s)
+ {
+ bool match = true;
+
+ // FIXME: check ph->website matches regex.
+ // If not: => TALER_EC_PAIVANA_WRONG_ORDER with 409!
+ if (! match)
+ {
+ GNUNET_break_op (0);
+ ph->response = TALER_MHD_make_error (TALER_EC_PAIVANA_WRONG_ORDER,
+ ph->order_id);
+ ph->response_status = MHD_HTTP_CONFLICT;
+ return false;
+ }
+ }
+ if (GNUNET_TIME_timestamp_cmp (ph->cur_time,
+ >,
+ max_time))
+ {
+ GNUNET_break_op (0);
+ // FIXME: bad EC! Introduce new one!
+ ph->response = TALER_MHD_make_error (TALER_EC_PAIVANA_WRONG_ORDER,
+ ph->order_id);
+ ph->response_status = MHD_HTTP_GONE;
+ return false;
+ }
+ return true;
+}
+
+
+/**
* Handle response from the GET /private/orders/$ORDER_ID request.
*
* @param ph the payment request we are processing
@@ -191,12 +268,9 @@ order_status_cb (struct PayRequest *ph,
ca_len = 0;
break;
}
- // FIXME: check ph->website matches template that
- // was paid here. If not:
- // => TALER_EC_PAIVANA_WRONG_ORDER with 409!
- // FIXME: check ph->cur_time is not too far into the
- // future (if purchase is for limited time!). If so:
- // => response with 410!
+ if (! check_contract (ph,
+ osr->details.ok.details.paid.contract_terms))
+ return;
cookie = PAIVANA_HTTPD_compute_cookie (ph->cur_time,
ph->website,
ca_len,