diff options
author | Christian Grothoff <christian@grothoff.org> | 2021-08-15 10:11:17 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2021-08-15 10:11:17 +0200 |
commit | 3d7de36cdd35fbfe95ba20c30b37cd81249b076b (patch) | |
tree | e466ac66b7ad9d388ff4c1e72d28e8372c68cb3c /src | |
parent | 6f0432ed839d1f5a7a1e880f492ce162073b680b (diff) | |
download | anastasis-3d7de36cdd35fbfe95ba20c30b37cd81249b076b.tar.gz anastasis-3d7de36cdd35fbfe95ba20c30b37cd81249b076b.tar.bz2 anastasis-3d7de36cdd35fbfe95ba20c30b37cd81249b076b.zip |
expand database plugin with logic to store wire transfer data made for authentication
Diffstat (limited to 'src')
-rw-r--r-- | src/include/anastasis_database_plugin.h | 64 | ||||
-rw-r--r-- | src/stasis/plugin_anastasis_postgres.c | 194 | ||||
-rw-r--r-- | src/stasis/stasis-0001.sql | 29 |
3 files changed, 287 insertions, 0 deletions
diff --git a/src/include/anastasis_database_plugin.h b/src/include/anastasis_database_plugin.h index 44f6b55..ae414dc 100644 --- a/src/include/anastasis_database_plugin.h +++ b/src/include/anastasis_database_plugin.h @@ -142,6 +142,23 @@ typedef void /** + * Function called to test if a given wire transfer + * satisfied the authentication requirement of the + * IBAN plugin. + * + * @param cls closure + * @param credit amount that was transferred + * @param wire_subject subject provided in the wire transfer + * @return true if this wire transfer satisfied the authentication check + */ +typedef bool +(*ANASTASIS_DB_AuthIbanTransfercheck)( + void *cls, + const struct TALER_Amount *credit, + const char *wire_subject); + + +/** * Handle to interact with the database. * * Functions ending with "_TR" run their OWN transaction scope @@ -715,6 +732,53 @@ struct ANASTASIS_DatabasePlugin /** + * Store inbound IBAN payment made for authentication. + * + * @param cls closure + * @param wire_reference unique identifier inside LibEuFin/Nexus + * @param wire_subject subject of the wire transfer + * @param amount how much was transferred + * @param debit_account account that was debited + * @param credit_account Anastasis operator account credited + * @param execution_date when was the transfer made + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*record_auth_iban_payment)( + void *cls, + uint64_t wire_reference, + const char *wire_subject, + const struct TALER_Amount *amount, + const char *debit_account, + const char *credit_account, + struct GNUNET_TIME_Absolute execution_date); + + + /** + * Function to check if we are aware of a wire transfer + * that satisfies the IBAN plugin's authentication check. + * + * @param cls closure + * @param debit_account which debit account to check + * @param earliest_date earliest date to check + * @param cb function to call on all entries found + * @param cb_cls closure for @a cb + * @return transaction status, + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if @a cb + * returned 'true' once + * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no + * wire transfers existed for which @a cb returned true + */ + enum GNUNET_DB_QueryStatus + (*test_auth_iban_payment)( + void *cls, + const char *debit_account, + struct GNUNET_TIME_Absolute earliest_date, + ANASTASIS_DB_AuthIbanTransfercheck cb, + void *cb_cls); + + + /** * Function called to remove all expired codes from the database. * * @return transaction status diff --git a/src/stasis/plugin_anastasis_postgres.c b/src/stasis/plugin_anastasis_postgres.c index 25c4dd3..1544367 100644 --- a/src/stasis/plugin_anastasis_postgres.c +++ b/src/stasis/plugin_anastasis_postgres.c @@ -1122,6 +1122,174 @@ postgres_record_challenge_refund ( /** + * Store inbound IBAN payment made for authentication. + * + * @param cls closure + * @param wire_reference unique identifier inside LibEuFin/Nexus + * @param wire_subject subject of the wire transfer + * @param amount how much was transferred + * @param debit_account account that was debited + * @param credit_account Anastasis operator account credited + * @param execution_date when was the transfer made + * @return transaction status + */ +static enum GNUNET_DB_QueryStatus +postgres_record_auth_iban_payment ( + void *cls, + uint64_t wire_reference, + const char *wire_subject, + const struct TALER_Amount *amount, + const char *debit_account, + const char *credit_account, + struct GNUNET_TIME_Absolute execution_date) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_uint64 (&wire_reference), + GNUNET_PQ_query_param_string (wire_subject), + TALER_PQ_query_param_amount (amount), + GNUNET_PQ_query_param_string (debit_account), + GNUNET_PQ_query_param_string (credit_account), + GNUNET_PQ_query_param_absolute_time (&execution_date), + GNUNET_PQ_query_param_end + }; + + check_connection (pg); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "store_auth_iban_payment_details", + params); +} + + +/** + * Closure for #test_auth_cb. + */ +struct TestIbanContext +{ + + /** + * Plugin context. + */ + struct PostgresClosure *pg; + + /** + * Function to call on each wire transfer found. + */ + ANASTASIS_DB_AuthIbanTransfercheck cb; + + /** + * Closure for @a cb. + */ + void *cb_cls; + + /** + * Value to return. + */ + enum GNUNET_DB_QueryStatus qs; +}; + + +/** + * Helper function for #postgres_test_auth_iban_payment(). + * To be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct TestIbanContext *` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +test_auth_cb (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct TestIbanContext *tic = cls; + struct PostgresClosure *pg = tic->pg; + + for (unsigned int i = 0; i<num_results; i++) + { + struct TALER_Amount credit; + char *wire_subject; + struct GNUNET_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_amount ("credit", + pg->currency, + &credit), + GNUNET_PQ_result_spec_string ("wire_subject", + &wire_subject), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + tic->qs = GNUNET_DB_STATUS_HARD_ERROR; + return; + } + if (tic->cb (tic->cb_cls, + &credit, + wire_subject)) + { + GNUNET_free (wire_subject); + tic->qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; + return; + } + GNUNET_free (wire_subject); + } +} + + +/** + * Function to check if we are aware of a wire transfer + * that satisfies the IBAN plugin's authentication check. + * + * @param cls closure + * @param debit_account which debit account to check + * @param earliest_date earliest date to check + * @param cb function to call on all entries found + * @param cb_cls closure for @a cb + * @return transaction status, + * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if @a cb + * returned 'true' once + * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no + * wire transfers existed for which @a cb returned true + */ +static enum GNUNET_DB_QueryStatus +postgres_test_auth_iban_payment ( + void *cls, + const char *debit_account, + struct GNUNET_TIME_Absolute earliest_date, + ANASTASIS_DB_AuthIbanTransfercheck cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct TestIbanContext tic = { + .cb = cb, + .cb_cls = cb_cls, + .pg = pg + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_string (debit_account), + TALER_PQ_query_param_absolute_time (&earliest_date), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + check_connection (pg); + qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, + "test_auth_iban_payment", + params, + &test_auth_cb, + &tic); + if (qs < 0) + return qs; + return tic.qs; +} + + +/** * Check payment identifier. Used to check if a payment identifier given by * the user is valid (existing and paid). * @@ -2210,6 +2378,30 @@ libanastasis_plugin_db_postgres_init (void *cls) ") VALUES " "($1, $2, $3, $4, $5, $6);", 6), + + GNUNET_PQ_make_prepare ("test_auth_iban_payment", + "SELECT" + " credit_val" + ",credit_frac" + ",wire_subject" + " FROM anastasis_auth_iban_in" + " WHERE debit_account_details=$1" + " AND execution_date>=$2;", + 2), + GNUNET_PQ_make_prepare ("store_auth_iban_payment_details", + "INSERT INTO anastasis_auth_iban_in " + "(wire_reference" + ",wire_subject" + ",credit_val" + ",credit_frac" + ",debit_account_details" + ",credit_account_details" + ",execution_date" + ") VALUES " + "($1, $2, $3, $4, $5, $6, $7);", + 7), + + GNUNET_PQ_make_prepare ("recovery_document_insert", "INSERT INTO anastasis_recoverydocument " "(user_id" @@ -2410,6 +2602,8 @@ libanastasis_plugin_db_postgres_init (void *cls) plugin->check_challenge_payment = &postgres_check_challenge_payment; plugin->lookup_challenge_payment = &postgres_lookup_challenge_payment; plugin->update_challenge_payment = &postgres_update_challenge_payment; + plugin->record_auth_iban_payment = &postgres_record_auth_iban_payment; + plugin->test_auth_iban_payment = &postgres_test_auth_iban_payment; return plugin; } diff --git a/src/stasis/stasis-0001.sql b/src/stasis/stasis-0001.sql index 87dde94..e0ebfa6 100644 --- a/src/stasis/stasis-0001.sql +++ b/src/stasis/stasis-0001.sql @@ -193,5 +193,34 @@ COMMENT ON INDEX anastasis_challengecode_expiration_index IS 'for challenge garbage collection'; +CREATE TABLE IF NOT EXISTS anastasis_auth_iban_in + (auth_in_serial_id BIGSERIAL UNIQUE + ,wire_reference INT8 NOT NULL PRIMARY KEY + ,wire_subject TEXT NOT NULL + ,credit_val INT8 NOT NULL + ,credit_frac INT4 NOT NULL + ,debit_account_details TEXT NOT NULL + ,credit_account_details TEXT NOT NULL + ,execution_date INT8 NOT NULL + ); +COMMENT ON TABLE anastasis_auth_iban_in + IS 'list of IBAN wire transfers for authentication using the IBAN plugin'; +COMMENT ON COLUMN anastasis_auth_iban_in.wire_reference + IS 'Unique number identifying the wire transfer in LibEuFin/Nexus'; +COMMENT ON COLUMN anastasis_auth_iban_in.wire_subject + IS 'For authentication, this contains the code, but also additional text'; +COMMENT ON COLUMN anastasis_auth_iban_in.execution_date + IS 'Used both for (theoretical) garbage collection and to see if the transfer happened on time'; +COMMENT ON COLUMN anastasis_auth_iban_in.credit_account_details + IS 'Identifies the bank account of the Anastasis provider, which could change over time'; +COMMENT ON COLUMN anastasis_auth_iban_in.debit_account_details + IS 'Identifies the bank account of the customer, which must match what was given in the truth'; + +CREATE INDEX IF NOT EXISTS anastasis_auth_iban_in_lookup_index + ON anastasis_auth_iban_in + (debit_account_details + ,execution_date + ); + -- Complete transaction COMMIT; |