diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_deposit.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_deposit.c | 124 |
1 files changed, 119 insertions, 5 deletions
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index 0484ab07..0199802c 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -47,7 +47,7 @@ * @param connection connection to the client * @param coin_pub public key of the coin * @param h_wire hash of wire details - * @param h_extensions hash of applicable extensions + * @param h_policy hash of applicable extensions * @param h_contract_terms hash of contract details * @param exchange_timestamp exchange's timestamp * @param refund_deadline until when this deposit be refunded @@ -61,7 +61,7 @@ reply_deposit_success ( struct MHD_Connection *connection, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_MerchantWireHashP *h_wire, - const struct TALER_ExtensionContractHashP *h_extensions, + const struct TALER_ExtensionPolicyHashP *h_policy, const struct TALER_PrivateContractHashP *h_contract_terms, struct GNUNET_TIME_Timestamp exchange_timestamp, struct GNUNET_TIME_Timestamp refund_deadline, @@ -78,7 +78,7 @@ reply_deposit_success ( &TEH_keys_exchange_sign_, h_contract_terms, h_wire, - h_extensions, + h_policy, exchange_timestamp, wire_deadline, refund_deadline, @@ -208,6 +208,86 @@ deposit_transaction (void *cls, } +/** + * @brief check the provided policy + * + * @param[in] policy_details JSON object provided by the client with prolicy + * @param[out] hc On success, will contain the hash of the normalized policy_details object + * @param[out] handler_out On success, the handler might provide an output + * @param[out] error_hint On failure, might contain a hint of the error from the extension + * @return GNUNET_OK on success. + */ +enum GNUNET_GenericReturnValue +check_policy_details ( + json_t *policy_details, + struct TALER_ExtensionPolicyHashP *hc, + json_t **handler_out, + char **error_hint) +{ + const char *type = NULL; + const struct TALER_Extension *extension; + enum GNUNET_GenericReturnValue ret; + + *error_hint = NULL; + + if ((NULL == policy_details) || + (! json_is_object (policy_details))) + { + *error_hint = "invalid policy object"; + return GNUNET_SYSERR; + } + + // parse and evaluate the object + { + json_t *jtype = json_object_get ( + policy_details, + "type"); + if (NULL == jtype) + { + *error_hint = "no type in policy object"; + return GNUNET_SYSERR; + } + + type = json_string_value (jtype); + if (NULL == type) + { + *error_hint = "invalid type in policy object"; + return GNUNET_SYSERR; + } + + extension = TALER_extensions_get_by_name (type); + if ((NULL == extension) || + (NULL == extension->deposit_handler)) + { + GNUNET_break (0); + *error_hint = "no such policy"; + return GNUNET_SYSERR; + } + + ret = extension->deposit_handler (policy_details, + handler_out); + if (GNUNET_OK != ret) + { + GNUNET_break (0); + if (NULL != *handler_out) + { + *error_hint = json_dumps (*handler_out, JSON_INDENT (2)); + } + else + { + GNUNET_break (1); + *error_hint = "unknown error with the policy"; + } + return ret; + } + } + + TALER_deposit_policy_hash (policy_details, + hc); + return GNUNET_OK; +} + + MHD_RESULT TEH_handler_deposit (struct MHD_Connection *connection, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -216,6 +296,9 @@ TEH_handler_deposit (struct MHD_Connection *connection, struct DepositContext dc; struct TALER_EXCHANGEDB_Deposit deposit; const char *payto_uri; + struct TALER_ExtensionPolicyHashP h_policy; + struct TALER_ExtensionPolicyHashP *ph_policy = NULL; + bool no_policy; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_string ("merchant_payto_uri", &payto_uri), @@ -240,10 +323,16 @@ TEH_handler_deposit (struct MHD_Connection *connection, &deposit.csig), GNUNET_JSON_spec_timestamp ("timestamp", &deposit.timestamp), + + /* TODO: this will move to an extension for refunds */ GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_timestamp ("refund_deadline", &deposit.refund_deadline), NULL), + GNUNET_JSON_spec_mark_optional ( + GNUNET_JSON_spec_json ("policy", + &deposit.policy_details), + &no_policy), GNUNET_JSON_spec_timestamp ("wire_transfer_deadline", &deposit.wire_deadline), GNUNET_JSON_spec_end () @@ -383,6 +472,31 @@ TEH_handler_deposit (struct MHD_Connection *connection, NULL); } + /* TODO: check policy_details */ + if (! no_policy) + { + char *hint; + json_t *out; + MHD_RESULT res; + + if (GNUNET_OK != + check_policy_details (dc.deposit->policy_details, + &h_policy, + &out, + &hint)) + { + res = TALER_MHD_reply_with_error (connection, + MHD_HTTP_BAD_REQUEST, + /* TODO: new error type needed */ + TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN, + hint); + GNUNET_free (hint); + return res; + } + + ph_policy = &h_policy; + } + deposit.deposit_fee = dk->meta.fees.deposit; /* check coin signature */ switch (dk->denom_pub.cipher) @@ -426,7 +540,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, &h_wire, &deposit.h_contract_terms, &deposit.coin.h_age_commitment, - NULL /* FIXME: h_extensions! */, + ph_policy, &deposit.coin.denom_pub_hash, deposit.timestamp, &deposit.merchant_pub, @@ -481,7 +595,7 @@ TEH_handler_deposit (struct MHD_Connection *connection, res = reply_deposit_success (connection, &deposit.coin.coin_pub, &h_wire, - NULL /* FIXME: h_extensions! */, + ph_policy, &deposit.h_contract_terms, dc.exchange_timestamp, deposit.refund_deadline, |