[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-anastasis] branch master updated: work on payment service
From: |
gnunet |
Subject: |
[taler-anastasis] branch master updated: work on payment service |
Date: |
Wed, 11 Nov 2020 18:56:23 +0100 |
This is an automated email from the git hooks/post-receive script.
ds-meister pushed a commit to branch master
in repository anastasis.
The following commit(s) were added to refs/heads/master by this push:
new 9ad9564 work on payment service
9ad9564 is described below
commit 9ad9564c22b06ea4c6f3c5a456e26ad61f4fd124
Author: Dominik Meister <dominik.meister@hotmail.ch>
AuthorDate: Wed Nov 11 18:56:06 2020 +0100
work on payment service
---
src/backend/anastasis-httpd_truth.c | 564 ++++++++++++++++++++----------
src/include/anastasis_service.h | 31 +-
src/include/anastasis_testing_lib.h | 4 +
src/lib/anastasis_api_keyshare_lookup.c | 47 ++-
src/lib/test_anastasis_api.c | 26 +-
src/lib/test_anastasis_api.conf | 19 +-
src/lib/testing_api_cmd_challenge_run.c | 67 +++-
src/lib/testing_api_cmd_keyshare_lookup.c | 17 +
8 files changed, 577 insertions(+), 198 deletions(-)
diff --git a/src/backend/anastasis-httpd_truth.c
b/src/backend/anastasis-httpd_truth.c
index a30f77c..e229d2a 100644
--- a/src/backend/anastasis-httpd_truth.c
+++ b/src/backend/anastasis-httpd_truth.c
@@ -103,6 +103,14 @@ struct GetContext
*/
struct ANASTASIS_DB_ChallengePayment cp;
+ /**
+ * true if client provided a payment secret / order ID?
+ */
+ bool payment_identifier_provided;
+ /**
+ * true if client provided a payment secret / order ID?
+ */
+ struct TALER_Amount challenge_cost;
};
/**
@@ -370,7 +378,7 @@ check_payment_cb (void *cls,
qs = db->update_challenge_payment (db->cls,
&gc->truth_public_key,
- &gc->payment_identifier); /* FIXME:
always annual ?*/
+ &gc->payment_identifier);
if (0 <= qs)
return; /* continue as planned */
GNUNET_break (0);
@@ -488,7 +496,7 @@ begin_payment (struct GetContext *gc,
AH_backend_url);
MHD_suspend_connection (gc->connection);
order = json_pack ("{s:o, s:s, s:s, s:s}",
- "amount", TALER_JSON_from_amount (&AH_annual_fee),
+ "amount", TALER_JSON_from_amount (&gc->challenge_cost),
"summary", "annual fee for anastasis service",
"fulfillment_url", AH_fulfillment_url,
"order_id", order_id);
@@ -511,6 +519,70 @@ begin_payment (struct GetContext *gc,
return MHD_YES;
}
+/**
+ * We got some query status from the DB. Handle the error cases.
+ * May perform asynchronous operations by suspending the connection
+ * if required.
+ *
+ * @param gc connection to handle status for
+ * @param qs query status to handle
+ * @return #MHD_YES or #MHD_NO
+ */
+static MHD_RESULT
+handle_database_error (struct GetContext *gc,
+ enum ANASTASIS_DB_QueryStatus qs)
+{
+ switch (qs)
+ {
+ case ANASTASIS_DB_STATUS_PAYMENT_REQUIRED:
+ {
+ if (! gc->payment_identifier_provided)
+ {
+ GNUNET_CRYPTO_random_block (
+ GNUNET_CRYPTO_QUALITY_NONCE,
+ &gc->payment_identifier,
+ sizeof (struct ANASTASIS_PaymentSecretP));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Payment-Identifier generated: %s, starting payment
process\n",
+ TALER_B2S (&gc->payment_identifier));
+ return begin_payment (gc,
+ GNUNET_NO);
+ }
+
+ {
+ char *order_id;
+
+ order_id = GNUNET_STRINGS_data_to_string_alloc (
+ &gc->payment_identifier,
+ sizeof (gc->payment_identifier));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Payment required, awaiting completion of `%s'\n",
+ order_id);
+ await_payment (gc,
+ CHECK_PAYMENT_GENERIC_TIMEOUT,
+ order_id);
+ GNUNET_free (order_id);
+ }
+ }
+ return MHD_YES;
+ case ANASTASIS_DB_STATUS_HARD_ERROR:
+ case ANASTASIS_DB_STATUS_SOFT_ERROR:
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (puc->con,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_FETCH_FAILED,
+ NULL);
+ case ANASTASIS_DB_STATUS_NO_RESULTS:
+ GNUNET_assert (0);
+ return MHD_NO;
+ /* intentional fall-through! */
+ case ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT:
+ GNUNET_assert (0);
+ return MHD_NO;
+ }
+ GNUNET_break (0);
+ return MHD_NO;
+}
/**
* @param connection the MHD connection to handle
@@ -537,6 +609,9 @@ AH_handler_truth_get (struct MHD_Connection *connection,
size_t decrypted_truth_size;
char *truth_mime;
char *method;
+ struct TALER_Amount zero_amount;
+ TALER_amount_get_zero (AH_currency, &zero_amount);
+ bool zero_cost = false;
if (NULL != gc)
{
@@ -579,11 +654,31 @@ AH_handler_truth_get (struct MHD_Connection *connection,
return MHD_NO;
}
}
+ {
+ const char *pay_id;
- /* extract public key from url */
- GNUNET_assert (0 == strncmp (url,
- "/truth/",
- strlen ("/truth/")));
+ pay_id = MHD_lookup_connection_value (connection,
+ MHD_HEADER_KIND,
+ "Payment-Identifier");
+ if (NULL != pay_id)
+ {
+ if (GNUNET_OK !=
+ GNUNET_STRINGS_string_to_data (pay_id,
+ strlen (pay_id),
+ &gc->payment_identifier,
+ sizeof (struct
+ ANASTASIS_PaymentSecretP)))
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ // FIXME: find error code
+ TALER_EC_SYNC_BAD_IF_MATCH,
+ "Payment-Identifier does not
include a base32-encoded Payment-Secret");
+ }
+ gc->payment_identifier_provided = true;
+ }
+ }
{
const char *pub_key_str;
@@ -666,198 +761,309 @@ AH_handler_truth_get (struct MHD_Connection *connection,
&decrypted_truth,
&decrypted_truth_size);
}
- if (0 == strcmp ("question",
- method))
- {
- if (NULL == challenge_response_s)
- {
- // FIXME: queue PROPER reply...
- GNUNET_free (decrypted_truth);
- return MHD_NO;
- }
-
- GNUNET_CRYPTO_hash_from_string (challenge_response_s,
- &challenge_response);
-
- if (0 != GNUNET_memcmp (&challenge_response,
- decrypted_truth))
- {
- GNUNET_break (0);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- // FIXME: find error code
- TALER_EC_SYNC_BAD_IF_MATCH,
- "Authentication failed"); // FIXME:
How much should we tell?
- }
- else
- {
- return return_key_share (&truth_public_key,
- connection);
- }
- }
-
- /* Not security question, check for answer in DB */
- if (NULL != challenge_response_s)
+ /* Check database to see if the transaction is permissible */
{
+ struct GNUNET_HashCode hc;
enum ANASTASIS_DB_QueryStatus qs;
- unsigned long long code;
- char dummy;
- if (1 != sscanf (challenge_response_s,
- "%llu%c",
- &code,
- &dummy))
+ if (gc->payment_identifier_provided)
{
- // FIXME: queue PROPER reply...
- GNUNET_free (decrypted_truth);
- return MHD_NO;
- }
-
- qs = db->verify_challenge_code (db->cls,
- &truth_public_key,
- code);
+ // check if payment identifier is valid (existing and paid)
+ bool paid;
- switch (qs)
- {
- case ANASTASIS_DB_STATUS_HARD_ERROR:
- GNUNET_free (decrypted_truth);
- return MHD_NO;
- case ANASTASIS_DB_STATUS_SOFT_ERROR:
- GNUNET_free (decrypted_truth);
- return MHD_NO;
- case ANASTASIS_DB_STATUS_NO_RESULTS:
- GNUNET_free (decrypted_truth);
- return MHD_NO;
- case ANASTASIS_DB_STATUS_VALID_CODE_STORED:
- break;
- default:
- GNUNET_free (decrypted_truth);
- return MHD_NO;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "At %s:%d Payment-Identifier from header is: %s\n",
+ __FILE__,
+ __LINE__,
+ TALER_B2S (&gc->payment_identifier));
+
+ qs = db->check_challenge_payment (db->cls,
+ &puc->payment_identifier,
+ &paid);
+ if (qs < 0)
+ return handle_database_error (puc,
+ qs);
+
+ if ((qs >= 0) && (! paid))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "At %s:%d paid is: '%d'\n",
+ __FILE__,
+ __LINE__,
+ paid);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "At %s:%d Payment is required, starting payment
process.\n",
+ __FILE__,
+ __LINE__);
+ return begin_payment (gc,
+ GNUNET_YES);
+ }
}
- return return_key_share (&truth_public_key,
- connection);
- }
-
- /* Not security question and no answer: use plugin to generate challenge! */
- {
- struct ANASTASIS_AuthorizationPlugin *authorization;
- enum GNUNET_GenericReturnValue ret;
- struct ANASTASIS_AUTHORIZATION_State *as;
- enum ANASTASIS_AUTHORIZATION_Result aret;
- enum ANASTASIS_DB_QueryStatus qs;
- struct GNUNET_TIME_Relative challenge_expiration;
- challenge_expiration = GNUNET_TIME_UNIT_HOURS;
-
- authorization = ANASTASIS_authorization_plugin_load (method);
- if (NULL == authorization)
+ if (! gc->payment_identifier_provided)
{
+ // generate new payment identifier
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &gc->payment_identifier,
+ sizeof (
+ struct ANASTASIS_PaymentSecretP));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Plugin not found: %s",method);
- GNUNET_free (decrypted_truth);
- return MHD_NO;
+ "At %s:%d Payment-Identifier generated is: %s\n",
+ __FILE__,
+ __LINE__,
+ TALER_B2S (&gc->payment_identifier));
+
+
+
+ if (0 == strcmp ("question",
+ method))
+ {
+ if (0 == TALER_amount_cmp (&AH_question_cost, &zero_amount))
+ zero_cost = true;
+ gc->challenge_cost = AH_question_cost;
+ }
+ if (0 == strcmp ("file",
+ method))
+ {
+ if (0 == TALER_amount_cmp (&AH_file_cost, &zero_amount))
+ zero_cost = true;
+ gc->challenge_cost = AH_file_cost;
+ }
+
+ if (zero_cost)
+ {
+ qs = db->record_challenge_payment (db->cls,
+ &truth_public_key,
+ &puc->payment_identifier,
+ &gc->challenge_cost);
+ if (qs >= 0)
+ {
+ qs = db->update_challenge_payment (db->cls,
+ truth_public_key,
+ &gc->payment_identifier);
+ }
+ if (qs < 0)
+ return handle_database_error (gc,
+ qs);
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "At %s:%d Payment is required, starting payment process\n",
+ __FILE__,
+ __LINE__);
+ return begin_payment (gc,
+ GNUNET_YES);
+ }
}
-
- ret = authorization->validate (authorization->cls,
- connection,
- decrypted_truth,
- decrypted_truth_size);
-
- switch (ret)
+ /* check if the client insists on paying */
{
- case GNUNET_OK:
- /* data valid, continued below */
- break;
- case GNUNET_NO:
- /* data invalid, reply was queued */
- GNUNET_free (decrypted_truth);
- return MHD_YES;
- case GNUNET_SYSERR:
- /* data invalid, reply was NOT queued */
- GNUNET_free (decrypted_truth);
- return MHD_NO;
+ const char *order_req;
+
+ order_req = MHD_lookup_connection_value (connection,
+ MHD_GET_ARGUMENT_KIND,
+ "pay");
+ if (NULL != order_req)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Payment requested, starting payment process\n");
+ return begin_payment (gc,
+ GNUNET_YES);
+ }
}
- // FIXME:
- // RANDOM! -- or from DB if recent one in DB!
- uint64_t code = 42;
- // FIXME TIME where to put this?
- // FIXME retry counter where to put it?
- qs = db->store_challenge_code (db->cls,
- &truth_public_key,
- code,
- challenge_expiration,
- 3);
- switch (qs)
+ if (0 == strcmp ("question",
+ method))
{
- case ANASTASIS_DB_STATUS_HARD_ERROR:
- /* data invalid, reply was NOT queued */
- GNUNET_free (decrypted_truth);
- return MHD_NO;
- case ANASTASIS_DB_STATUS_SOFT_ERROR:
- /* data invalid, reply was NOT queued */
- GNUNET_free (decrypted_truth);
- return MHD_NO;
- case ANASTASIS_DB_STATUS_VALID_CODE_STORED:
- /*FIXME already code stored message */
- return MHD_NO;
- case ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT:
- /*challengecode was stored successfully*/
- break;
- default:
- GNUNET_free (decrypted_truth);
- return MHD_NO;
+ if (NULL == challenge_response_s)
+ {
+ // FIXME: queue PROPER reply...
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ }
+
+ GNUNET_CRYPTO_hash_from_string (challenge_response_s,
+ &challenge_response);
+
+ if (0 != GNUNET_memcmp (&challenge_response,
+ decrypted_truth))
+ {
+ GNUNET_break (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ // FIXME: find error code
+ TALER_EC_SYNC_BAD_IF_MATCH,
+ "Authentication failed"); // FIXME:
How much should we tell?
+ }
+ else
+ {
+ return return_key_share (&truth_public_key,
+ connection);
+ }
}
- as = authorization->start (authorization->cls,
- &truth_public_key,
- code,
- decrypted_truth,
- decrypted_truth_size);
- GNUNET_free (decrypted_truth);
- if (NULL == as)
+ /* Not security question, check for answer in DB */
+ if (NULL != challenge_response_s)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- ("AUTHORIZATION START FAILED"));
- // FIXME: queue PROPER reply...
- return MHD_NO;
+ enum ANASTASIS_DB_QueryStatus qs;
+ unsigned long long code;
+ char dummy;
+
+ if (1 != sscanf (challenge_response_s,
+ "%llu%c",
+ &code,
+ &dummy))
+ {
+ // FIXME: queue PROPER reply...
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ }
+
+ qs = db->verify_challenge_code (db->cls,
+ &truth_public_key,
+ code);
+
+ switch (qs)
+ {
+ case ANASTASIS_DB_STATUS_HARD_ERROR:
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ case ANASTASIS_DB_STATUS_SOFT_ERROR:
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ case ANASTASIS_DB_STATUS_NO_RESULTS:
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ case ANASTASIS_DB_STATUS_VALID_CODE_STORED:
+ break;
+ default:
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ }
+
+ return return_key_share (&truth_public_key,
+ connection);
}
- gc = GNUNET_new (struct GetContext);
- gc->connection = connection;
- gc->authorization = authorization;
- gc->as = as;
- hc->ctx = gc;
- hc->cc = &request_done;
- GNUNET_CONTAINER_DLL_insert (gc_head,
- gc_tail,
- gc);
- aret = authorization->process (as,
- connection);
- switch (aret)
+
+ /* Not security question and no answer: use plugin to generate challenge!
*/
{
- case ANASTASIS_AUTHORIZATION_RES_SUCCESS:
- /* all good, challenge sent! */
- // FIXME: mark in DB that we did it (now, for
code_retransmission_frequency!)
- break;
- case ANASTASIS_AUTHORIZATION_RES_FAILED:
- /* sending challenge failed */
- // FIXME: give at least a refund!?
- break;
- case ANASTASIS_AUTHORIZATION_RES_SUSPENDED:
- /* we have been suspended, see you later */
- return MHD_YES;
- case ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED:
- /* Challenge sent successfully */
- // FIXME: mark in DB that we did it (now, for
code_retransmission_frequency!)
- authorization->cleanup (gc->as);
- return MHD_NO;
- case ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED:
- /* failure to queue reply, kill connection */
+ struct ANASTASIS_AuthorizationPlugin *authorization;
+ enum GNUNET_GenericReturnValue ret;
+ struct ANASTASIS_AUTHORIZATION_State *as;
+ enum ANASTASIS_AUTHORIZATION_Result aret;
+ enum ANASTASIS_DB_QueryStatus qs;
+ struct GNUNET_TIME_Relative challenge_expiration;
+ challenge_expiration = GNUNET_TIME_UNIT_HOURS;
+
+ authorization = ANASTASIS_authorization_plugin_load (method);
+ if (NULL == authorization)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Plugin not found: %s",method);
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ }
+
+ ret = authorization->validate (authorization->cls,
+ connection,
+ decrypted_truth,
+ decrypted_truth_size);
+
+ switch (ret)
+ {
+ case GNUNET_OK:
+ /* data valid, continued below */
+ break;
+ case GNUNET_NO:
+ /* data invalid, reply was queued */
+ GNUNET_free (decrypted_truth);
+ return MHD_YES;
+ case GNUNET_SYSERR:
+ /* data invalid, reply was NOT queued */
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ }
+ // FIXME:
+ // RANDOM! -- or from DB if recent one in DB!
+ uint64_t code = 42;
+ // FIXME TIME where to put this?
+ // FIXME retry counter where to put it?
+ qs = db->store_challenge_code (db->cls,
+ &truth_public_key,
+ code,
+ challenge_expiration,
+ 3);
+
+ switch (qs)
+ {
+ case ANASTASIS_DB_STATUS_HARD_ERROR:
+ /* data invalid, reply was NOT queued */
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ case ANASTASIS_DB_STATUS_SOFT_ERROR:
+ /* data invalid, reply was NOT queued */
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ case ANASTASIS_DB_STATUS_VALID_CODE_STORED:
+ /*FIXME already code stored message */
+ return MHD_NO;
+ case ANASTASIS_DB_STATUS_SUCCESS_ONE_RESULT:
+ /*challengecode was stored successfully*/
+ break;
+ default:
+ GNUNET_free (decrypted_truth);
+ return MHD_NO;
+ }
+
+ as = authorization->start (authorization->cls,
+ &truth_public_key,
+ code,
+ decrypted_truth,
+ decrypted_truth_size);
+ GNUNET_free (decrypted_truth);
+ if (NULL == as)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ ("AUTHORIZATION START FAILED"));
+ // FIXME: queue PROPER reply...
+ return MHD_NO;
+ }
+ gc = GNUNET_new (struct GetContext);
+ gc->connection = connection;
+ gc->authorization = authorization;
+ gc->as = as;
+ hc->ctx = gc;
+ hc->cc = &request_done;
+ GNUNET_CONTAINER_DLL_insert (gc_head,
+ gc_tail,
+ gc);
+ aret = authorization->process (as,
+ connection);
+ switch (aret)
+ {
+ case ANASTASIS_AUTHORIZATION_RES_SUCCESS:
+ /* all good, challenge sent! */
+ // FIXME: mark in DB that we did it (now, for
code_retransmission_frequency!)
+ break;
+ case ANASTASIS_AUTHORIZATION_RES_FAILED:
+ /* sending challenge failed */
+ // FIXME: give at least a refund!?
+ break;
+ case ANASTASIS_AUTHORIZATION_RES_SUSPENDED:
+ /* we have been suspended, see you later */
+ return MHD_YES;
+ case ANASTASIS_AUTHORIZATION_RES_SUCCESS_REPLY_FAILED:
+ /* Challenge sent successfully */
+ // FIXME: mark in DB that we did it (now, for
code_retransmission_frequency!)
+ authorization->cleanup (gc->as);
+ return MHD_NO;
+ case ANASTASIS_AUTHORIZATION_RES_FAILED_REPLY_FAILED:
+ /* failure to queue reply, kill connection */
+ authorization->cleanup (gc->as);
+ return MHD_NO;
+ }
authorization->cleanup (gc->as);
- return MHD_NO;
+ gc->as = NULL;
+ return MHD_YES;
}
- authorization->cleanup (gc->as);
- gc->as = NULL;
- return MHD_YES;
}
-}
diff --git a/src/include/anastasis_service.h b/src/include/anastasis_service.h
index 52bb12f..6b24934 100644
--- a/src/include/anastasis_service.h
+++ b/src/include/anastasis_service.h
@@ -237,6 +237,12 @@ struct ANASTASIS_UploadDetails
} details;
};
+struct ANASTASIS_ChallengeRunDetails
+{
+ const char *response_string;
+ const char *payment_request;
+}
+
typedef void
(*ANASTASIS_ConfigCallback)(void *cls,
@@ -526,21 +532,26 @@ typedef void
* @param backend_url base URL of the merchant backend
* @param truth_public_key identification of the Truth
* @param truth_key Key used to Decrypt the Truth on the Server
- * @param answer Answer for the different authentication methods(code, hash of
answer as string)
+ * @param payment_request checks if payment was requested
+ * @param payment_secret secret from the previously done payment NULL to
trigger payment
+ * @param answer Answer for the different authentication methods(code, hash)
+ * @param answer_length size of the answer
* @param cb callback which will work the response gotten from the backend
* @param cb_cls closure to pass to the callback
* @return handle for this operation, NULL upon errors
*/
struct ANASTASIS_KeyShareLookupOperation *
-ANASTASIS_keyshare_lookup (
- struct GNUNET_CURL_Context *ctx,
- const char *backend_url,
- const struct ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key,
- const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
- const char *answer,
- ANASTASIS_KeyShareLookupCallback cb,
- void *cb_cls);
-
+ANASTASIS_keyshare_lookup (struct GNUNET_CURL_Context *ctx,
+ const char *backend_url,
+ const struct
+ ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key,
+ const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
+ int payment_requested,
+ const struct
+ ANASTASIS_PaymentSecretP *payment_secret,
+ const char *answer,
+ ANASTASIS_KeyShareLookupCallback cb,
+ void *cb_cls)
/**
* Cancel a GET /truth request.
diff --git a/src/include/anastasis_testing_lib.h
b/src/include/anastasis_testing_lib.h
index 3fae5d5..f9cd892 100644
--- a/src/include/anastasis_testing_lib.h
+++ b/src/include/anastasis_testing_lib.h
@@ -433,6 +433,7 @@ ANASTASIS_TESTING_cmd_truth_store (const char *label,
* @param http_status expected HTTP status.
* @param answer (response to challenge)
* @param key key to decrypt truth
+ * @param payment secret secret used to pay
* @param upload_ref reference to upload command
* @param lookup_mode defines the mode (0= secure question, 1 code based)
* @return the command
@@ -444,6 +445,9 @@ ANASTASIS_TESTING_cmd_keyshare_lookup (const char *label,
char *answer,
const struct
ANASTASIS_CRYPTO_TruthKeyP key,
+ const struct
+ ANASTASIS_PaymentSecretP
*payment_secret,
+ int payment_requested,
const char *upload_ref,
int lookup_mode);
/**
diff --git a/src/lib/anastasis_api_keyshare_lookup.c
b/src/lib/anastasis_api_keyshare_lookup.c
index 06111ad..b3c96c0 100644
--- a/src/lib/anastasis_api_keyshare_lookup.c
+++ b/src/lib/anastasis_api_keyshare_lookup.c
@@ -235,6 +235,8 @@ handle_header (char *buffer,
* @param backend_url base URL of the merchant backend
* @param truth_public_key identification of the Truth
* @param truth_key Key used to Decrypt the Truth on the Server
+ * @param payment_request checks if payment was requested
+ * @param payment_secret secret from the previously done payment NULL to
trigger payment
* @param answer Answer for the different authentication methods(code, hash)
* @param answer_length size of the answer
* @param cb callback which will work the response gotten from the backend
@@ -247,6 +249,9 @@ ANASTASIS_keyshare_lookup (struct GNUNET_CURL_Context *ctx,
const struct
ANASTASIS_CRYPTO_TruthPublicKeyP *truth_public_key,
const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
+ int payment_requested,
+ const struct
+ ANASTASIS_PaymentSecretP *payment_secret,
const char *answer,
ANASTASIS_KeyShareLookupCallback cb,
void *cb_cls)
@@ -280,6 +285,29 @@ ANASTASIS_keyshare_lookup (struct GNUNET_CURL_Context *ctx,
}
job_headers = ext;
}
+ /* Setup Payment-Identifier header */
+ if (NULL != payment_secret)
+ {
+ char *paid_order_id;
+
+ paid_order_id = GNUNET_STRINGS_data_to_string_alloc (
+ payment_secret,
+ sizeof (*payment_secret));
+ GNUNET_asprintf (&hdr,
+ "Payment-Identifier: %s",
+ paid_order_id);
+ GNUNET_free (paid_order_id);
+ ext = curl_slist_append (job_headers,
+ hdr);
+ GNUNET_free (hdr);
+ if (NULL == ext)
+ {
+ GNUNET_break (0);
+ curl_slist_free_all (job_headers);
+ return NULL;
+ }
+ job_headers = ext;
+ }
kslo = GNUNET_new (struct ANASTASIS_KeyShareLookupOperation);
kslo->ctx = ctx;
kslo->truth_key = truth_key;
@@ -293,11 +321,20 @@ ANASTASIS_keyshare_lookup (struct GNUNET_CURL_Context
*ctx,
GNUNET_asprintf (&path,
"truth/%s",
pub_key_str);
- kslo->url = TALER_url_join (backend_url,
- path,
- "response",
- answer,
- NULL);
+
+ kslo->url = (GNUNET_YES == payment_requested)
+ ? TALER_url_join (backend_url,
+ path,
+ "pay",
+ "y",
+ NULL)
+ : TALER_url_join (backend_url,
+ path,
+ "response",
+ answer,
+ NULL);
+ GNUNET_free (path);
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Url get request (keyshare lookup): %s\n",
kslo->url);
diff --git a/src/lib/test_anastasis_api.c b/src/lib/test_anastasis_api.c
index 0cd67df..0e1549b 100644
--- a/src/lib/test_anastasis_api.c
+++ b/src/lib/test_anastasis_api.c
@@ -264,6 +264,8 @@ run (void *cls,
answer_str,
ANASTASIS_TESTING_make_truthkey (
"Truth-Key"),
+ NULL,
+ 0,
"truth-store-1",
0),
@@ -282,6 +284,28 @@ run (void *cls,
"Truth-Key-2"))),
ANASTASIS_TESTING_cmd_challenge_run ("challenge-run-1",
+ anastasis_url,
+ MHD_HTTP_PAYMENT_REQUIRED,
+ ANASTASIS_TESTING_make_truthkey (
+ "Truth-Key-2"),
+ "truth-store-2"),
+ /* what would we have to pay? */
+ TALER_TESTING_cmd_merchant_claim_order ("fetch-proposal",
+ merchant_url,
+ MHD_HTTP_OK,
+ "challenge-run-1",
+ NULL),
+ /* make the payment */
+ TALER_TESTING_cmd_merchant_pay_order ("pay-account",
+ merchant_url,
+ MHD_HTTP_OK,
+ "fetch-proposal",
+ "withdraw-coin-1",
+ "EUR:1",
+ "EUR:1", /* must match ANNUAL_FEE in
config! */
+ NULL),
+
+ ANASTASIS_TESTING_cmd_challenge_run ("challenge-run-2",
anastasis_url,
MHD_HTTP_OK,
ANASTASIS_TESTING_make_truthkey (
@@ -291,7 +315,7 @@ run (void *cls,
ANASTASIS_TESTING_cmd_keyshare_lookup ("keyshare-lookup-2",
anastasis_url,
MHD_HTTP_OK,
- "challenge-run-1",
+ "challenge-run-2",
ANASTASIS_TESTING_make_truthkey (
"Truth-Key-2"),
"truth-store-2",
diff --git a/src/lib/test_anastasis_api.conf b/src/lib/test_anastasis_api.conf
index 0821ffb..91db82a 100644
--- a/src/lib/test_anastasis_api.conf
+++ b/src/lib/test_anastasis_api.conf
@@ -44,11 +44,26 @@ PAYMENT_BACKEND_URL = http://localhost:8080/
ANNUAL_FEE = EUR:4.99
#ANNUAL_FEE = EUR:0
-# Cost of authentication by question
-#QUESTION_COST = EUR:0
+# Authentication costs
+# Cost of authentication by question
QUESTION_COST = EUR:0
+# Cost of authentication by file (only for testing purposes)
+FILE_COST = EUR:1
+
+# Cost of authentication by E-Mail
+#EMAIL_COST = EUR:0
+
+# Cost of authentication by SMS
+#SMS_COST = EUR:0
+
+# Cost of authentication by postal
+#POSTAL_COST = EUR:0
+
+# Cost of authentication by video
+#VIDEO_COST = EUR:0
+
# Upload limit
UPLOAD_LIMIT_MB = 1
diff --git a/src/lib/testing_api_cmd_challenge_run.c
b/src/lib/testing_api_cmd_challenge_run.c
index e59f38c..f1b9231 100644
--- a/src/lib/testing_api_cmd_challenge_run.c
+++ b/src/lib/testing_api_cmd_challenge_run.c
@@ -32,6 +32,26 @@
*/
struct ChallengeRunState
{
+ /**
+ * Claim token we got back, if any. Otherwise all zeros.
+ */
+ struct TALER_ClaimTokenP token;
+
+ /**
+ * Payment identifier.
+ */
+ struct ANASTASIS_PaymentSecretP payment_id;
+
+ /**
+ * Payment order ID we got back, if any. Otherwise NULL.
+ */
+ char *payment_order_id;
+
+ /**
+ * Payment order ID we are to provide in the request, may be NULL.
+ */
+ struct ANASTASIS_PaymentSecretP payment_order_req;
+
/**
* The interpreter state.
*/
@@ -81,7 +101,7 @@ struct ChallengeRunState
static void
challenge_run_cb (void *cls,
unsigned int http_status,
- char *response_string)
+ const struct ANASTASIS_ChallengeRunDetails *crd)
{
struct ChallengeRunState *crs = cls;
crs->cro = NULL;
@@ -96,6 +116,47 @@ challenge_run_cb (void *cls,
TALER_TESTING_interpreter_fail (crs->is);
return;
}
+
+ if (http_status == MHD_HTTP_PAYMENT_REQUIRED)
+ {
+ const char *m;
+
+ if (0 != strncmp (crd->payment_request,
+ "taler://pay/http",
+ strlen ("taler://pay/http")))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Did not find `%s' in `%s'\n",
+ "/-/-/",
+ crd->payment_request);
+ TALER_TESTING_interpreter_fail (crs->is);
+ return;
+ }
+ m = strstr (crd->payment_request, "/-/-/");
+ if (NULL == m)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Did not find `%s' in `%s'\n",
+ "/-/-/",
+ crd->payment_request);
+ TALER_TESTING_interpreter_fail (pss->is);
+ /* NOTE: The above is a simplifying assumption for the
+ test-logic, hitting this code merely means that
+ the assumptions for the test (i.e. no instance) are
+ not satisfied, it is not inherently the case that
+ the above token must appear in the payment request!
+
+ So if you hit this, you might just want to modify
+ the code here to handle this better! */
+ return;
+ }
+ crs->payment_order_id = GNUNET_strdup (&m[strlen ("/-/-/")]);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Order ID from Anastasis service is `%s'\n",
+ pss->payment_order_id);
+ }
+
+
FILE *file;
crs->code = malloc (sizeof(char) * 22);
file = fopen (response_string, "r");
@@ -135,6 +196,10 @@ challenge_run_create_traits (void *cls,
struct TALER_TESTING_Trait traits[] = {
ANASTASIS_TESTING_make_trait_code (0,
crs->code),
+ TALER_TESTING_make_trait_claim_token (0,
+ &pss->token),
+ TALER_TESTING_make_trait_order_id (0,
+ pss->payment_order_id),
TALER_TESTING_trait_end ()
};
diff --git a/src/lib/testing_api_cmd_keyshare_lookup.c
b/src/lib/testing_api_cmd_keyshare_lookup.c
index a2d5574..dcd7796 100644
--- a/src/lib/testing_api_cmd_keyshare_lookup.c
+++ b/src/lib/testing_api_cmd_keyshare_lookup.c
@@ -76,6 +76,16 @@ struct KeyShareLookupState
* Mode for the lookup(0 = question, 1 = code based)
*/
int lookup_mode;
+ /**
+ * Payment secret used for the payment
+ */
+ const struct ANASTASIS_PaymentSecretP payment_secret;
+
+ /**
+ * if payment is needed or free
+ */
+ int payment_requested;
+
};
/**
@@ -198,6 +208,8 @@ keyshare_lookup_run (void *cls,
ksls->anastasis_url,
ksls->truth_public_key,
&ksls->truth_key,
+ ksls->payment_requested,
+ &ksls->payment_secret,
ksls->answer,
&keyshare_lookup_cb,
ksls);
@@ -276,6 +288,9 @@ ANASTASIS_TESTING_cmd_keyshare_lookup (const char *label,
char *answer,
const struct
ANASTASIS_CRYPTO_TruthKeyP key,
+ const struct
+ ANASTASIS_PaymentSecretP
*payment_secret,
+ int payment_requested,
const char *upload_ref,
int lookup_mode)
{
@@ -293,6 +308,8 @@ ANASTASIS_TESTING_cmd_keyshare_lookup (const char *label,
ksls->http_status = http_status;
ksls->anastasis_url = anastasis_url;
ksls->upload_reference = upload_ref;
+ ksls->payment_secret = payment_secret;
+ ksls->payment_requested = payment_requested;
ksls->answer = answer;
ksls->truth_key = key;
ksls->lookup_mode = lookup_mode;
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-anastasis] branch master updated: work on payment service,
gnunet <=