/* This file is part of TALER 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 General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. TALER is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, see */ /** * @file test_kyc_api.c * @brief testcase to test exchange's HTTP API interface * @author Sree Harsha Totakura * @author Christian Grothoff * @author Marcello Stanisci */ #include "platform.h" #include #include #include #include #include #include #include #include #include #include #include "taler_merchant_testing_lib.h" /** * Configuration file we use. One (big) configuration is used * for the various components for this test. */ #define CONFIG_FILE "test_kyc_api.conf" /** * Exchange base URL. Could also be taken from config. */ #define EXCHANGE_URL "http://localhost:8081/" /** * Payto URI of the customer (payer). */ static const char *payer_payto; /** * Payto URI of the exchange (escrow account). */ static const char *exchange_payto; /** * Payto URI of the merchant (receiver). */ static const char *merchant_payto; /** * Credentials for the test. */ static struct TALER_TESTING_Credentials cred; /** * Merchant base URL. */ static const char *merchant_url; /** * Merchant instance "i1a" base URL. */ static char *merchant_url_i1a; /** * Account number of the exchange at the bank. */ #define EXCHANGE_ACCOUNT_NAME "2" /** * Account number of some user. */ #define USER_ACCOUNT_NAME "62" /** * Account number used by the merchant */ #define MERCHANT_ACCOUNT_NAME "3" /** * Execute the taler-exchange-aggregator and transfer commands with * our configuration file. * * @param label label to use for the command. */ #define CMD_EXEC_AGGREGATOR(label) \ TALER_TESTING_cmd_exec_aggregator_with_kyc (label "-aggregator", \ CONFIG_FILE), \ TALER_TESTING_cmd_exec_transfer (label "-transfer", CONFIG_FILE) /** * Execute the taler-exchange-wirewatch command with * our configuration file. * * @param label label to use for the command. */ #define CMD_EXEC_WIREWATCH(label) \ TALER_TESTING_cmd_exec_wirewatch2 ( \ label, \ CONFIG_FILE, \ "exchange-account-exchange") /** * Run wire transfer of funds from some user's account to the * exchange. * * @param label label to use for the command. * @param amount amount to transfer, i.e. "EUR:1" * @param url exchange_url */ static struct TALER_TESTING_Command cmd_transfer_to_exchange (const char *label, const char *amount) { return TALER_TESTING_cmd_admin_add_incoming (label, amount, &cred.ba, payer_payto); } /** * Main function that will tell the interpreter what commands to * run. * * @param cls closure */ static void run (void *cls, struct TALER_TESTING_Interpreter *is) { struct TALER_TESTING_Command pay[] = { /** * Move money to the exchange's bank account. */ cmd_transfer_to_exchange ( "create-reserve-1", "EUR:10.02"), /** * Make a reserve exist, according to the previous transfer. */ TALER_TESTING_cmd_exec_wirewatch ( "wirewatch-1", CONFIG_FILE), TALER_TESTING_cmd_check_bank_admin_transfer ( "check_bank_transfer-2", "EUR:10.02", payer_payto, exchange_payto, "create-reserve-1"), TALER_TESTING_cmd_withdraw_amount ( "withdraw-coin-1", "create-reserve-1", "EUR:5", 0, MHD_HTTP_OK), TALER_TESTING_cmd_withdraw_amount ( "withdraw-coin-2", "create-reserve-1", "EUR:5", 0, MHD_HTTP_OK), TALER_TESTING_cmd_merchant_get_orders ( "get-orders-empty", merchant_url, MHD_HTTP_OK, NULL), /** * Check the reserve is depleted. */ TALER_TESTING_cmd_status ( "withdraw-status-1", "create-reserve-1", "EUR:0", MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders2 ( "create-proposal-1", cred.cfg, merchant_url, MHD_HTTP_OK, "1", /* order ID */ GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, true, "EUR:5.0", "x-taler-bank", "", "", NULL), TALER_TESTING_cmd_merchant_claim_order ( "reclaim-1", merchant_url, MHD_HTTP_OK, "create-proposal-1", NULL), TALER_TESTING_cmd_merchant_get_instance ( "get-default-instance", merchant_url, NULL, MHD_HTTP_OK, "instance-create-default-setup"), TALER_TESTING_cmd_admin_add_kycauth ( "merchant-kyc-auth-transfer", "EUR:0.01", &cred.ba, merchant_payto, "get-default-instance"), CMD_EXEC_WIREWATCH ( "import-kyc-account-withdraw"), TALER_TESTING_cmd_merchant_pay_order ( "deposit-simple", merchant_url, MHD_HTTP_OK, "create-proposal-1", "withdraw-coin-1", "EUR:5", "EUR:4.99", "session-0"), TALER_TESTING_cmd_merchant_post_orders_paid ( "verify-order-1-paid", merchant_url, "deposit-simple", "session-1", MHD_HTTP_OK), TALER_TESTING_cmd_check_bank_empty ( "check_bank_empty-1"), CMD_EXEC_AGGREGATOR ( "run-aggregator"), /* KYC: hence nothing happened at the bank yet: */ TALER_TESTING_cmd_check_bank_empty ( "check_bank_empty-2"), /* KYC: we don't even know the legitimization UUID yet */ TALER_TESTING_cmd_merchant_kyc_get ( "kyc-pending-early", merchant_url, NULL, NULL, EXCHANGE_URL, TALER_EXCHANGE_KLPT_NONE, MHD_HTTP_OK, true), /* now we get the legi UUID by running taler-merchant-depositcheck */ TALER_TESTING_cmd_depositcheck ( "deposit-check", CONFIG_FILE), /* Now we should get a status of pending */ TALER_TESTING_cmd_merchant_kyc_get ( "kyc-pending", merchant_url, NULL, /* default instance */ "instance-create-default-account", /* h_wire_ref: which account to query */ EXCHANGE_URL, TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_OK, true), TALER_TESTING_cmd_get_kyc_info ( "get-kyc-info-deposit", "kyc-pending", MHD_HTTP_OK), TALER_TESTING_cmd_post_kyc_start ( "start-kyc-process-withdraw", "get-kyc-info-deposit", 0, MHD_HTTP_OK), TALER_TESTING_cmd_proof_kyc_oauth2 ( "kyc-do", "kyc-pending", "test-oauth2", "pass", MHD_HTTP_SEE_OTHER), CMD_EXEC_AGGREGATOR ("run-aggregator"), TALER_TESTING_cmd_check_bank_transfer ( "check_bank_transfer-498c", EXCHANGE_URL, "EUR:4.98", exchange_payto, merchant_payto), TALER_TESTING_cmd_merchant_post_transfer ( "post-transfer-1", &cred.ba, merchant_payto, merchant_url, "EUR:4.98", MHD_HTTP_NO_CONTENT, "deposit-simple", NULL), TALER_TESTING_cmd_run_tme ( "run taler-merchant-reconciliation-1", CONFIG_FILE), TALER_TESTING_cmd_merchant_get_transfers ( "get-transfers-1", merchant_url, merchant_payto, MHD_HTTP_OK, "post-transfer-1", NULL), TALER_TESTING_cmd_check_bank_empty ( "check_bank_empty-3"), TALER_TESTING_cmd_end () }; struct TALER_TESTING_Command aml[] = { TALER_TESTING_cmd_set_officer ( "aml-officer", NULL, "Ernest&Young", true, false), cmd_transfer_to_exchange ( "create-reserve-big", "EUR:100.02"), TALER_TESTING_cmd_exec_wirewatch ( "wirewatch-big", CONFIG_FILE), TALER_TESTING_cmd_take_aml_decision ( "freeze", "aml-officer", "post-transfer-1", true /* keep investigating */, GNUNET_TIME_UNIT_HOURS /* expiration */, NULL /* successor measure: default */, "{\"rules\":" "[" " {" " \"timeframe\":{\"d_us\":3600000000}" " ,\"threshold\":\"EUR:1\"" " ,\"operation_type\":\"WITHDRAW\"" " ,\"verboten\":true" " }" " ,{" " \"timeframe\":{\"d_us\":3600000000}" " ,\"threshold\":\"EUR:1\"" " ,\"operation_type\":\"AGGREGATE\"" " ,\"display_priority\":65536" " ,\"measures\":[\"form-measure\"]" " ,\"verboten\":false" " }" "]" /* end rules */ ",\"new_measure\":\"form-measure\"" ",\"custom_measures\":" " {" " \"form-measure\":" " {" " \"check_name\":\"test-form\"" " ,\"prog_name\":\"test-form-check\"" " }" " }" /* end custom measures */ "}", "{}" /* properties */, "suspicious", MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_check_bank_admin_transfer ( "check_bank_transfer-big", "EUR:100.02", payer_payto, exchange_payto, "create-reserve-big"), TALER_TESTING_cmd_withdraw_amount ( "withdraw-coin-aml", "create-reserve-big", "EUR:5", 0, MHD_HTTP_OK), TALER_TESTING_cmd_merchant_post_orders2 ( "create-proposal-aml", cred.cfg, merchant_url, MHD_HTTP_OK, "10-aml", /* order ID */ GNUNET_TIME_UNIT_ZERO_TS, GNUNET_TIME_UNIT_FOREVER_TS, true, "EUR:5.0", "x-taler-bank", "", "", NULL), TALER_TESTING_cmd_merchant_claim_order ( "reclaim-aml", merchant_url, MHD_HTTP_OK, "create-proposal-aml", NULL), TALER_TESTING_cmd_merchant_pay_order ( "deposit-simple", merchant_url, MHD_HTTP_OK, "create-proposal-aml", "withdraw-coin-aml", "EUR:5", "EUR:4.99", "session-aml"), TALER_TESTING_cmd_merchant_post_orders_paid ( "verify-order-aml-paid", merchant_url, "deposit-simple", "session-aml", MHD_HTTP_OK), TALER_TESTING_cmd_check_bank_empty ( "check_bank_empty-aml-1"), CMD_EXEC_AGGREGATOR ("run-aggregator-aml-frozen"), /* AML-frozen: hence nothing happened at the bank yet: */ TALER_TESTING_cmd_check_bank_empty ( "check_bank_empty-aml-2"), /* Now we should get a status of KYC required */ TALER_TESTING_cmd_merchant_kyc_get ( "aml-frozen-kyc-required", merchant_url, NULL, /* no instance ID */ NULL, /* no wire ref */ EXCHANGE_URL, TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER, MHD_HTTP_OK, true), TALER_TESTING_cmd_sleep ( "sleep to de-collide AML timestamps", 1), TALER_TESTING_cmd_take_aml_decision ( "unfreeze", "aml-officer", "post-transfer-1", true /* keep investigating */, GNUNET_TIME_UNIT_HOURS /* expiration */, NULL /* new measure: none */, "{\"rules\":[" "{\"timeframe\":{\"d_us\":3600000000}," " \"threshold\":\"EUR:100\"," " \"operation_type\":\"WITHDRAW\"," " \"verboten\":true" "}" "]}" /* new rules */, "{}" /* properties */, "fine", MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_kyc_get ( "aml-unfrozen", merchant_url, NULL, /* no instance ID */ NULL, /* no wire ref */ EXCHANGE_URL, TALER_EXCHANGE_KLPT_KYC_OK, MHD_HTTP_OK, true), CMD_EXEC_AGGREGATOR ("run-aggregator-aml-normal"), TALER_TESTING_cmd_check_bank_transfer ( "check_bank_transfer-498c-post-unfreeze", EXCHANGE_URL, "EUR:4.98", exchange_payto, merchant_payto), TALER_TESTING_cmd_merchant_post_transfer ( "post-transfer-aml", &cred.ba, merchant_payto, merchant_url, "EUR:4.98", MHD_HTTP_NO_CONTENT, "deposit-simple", NULL), TALER_TESTING_cmd_run_tme ( "run taler-merchant-reconciliation-2-aml", CONFIG_FILE), TALER_TESTING_cmd_merchant_get_transfers ( "get-transfers-aml", merchant_url, merchant_payto, MHD_HTTP_OK, "post-transfer-1", "post-transfer-aml", NULL), TALER_TESTING_cmd_end () }; /* end of aml batch */ struct TALER_TESTING_Command commands[] = { /* general setup */ TALER_TESTING_cmd_run_fakebank ( "run-fakebank", cred.cfg, "exchange-account-exchange"), TALER_TESTING_cmd_system_start ( "start-taler", CONFIG_FILE, "-ema", "-u", "exchange-account-exchange", NULL), TALER_TESTING_cmd_get_exchange ( "get-exchange", cred.cfg, NULL, true, true), TALER_TESTING_cmd_oauth_with_birthdate ( "start-oauth-service", "2005-00-00", 6666), TALER_TESTING_cmd_merchant_post_instances ( "instance-create-default-setup", merchant_url, "default", MHD_HTTP_NO_CONTENT), TALER_TESTING_cmd_merchant_post_account ( "instance-create-default-account", merchant_url, merchant_payto, NULL, NULL, MHD_HTTP_OK), TALER_TESTING_cmd_batch ("pay", pay), TALER_TESTING_cmd_batch ("aml", aml), TALER_TESTING_cmd_end () }; TALER_TESTING_run (is, commands); } int main (int argc, char *const *argv) { payer_payto = "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME "?receiver-name=" USER_ACCOUNT_NAME; exchange_payto = "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME "?receiver-name=" EXCHANGE_ACCOUNT_NAME; merchant_payto = "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME "?receiver-name=" MERCHANT_ACCOUNT_NAME; merchant_url = "http://localhost:8080/"; GNUNET_asprintf (&merchant_url_i1a, "%sinstances/i1a/", merchant_url); return TALER_TESTING_main (argv, "INFO", CONFIG_FILE, "exchange-account-exchange", TALER_TESTING_BS_FAKEBANK, &cred, &run, NULL); } /* end of test_kyc_api.c */