From a82d8fab696d3fca24c2f1c48a1646107e38cef8 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 10 Jan 2023 17:31:01 +0100 Subject: wallet-core: KYC mvp Only hard withdrawal KYC is supporte so far, and no long-polling is done yet. --- packages/taler-harness/src/harness/harness.ts | 11 ++ .../taler-harness/src/integrationtests/test-kyc.ts | 204 +++++++++++++++++++++ .../src/integrationtests/testrunner.ts | 50 ++--- 3 files changed, 241 insertions(+), 24 deletions(-) create mode 100644 packages/taler-harness/src/integrationtests/test-kyc.ts (limited to 'packages/taler-harness') diff --git a/packages/taler-harness/src/harness/harness.ts b/packages/taler-harness/src/harness/harness.ts index a9298637f..5b72cbc06 100644 --- a/packages/taler-harness/src/harness/harness.ts +++ b/packages/taler-harness/src/harness/harness.ts @@ -1081,6 +1081,17 @@ export class ExchangeService implements ExchangeServiceInterface { return this.exchangeConfig.httpPort; } + /** + * Run a function that modifies the existing exchange configuration. + * The modified exchange configuration will then be written to the + * file system. + */ + async modifyConfig(f: (config: Configuration) => Promise): Promise { + const config = Configuration.load(this.configFilename); + await f(config); + config.write(this.configFilename); + } + async addBankAccount( localName: string, exchangeBankAccount: HarnessExchangeBankAccount, diff --git a/packages/taler-harness/src/integrationtests/test-kyc.ts b/packages/taler-harness/src/integrationtests/test-kyc.ts new file mode 100644 index 000000000..40474fb6f --- /dev/null +++ b/packages/taler-harness/src/integrationtests/test-kyc.ts @@ -0,0 +1,204 @@ +/* + This file is part of GNU Taler + (C) 2020 Taler Systems S.A. + + GNU 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. + + GNU 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 + GNU Taler; see the file COPYING. If not, see + */ + +/** + * Imports. + */ +import { Duration } from "@gnu-taler/taler-util"; +import { CoinConfig, defaultCoinConfig } from "../harness/denomStructures.js"; +import { + BankService, + ExchangeService, + getPayto, + GlobalTestState, + MerchantService, + setupDb, + WalletCli, +} from "../harness/harness.js"; +import { + withdrawViaBank, + makeTestPayment, + EnvOptions, + SimpleTestEnvironment, +} from "../harness/helpers.js"; + +export async function createKycTestkudosEnvironment( + t: GlobalTestState, + coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS")), + opts: EnvOptions = {}, +): Promise { + const db = await setupDb(t); + + const bank = await BankService.create(t, { + allowRegistrations: true, + currency: "TESTKUDOS", + database: db.connStr, + httpPort: 8082, + }); + + const exchange = ExchangeService.create(t, { + name: "testexchange-1", + currency: "TESTKUDOS", + httpPort: 8081, + database: db.connStr, + }); + + const merchant = await MerchantService.create(t, { + name: "testmerchant-1", + currency: "TESTKUDOS", + httpPort: 8083, + database: db.connStr, + }); + + const exchangeBankAccount = await bank.createExchangeAccount( + "myexchange", + "x", + ); + exchange.addBankAccount("1", exchangeBankAccount); + + bank.setSuggestedExchange(exchange, exchangeBankAccount.accountPaytoUri); + + await bank.start(); + + await bank.pingUntilAvailable(); + + const ageMaskSpec = opts.ageMaskSpec; + + if (ageMaskSpec) { + exchange.enableAgeRestrictions(ageMaskSpec); + // Enable age restriction for all coins. + exchange.addCoinConfigList( + coinConfig.map((x) => ({ + ...x, + name: `${x.name}-age`, + ageRestricted: true, + })), + ); + // For mixed age restrictions, we also offer coins without age restrictions + if (opts.mixedAgeRestriction) { + exchange.addCoinConfigList( + coinConfig.map((x) => ({ ...x, ageRestricted: false })), + ); + } + } else { + exchange.addCoinConfigList(coinConfig); + } + + await exchange.modifyConfig(async (config) => { + const myprov = "kyc-provider-myprov"; + config.setString(myprov, "cost", "0"); + config.setString(myprov, "logic", "oauth2"); + config.setString(myprov, "provided_checks", "dummy1"); + config.setString(myprov, "user_type", "individual"); + config.setString(myprov, "kyc_oauth2_validity", "forever"); + config.setString( + myprov, + "kyc_oauth2_auth_url", + "http://localhost:6666/oauth/v2/token", + ); + config.setString( + myprov, + "kyc_oauth2_login_url", + "http://localhost:6666/oauth/v2/login", + ); + config.setString( + myprov, + "kyc_oauth2_info_url", + "http://localhost:6666/oauth/v2/login", + ); + config.setString( + myprov, + "kyc_oauth2_client_id", + "taler-exchange", + ); + config.setString( + myprov, + "kyc_oauth2_client_secret", + "exchange-secret", + ); + config.setString( + myprov, + "kyc_oauth2_post_url", + "https://taler.com", + ); + + config.setString("kyc-legitimization-withdraw1", "operation_type", "withdraw"); + config.setString("kyc-legitimization-withdraw1", "required_checks", "dummy1"); + config.setString("kyc-legitimization-withdraw1", "timeframe", "1d"); + config.setString("kyc-legitimization-withdraw1", "threshold", "TESTKUDOS:5"); + }); + + await exchange.start(); + await exchange.pingUntilAvailable(); + + merchant.addExchange(exchange); + + await merchant.start(); + await merchant.pingUntilAvailable(); + + await merchant.addInstance({ + id: "default", + name: "Default Instance", + paytoUris: [getPayto("merchant-default")], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }); + + await merchant.addInstance({ + id: "minst1", + name: "minst1", + paytoUris: [getPayto("minst1")], + defaultWireTransferDelay: Duration.toTalerProtocolDuration( + Duration.fromSpec({ minutes: 1 }), + ), + }); + + console.log("setup done!"); + + const wallet = new WalletCli(t); + + return { + commonDb: db, + exchange, + merchant, + wallet, + bank, + exchangeBankAccount, + }; +} + +export async function runKycTest(t: GlobalTestState) { + // Set up test environment + + const { wallet, bank, exchange, merchant } = + await createKycTestkudosEnvironment(t); + + // Withdraw digital cash into the wallet. + + await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" }); + + const order = { + summary: "Buy me!", + amount: "TESTKUDOS:5", + fulfillment_url: "taler://fulfillment-success/thx", + }; + + await makeTestPayment(t, { wallet, merchant, order }); + await wallet.runUntilDone(); +} + +runKycTest.suites = ["wallet"]; diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts b/packages/taler-harness/src/integrationtests/testrunner.ts index 4b1c28bde..9e64a151a 100644 --- a/packages/taler-harness/src/integrationtests/testrunner.ts +++ b/packages/taler-harness/src/integrationtests/testrunner.ts @@ -96,6 +96,7 @@ import { runWalletBalanceTest } from "./test-wallet-balance.js"; import { runAgeRestrictionsMixedMerchantTest } from "./test-age-restrictions-mixed-merchant.js"; import { runWalletCryptoWorkerTest } from "./test-wallet-cryptoworker.js"; import { runWithdrawalHighTest } from "./test-withdrawal-high.js"; +import { runKycTest } from "./test-kyc.js"; /** * Test runner. @@ -113,75 +114,76 @@ interface TestMainFunction { const allTests: TestMainFunction[] = [ runAgeRestrictionsMerchantTest, - runAgeRestrictionsPeerTest, runAgeRestrictionsMixedMerchantTest, + runAgeRestrictionsPeerTest, runBankApiTest, runClaimLoopTest, runClauseSchnorrTest, - runWalletCryptoWorkerTest, - runDepositTest, runDenomUnofferedTest, + runDepositTest, runExchangeManagementTest, runExchangeTimetravelTest, runFeeRegressionTest, runForcedSelectionTest, - runLibeufinBasicTest, - runLibeufinKeyrotationTest, - runLibeufinTutorialTest, - runLibeufinRefundTest, - runLibeufinC5xTest, - runLibeufinNexusBalanceTest, - runLibeufinBadGatewayTest, - runLibeufinRefundMultipleUsersTest, - runLibeufinApiPermissionsTest, - runLibeufinApiFacadeTest, - runLibeufinApiFacadeBadRequestTest, + runKycTest, runLibeufinAnastasisFacadeTest, - runLibeufinApiSchedulingTest, - runLibeufinApiUsersTest, runLibeufinApiBankaccountTest, runLibeufinApiBankconnectionTest, - runLibeufinApiSandboxTransactionsTest, + runLibeufinApiFacadeBadRequestTest, + runLibeufinApiFacadeTest, + runLibeufinApiPermissionsTest, runLibeufinApiSandboxCamtTest, + runLibeufinApiSandboxTransactionsTest, + runLibeufinApiSchedulingTest, + runLibeufinApiUsersTest, + runLibeufinBadGatewayTest, + runLibeufinBasicTest, + runLibeufinC5xTest, + runLibeufinKeyrotationTest, + runLibeufinNexusBalanceTest, + runLibeufinRefundMultipleUsersTest, + runLibeufinRefundTest, runLibeufinSandboxWireTransferCliTest, + runLibeufinTutorialTest, runMerchantExchangeConfusionTest, - runMerchantInstancesTest, runMerchantInstancesDeleteTest, + runMerchantInstancesTest, runMerchantInstancesUrlsTest, runMerchantLongpollingTest, - runMerchantSpecPublicOrdersTest, runMerchantRefundApiTest, + runMerchantSpecPublicOrdersTest, runPaymentClaimTest, + runPaymentDemoTest, runPaymentFaultTest, runPaymentForgettableTest, runPaymentIdempotencyTest, runPaymentMultipleTest, runPaymentTest, - runPaymentDemoTest, runPaymentTransientTest, runPaymentZeroTest, runPayPaidTest, runPaywallFlowTest, - runPeerToPeerPushTest, runPeerToPeerPullTest, + runPeerToPeerPushTest, runRefundAutoTest, runRefundGoneTest, runRefundIncrementalTest, runRefundTest, runRevocationTest, runTestWithdrawalManualTest, - runWithdrawalFakebankTest, runTimetravelAutorefreshTest, runTimetravelWithdrawTest, runTippingTest, runWalletBackupBasicTest, runWalletBackupDoublespendTest, runWalletBalanceTest, - runWithdrawalHighTest, - runWallettestingTest, + runWalletCryptoWorkerTest, runWalletDblessTest, + runWallettestingTest, runWithdrawalAbortBankTest, runWithdrawalBankIntegratedTest, + runWithdrawalFakebankTest, + runWithdrawalHighTest, ]; export interface TestRunSpec { -- cgit v1.2.3