diff options
Diffstat (limited to 'packages/taler-wallet-cli')
5 files changed, 115 insertions, 3 deletions
diff --git a/packages/taler-wallet-cli/src/harness/denomStructures.ts b/packages/taler-wallet-cli/src/harness/denomStructures.ts index 2ca777030..b12857c7e 100644 --- a/packages/taler-wallet-cli/src/harness/denomStructures.ts +++ b/packages/taler-wallet-cli/src/harness/denomStructures.ts @@ -24,6 +24,7 @@ export interface CoinCoinfigCommon { feeDeposit: string; feeRefresh: string; feeRefund: string; + ageRestricted?: boolean; } export interface CoinConfigRsa extends CoinCoinfigCommon { diff --git a/packages/taler-wallet-cli/src/harness/harness.ts b/packages/taler-wallet-cli/src/harness/harness.ts index 30503e488..a2339e5f3 100644 --- a/packages/taler-wallet-cli/src/harness/harness.ts +++ b/packages/taler-wallet-cli/src/harness/harness.ts @@ -430,6 +430,9 @@ function setCoin(config: Configuration, c: CoinConfig) { config.setString(s, "fee_withdraw", c.feeWithdraw); config.setString(s, "fee_refresh", c.feeRefresh); config.setString(s, "fee_refund", c.feeRefund); + if (c.ageRestricted) { + config.setString(s, "age_restricted", "yes"); + } if (c.cipher === "RSA") { config.setString(s, "rsa_keysize", `${c.rsaKeySize}`); config.setString(s, "cipher", "RSA"); @@ -1112,6 +1115,17 @@ export class ExchangeService implements ExchangeServiceInterface { config.write(this.configFilename); } + enableAgeRestrictions(maskStr: string) { + const config = Configuration.load(this.configFilename); + config.setString("exchange-extension-age_restriction", "enabled", "yes"); + config.setString( + "exchange-extension-age_restriction", + "age_groups", + maskStr, + ); + config.write(this.configFilename); + } + get masterPub() { return encodeCrock(this.keyPair.eddsaPub); } @@ -1645,8 +1659,14 @@ export class MerchantService implements MerchantServiceInterface { await exec(`taler-merchant-dbinit -c "${this.configFilename}"`); this.proc = this.globalState.spawnService( - "taler-merchant-httpd", - ["-LDEBUG", "-c", this.configFilename, ...this.timetravelArgArr], + "valgrind", + [ + "taler-merchant-httpd", + "-LDEBUG", + "-c", + this.configFilename, + ...this.timetravelArgArr, + ], `merchant-${this.merchantConfig.name}`, ); } @@ -1848,6 +1868,9 @@ export async function runTestWithState( } } catch (e) { console.error("FATAL: test failed with exception", e); + if (e instanceof TalerError) { + console.error(`error detail: ${j2s(e.errorDetail)}`); + } status = "fail"; } finally { await gc.shutdown(); diff --git a/packages/taler-wallet-cli/src/harness/helpers.ts b/packages/taler-wallet-cli/src/harness/helpers.ts index 3840dcf94..db66efbb6 100644 --- a/packages/taler-wallet-cli/src/harness/helpers.ts +++ b/packages/taler-wallet-cli/src/harness/helpers.ts @@ -65,6 +65,13 @@ export interface SimpleTestEnvironment { wallet: WalletCli; } +export interface EnvOptions { + /** + * If provided, enable age restrictions with the specified age mask string. + */ + ageMaskSpec?: string; +} + /** * Run a test case with a simple TESTKUDOS Taler environment, consisting * of one exchange, one bank and one merchant. @@ -72,6 +79,7 @@ export interface SimpleTestEnvironment { export async function createSimpleTestkudosEnvironment( t: GlobalTestState, coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS")), + opts: EnvOptions = {}, ): Promise<SimpleTestEnvironment> { const db = await setupDb(t); @@ -108,7 +116,17 @@ export async function createSimpleTestkudosEnvironment( await bank.pingUntilAvailable(); - exchange.addCoinConfigList(coinConfig); + const ageMaskSpec = opts.ageMaskSpec; + + if (ageMaskSpec) { + exchange.enableAgeRestrictions(ageMaskSpec); + // Enable age restriction for all coins. + exchange.addCoinConfigList( + coinConfig.map((x) => ({ ...x, ageRestricted: true })), + ); + } else { + exchange.addCoinConfigList(coinConfig); + } await exchange.start(); await exchange.pingUntilAvailable(); @@ -259,6 +277,7 @@ export async function startWithdrawViaBank( bank: BankService; exchange: ExchangeServiceInterface; amount: AmountString; + restrictAge?: number; }, ): Promise<void> { const { wallet, bank, exchange, amount } = p; @@ -270,6 +289,7 @@ export async function startWithdrawViaBank( await wallet.client.call(WalletApiOperation.GetWithdrawalDetailsForUri, { talerWithdrawUri: wop.taler_withdraw_uri, + restrictAge: p.restrictAge, }); await wallet.runPending(); @@ -279,6 +299,7 @@ export async function startWithdrawViaBank( await wallet.client.call(WalletApiOperation.AcceptBankIntegratedWithdrawal, { exchangeBaseUrl: exchange.baseUrl, talerWithdrawUri: wop.taler_withdraw_uri, + restrictAge: p.restrictAge, }); // Confirm it @@ -299,6 +320,7 @@ export async function withdrawViaBank( bank: BankService; exchange: ExchangeServiceInterface; amount: AmountString; + restrictAge?: number; }, ): Promise<void> { const { wallet } = p; diff --git a/packages/taler-wallet-cli/src/integrationtests/test-age-restrictions.ts b/packages/taler-wallet-cli/src/integrationtests/test-age-restrictions.ts new file mode 100644 index 000000000..9f523ae5d --- /dev/null +++ b/packages/taler-wallet-cli/src/integrationtests/test-age-restrictions.ts @@ -0,0 +1,64 @@ +/* + This file is part of GNU Taler + (C) 2022 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 <http://www.gnu.org/licenses/> + */ + +/** + * Imports. + */ +import { defaultCoinConfig } from "../harness/denomStructures.js"; +import { GlobalTestState } from "../harness/harness.js"; +import { + createSimpleTestkudosEnvironment, + withdrawViaBank, + makeTestPayment, +} from "../harness/helpers.js"; + +/** + * Run test for basic, bank-integrated withdrawal and payment. + */ +export async function runAgeRestrictionsTest(t: GlobalTestState) { + // Set up test environment + + const { wallet, bank, exchange, merchant } = + await createSimpleTestkudosEnvironment( + t, + defaultCoinConfig.map((x) => x("TESTKUDOS")), + { + ageMaskSpec: "8:10:12:14:16:18:21", + }, + ); + + // Withdraw digital cash into the wallet. + + await withdrawViaBank(t, { + wallet, + bank, + exchange, + amount: "TESTKUDOS:20", + restrictAge: 13, + }); + + const order = { + summary: "Buy me!", + amount: "TESTKUDOS:5", + fulfillment_url: "taler://fulfillment-success/thx", + minimum_age: 9, + }; + + await makeTestPayment(t, { wallet, merchant, order }); + await wallet.runUntilDone(); +} + +runAgeRestrictionsTest.suites = ["wallet"]; diff --git a/packages/taler-wallet-cli/src/integrationtests/testrunner.ts b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts index d8dc569d2..dcbf84497 100644 --- a/packages/taler-wallet-cli/src/integrationtests/testrunner.ts +++ b/packages/taler-wallet-cli/src/integrationtests/testrunner.ts @@ -25,6 +25,7 @@ import { shouldLingerInTest, TestRunResult, } from "../harness/harness.js"; +import { runAgeRestrictionsTest } from "./test-age-restrictions.js"; import { runBankApiTest } from "./test-bank-api"; import { runClaimLoopTest } from "./test-claim-loop"; import { runClauseSchnorrTest } from "./test-clause-schnorr.js"; @@ -103,6 +104,7 @@ interface TestMainFunction { } const allTests: TestMainFunction[] = [ + runAgeRestrictionsTest, runBankApiTest, runClaimLoopTest, runClauseSchnorrTest, |