gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 02/02: test using multiple form in kyc measures


From: gnunet
Subject: [taler-wallet-core] 02/02: test using multiple form in kyc measures
Date: Tue, 03 Dec 2024 15:13:12 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

commit 5e8bd098b1e1aac592ae893e2798d69aaac6d78c
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue Dec 3 11:13:02 2024 -0300

    test using multiple form in kyc measures
---
 packages/taler-harness/src/harness/environments.ts |  13 +-
 packages/taler-harness/src/index.ts                |   8 +
 .../src/integrationtests/test-kyc-two-forms.ts     | 399 +++++++++++++++++++++
 .../src/integrationtests/testrunner.ts             |   2 +
 4 files changed, 418 insertions(+), 4 deletions(-)

diff --git a/packages/taler-harness/src/harness/environments.ts 
b/packages/taler-harness/src/harness/environments.ts
index d5a4b1376..fa5d4a395 100644
--- a/packages/taler-harness/src/harness/environments.ts
+++ b/packages/taler-harness/src/harness/environments.ts
@@ -1101,9 +1101,14 @@ export async function postAmlDecision(
   t.assertDeepEqual(resp.status, HttpStatusCode.NoContent);
 }
 
+function defaultOnNotification(n: WalletNotification):void {
+  console.log("wallet-core notification", n);
+}
+
+
 export interface KycEnvOptions {
   coinConfig?: CoinConfig[];
-
+  onWalletNotification?: (n: WalletNotification) => void;
   adjustExchangeConfig?(config: Configuration): void;
 }
 
@@ -1118,6 +1123,7 @@ export interface KycTestEnv {
   merchant: MerchantService;
 }
 
+
 export async function createKycTestkudosEnvironment(
   t: GlobalTestState,
   opts: KycEnvOptions = {},
@@ -1206,12 +1212,11 @@ export async function createKycTestkudosEnvironment(
   await walletService.start();
   await walletService.pingUntilAvailable();
 
+
   const walletClient = new WalletClient({
     name: "wallet",
     unixPath: walletService.socketPath,
-    onNotification(n) {
-      console.log("wallet-core notification", n);
-    },
+    onNotification: opts.onWalletNotification ?? defaultOnNotification,
   });
   await walletClient.connect();
   await walletClient.client.call(WalletApiOperation.InitWallet, {
diff --git a/packages/taler-harness/src/index.ts 
b/packages/taler-harness/src/index.ts
index 4de5b1527..de2b27a39 100644
--- a/packages/taler-harness/src/index.ts
+++ b/packages/taler-harness/src/index.ts
@@ -83,6 +83,7 @@ import {
 import { getTestInfo, runTests } from "./integrationtests/testrunner.js";
 import { lintExchangeDeployment } from "./lint.js";
 import { AML_PROGRAM_FROM_ATTRIBUTES_TO_CONTEXT } from 
"integrationtests/test-kyc-skip-expiration.js";
+import { AML_PROGRAM_NEXT_MEASURE_FORM } from 
"integrationtests/test-kyc-two-forms.js";
 
 const logger = new Logger("taler-harness:index.ts");
 
@@ -1451,12 +1452,14 @@ const allAmlPrograms: 
TalerKycAml.AmlProgramDefinition[] = [
     requiredContext: [],
   },
   AML_PROGRAM_FROM_ATTRIBUTES_TO_CONTEXT,
+  AML_PROGRAM_NEXT_MEASURE_FORM,
 ];
 
 amlProgramCli
   .subcommand("run", "run-program")
   .requiredOption("name", ["-n", "--name"], clk.STRING)
   .flag("requires", ["-r"])
+  .flag("inputs", ["-i"])
   .flag("attributes", ["-a"])
   .maybeOption("config", ["-c", "--config"], clk.STRING)
   .action(async (args) => {
@@ -1473,6 +1476,11 @@ amlProgramCli
       console.log(found.requiredContext.join("\n"));
       return;
     }
+    if (args.run.inputs) {
+      logger.info("Reporting requirements");
+      console.log(found.requiredInputs.join("\n"));
+      return;
+    }
 
     if (args.run.attributes) {
       logger.info("reporting attributes");
diff --git a/packages/taler-harness/src/integrationtests/test-kyc-two-forms.ts 
b/packages/taler-harness/src/integrationtests/test-kyc-two-forms.ts
new file mode 100644
index 000000000..b3fb2fcf8
--- /dev/null
+++ b/packages/taler-harness/src/integrationtests/test-kyc-two-forms.ts
@@ -0,0 +1,399 @@
+/*
+ This file is part of GNU Taler
+ (C) 2024 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 {
+  AbsoluteTime,
+  AmountString,
+  amountToBuffer,
+  buildSigPS,
+  codecForAccountKycStatus,
+  codecForAny,
+  codecForKycProcessClientInformation,
+  codecForLegitimizationNeededResponse,
+  codecOptional,
+  Configuration,
+  createNewWalletKycAccount,
+  decodeCrock,
+  eddsaSign,
+  encodeCrock,
+  j2s,
+  Logger,
+  signAmlQuery,
+  TalerKycAml,
+  TalerProtocolTimestamp,
+  TalerSignaturePurpose,
+  TransactionIdStr,
+  TransactionMajorState,
+  TransactionMinorState,
+  WalletKycRequest,
+} from "@gnu-taler/taler-util";
+import { readResponseJsonOrThrow } from "@gnu-taler/taler-util/http";
+import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import {
+  createKycTestkudosEnvironment,
+  postAmlDecision,
+  withdrawViaBankV3,
+} from "../harness/environments.js";
+import { GlobalTestState, harnessHttpLib, waitMs } from 
"../harness/harness.js";
+
+const logger = new Logger("test-kyc-two-forms.ts");
+
+export const AML_PROGRAM_NEXT_MEASURE_FORM: TalerKycAml.AmlProgramDefinition = 
{
+  name: "TWO_FORMS",
+  logic: (input, config) => {
+    const outcome: TalerKycAml.AmlOutcome = {
+      to_investigate: false,
+      properties: {},
+      events: [],
+      new_rules: {
+        expiration_time: { t_s: 1 },
+        rules: [],
+        successor_measure: "M2",
+        custom_measures: {},
+      },
+    };
+    logger.info("aml program TWO FORMS outcome", j2s(outcome));
+
+    return outcome;
+  },
+  requiredAttributes: [],
+  requiredInputs: [],
+  requiredContext: [],
+};
+
+function adjustExchangeConfig(config: Configuration) {
+  config.setString("exchange", "enable_kyc", "yes");
+
+  // config.setString("KYC-RULE-R1", "operation_type", "withdraw");
+  // config.setString("KYC-RULE-R1", "enabled", "yes");
+  // config.setString("KYC-RULE-R1", "exposed", "yes");
+  // config.setString("KYC-RULE-R1", "is_and_combinator", "no");
+  // config.setString("KYC-RULE-R1", "threshold", "TESTKUDOS:5");
+  // config.setString("KYC-RULE-R1", "timeframe", "1d");
+  // config.setString("KYC-RULE-R1", "next_measures", "M1");
+
+  config.setString("KYC-RULE-R1", "operation_type", "balance");
+  config.setString("KYC-RULE-R1", "enabled", "yes");
+  config.setString("KYC-RULE-R1", "exposed", "yes");
+  config.setString("KYC-RULE-R1", "is_and_combinator", "no");
+  config.setString("KYC-RULE-R1", "threshold", "TESTKUDOS:5");
+  config.setString("KYC-RULE-R1", "timeframe", "forever");
+  config.setString("KYC-RULE-R1", "next_measures", "M1");
+
+  config.setString("KYC-MEASURE-M1", "check_name", "C1");
+  config.setString("KYC-MEASURE-M1", "context", "{}");
+  config.setString("KYC-MEASURE-M1", "program", "P1");
+
+  config.setString("KYC-MEASURE-M2", "check_name", "C2");
+  config.setString("KYC-MEASURE-M2", "context", "{}");
+  config.setString("KYC-MEASURE-M2", "program", "P2");
+
+  config.setString("KYC-MEASURE-M3", "check_name", "C3");
+  config.setString("KYC-MEASURE-M3", "context", "{}");
+  config.setString("KYC-MEASURE-M3", "program", "NOP");
+
+  config.setString("KYC-MEASURE-M4", "check_name", "C4");
+  config.setString("KYC-MEASURE-M4", "context", "{}");
+  config.setString("KYC-MEASURE-M4", "program", "NOP");
+
+  config.setString("KYC-MEASURE-MF", "check_name", "SKIP");
+  config.setString("KYC-MEASURE-MF", "context", "{}");
+  config.setString("KYC-MEASURE-MF", "program", "NOP");
+
+  config.setString(
+    "AML-PROGRAM-P1",
+    "command",
+    "taler-harness aml-program run-program --name TWO_FORMS",
+  );
+  config.setString("AML-PROGRAM-P1", "enabled", "true");
+  config.setString("AML-PROGRAM-P1", "description", "remove all rules");
+  config.setString("AML-PROGRAM-P1", "description_i18n", "{}");
+  config.setString("AML-PROGRAM-P1", "fallback", "M1");
+
+  config.setString("AML-PROGRAM-P2", "command", "/bin/true");
+  config.setString("AML-PROGRAM-P2", "enabled", "true");
+  config.setString("AML-PROGRAM-P2", "description", "does nothing");
+  config.setString("AML-PROGRAM-P2", "description_i18n", "{}");
+  config.setString("AML-PROGRAM-P2", "fallback", "M1");
+
+  config.setString("AML-PROGRAM-NOP", "command", "/bin/true");
+  config.setString("AML-PROGRAM-NOP", "enabled", "true");
+  config.setString(
+    "AML-PROGRAM-NOP",
+    "description",
+    "does nothing (never used)",
+  );
+  config.setString("AML-PROGRAM-NOP", "description_i18n", "{}");
+  config.setString("AML-PROGRAM-NOP", "fallback", "MF");
+
+  config.setString("KYC-CHECK-C1", "type", "FORM");
+  config.setString("KYC-CHECK-C1", "form_name", "firstForm");
+  config.setString("KYC-CHECK-C1", "description", "starting check!");
+  config.setString("KYC-CHECK-C1", "description_i18n", "{}");
+  config.setString("KYC-CHECK-C1", "outputs", "NAME");
+  config.setString("KYC-CHECK-C1", "fallback", "MF");
+
+  config.setString("KYC-CHECK-C2", "type", "FORM");
+  config.setString("KYC-CHECK-C2", "form_name", "secondForm");
+  config.setString("KYC-CHECK-C2", "description", "final check!");
+  config.setString("KYC-CHECK-C2", "description_i18n", "{}");
+  config.setString("KYC-CHECK-C2", "outputs", "FINAL");
+  config.setString("KYC-CHECK-C2", "fallback", "MF");
+
+  config.setString("KYC-CHECK-C3", "type", "FORM");
+  config.setString("KYC-CHECK-C3", "form_name", "thirdForm");
+  config.setString(
+    "KYC-CHECK-C3",
+    "description",
+    "this is check c3 (never used)",
+  );
+  config.setString("KYC-CHECK-C3", "description_i18n", "{}");
+  config.setString("KYC-CHECK-C3", "fallback", "MF");
+
+  config.setString("KYC-CHECK-C4", "type", "FORM");
+  config.setString("KYC-CHECK-C4", "form_name", "fourthForm");
+  config.setString(
+    "KYC-CHECK-C4",
+    "description",
+    "this is check c4 (never used)",
+  );
+  config.setString("KYC-CHECK-C4", "description_i18n", "{}");
+  config.setString("KYC-CHECK-C4", "fallback", "MF");
+}
+
+/**
+ * Test setting a `new_measure` as the AML officer.
+ */
+export async function runKycTwoFormsTest(t: GlobalTestState) {
+  // Set up test environment
+
+  const { exchange, amlKeypair } = await createKycTestkudosEnvironment(t, {
+    adjustExchangeConfig,
+    onWalletNotification: () => {},
+  });
+
+  // Withdraw digital cash into the wallet.
+  let kycPaytoHash: string;
+  let accessToken: string;
+  let latestFormId: string;
+
+  // {
+  //   logger.info("step 1) Withdraw to trigger AML and 2) get access token")
+  //   const wres = await withdrawViaBankV3(t, {
+  //     amount: "TESTKUDOS:20",
+  //     bankClient,
+  //     exchange,
+  //     walletClient,
+  //   });
+
+  //   await walletClient.call(WalletApiOperation.TestingWaitTransactionState, 
{
+  //     transactionId: wres.transactionId as TransactionIdStr,
+  //     txState: {
+  //       major: TransactionMajorState.Pending,
+  //       minor: TransactionMinorState.KycRequired,
+  //     },
+  //   });
+
+  //   const txDetails = await walletClient.call(
+  //     WalletApiOperation.GetTransactionById,
+  //     {
+  //       transactionId: wres.transactionId,
+  //     },
+  //   );
+
+  //   accessToken = txDetails.kycAccessToken;
+  //   kycPaytoHash = txDetails.kycPaytoHash;
+  //   firstTransaction = wres.transactionId;
+  // }
+  const account = await createNewWalletKycAccount(new Uint8Array());
+  {
+    logger.info("step 1) Check balance to trigger AML");
+
+    const balance: AmountString = "TESTKUDOS:20";
+    const sigBlob = buildSigPS(TalerSignaturePurpose.WALLET_ACCOUNT_SETUP)
+      .put(amountToBuffer(balance))
+      .build();
+    const body: WalletKycRequest = {
+      balance,
+      reserve_pub: account.id,
+      reserve_sig: encodeCrock(eddsaSign(sigBlob, account.signingKey)),
+    };
+    const infoResp = await harnessHttpLib.fetch(
+      new URL(`kyc-wallet`, exchange.baseUrl).href,
+      {
+        method: "POST",
+        body,
+      },
+    );
+
+    t.assertDeepEqual(infoResp.status, 451);
+    const clientInfo = await readResponseJsonOrThrow(
+      infoResp,
+      codecOptional(codecForLegitimizationNeededResponse()),
+    );
+
+    t.assertTrue(clientInfo?.h_payto !== undefined);
+    kycPaytoHash = clientInfo?.h_payto;
+  }
+
+  {
+    logger.info("step 2) Get account access token");
+    const sigBlob = buildSigPS(TalerSignaturePurpose.KYC_AUTH).build();
+
+    const infoResp = await harnessHttpLib.fetch(
+      new URL(`kyc-check/${kycPaytoHash}`, exchange.baseUrl).href,
+      {
+        headers: {
+          "Account-Owner-Signature": encodeCrock(
+            eddsaSign(sigBlob, account.signingKey),
+          ),
+        },
+      },
+    );
+
+    t.assertDeepEqual(infoResp.status, 202);
+    const clientInfo = await readResponseJsonOrThrow(
+      infoResp,
+      codecOptional(codecForAccountKycStatus()),
+    );
+    t.assertTrue(clientInfo?.access_token !== undefined);
+    accessToken = clientInfo?.access_token;
+  }
+
+  // {
+  //   // step 2) Check KYC info
+  //   const infoResp = await harnessHttpLib.fetch(
+  //     new URL(`kyc-info/${accessToken}`, exchange.baseUrl).href,
+  //   );
+
+  //   const clientInfo = await readResponseJsonOrThrow(
+  //     infoResp,
+  //     codecOptional(codecForKycProcessClientInformation()),
+  //   );
+
+  //   console.log(j2s(clientInfo));
+  //   t.assertDeepEqual(infoResp.status, 200);
+  //   t.assertDeepEqual(clientInfo?.requirements.length, 1);
+  //   t.assertDeepEqual(clientInfo?.requirements[0].form, "firstForm");
+  // }
+
+  {
+    logger.info("step 3) Check KYC info, should be waiting for the first 
form");
+    const infoResp = await harnessHttpLib.fetch(
+      new URL(`kyc-info/${accessToken}?timeout_ms=1000`, 
exchange.baseUrl).href,
+    );
+    const clientInfo = await readResponseJsonOrThrow(
+      infoResp,
+      codecOptional(codecForKycProcessClientInformation()),
+    );
+
+    console.log(j2s(clientInfo));
+    t.assertDeepEqual(infoResp.status, 200);
+    t.assertDeepEqual(clientInfo?.requirements.length, 1);
+    t.assertDeepEqual(clientInfo?.requirements[0].form, "firstForm");
+    t.assertTrue(!!clientInfo?.requirements[0].id);
+    latestFormId = clientInfo?.requirements[0].id;
+  }
+
+  {
+    logger.info("step 4) Complete form");
+    const infoResp = await harnessHttpLib.fetch(
+      new URL(`kyc-upload/${latestFormId}`, exchange.baseUrl).href,
+      {
+        method: "POST",
+        headers: {
+          "Content-Type": "application/x-www-form-urlencoded",
+        },
+        body: "NAME=who",
+      },
+    );
+
+    t.assertDeepEqual(infoResp.status, 204);
+  }
+
+  {
+    logger.info(
+      "step 5) Check KYC info again, should see the second form but this time 
is too fast",
+    );
+
+    ///////////////////////////////////////////
+    // if the request is too early id result in garbage
+    // can't be ignored because browser see this
+    ///////////////////////////////////////////
+    {
+      const infoResp = await harnessHttpLib.fetch(
+        new URL(`kyc-info/${accessToken}?timeout_ms=1000`, exchange.baseUrl)
+          .href,
+      );
+      {
+        const clientInfo = await readResponseJsonOrThrow(
+          infoResp,
+          codecOptional(codecForKycProcessClientInformation()),
+        );
+
+        console.log(j2s(clientInfo));
+        // t.assertDeepEqual(infoResp.status, 200);
+        // t.assertDeepEqual(clientInfo?.requirements.length, 1);
+        // t.assertDeepEqual(clientInfo?.requirements[0].form, "secondForm");
+  
+      }
+    }
+  }
+
+  await waitMs(2000);
+  {
+    logger.info("step 6) Check KYC info again after some time, should see the 
second form");
+      //doing a second request shouldnt fail
+      const infoResp = await harnessHttpLib.fetch(
+        new URL(`kyc-info/${accessToken}?timeout_ms=1000`, exchange.baseUrl)
+          .href,
+      );
+
+      const clientInfo = await readResponseJsonOrThrow(
+        infoResp,
+        codecOptional(codecForKycProcessClientInformation()),
+      );
+
+      console.log(j2s(clientInfo));
+      t.assertDeepEqual(infoResp.status, 200);
+      t.assertDeepEqual(clientInfo?.requirements.length, 1);
+      t.assertDeepEqual(clientInfo?.requirements[0].form, "secondForm");
+  }
+
+  await waitMs(2000);
+
+  {
+    logger.info("step 6) Check KYC info again after some time, here the 
exchange fails");
+    const infoResp = await harnessHttpLib.fetch(
+      new URL(`kyc-info/${accessToken}?timeout_ms=1000`, 
exchange.baseUrl).href,
+    );
+
+    const clientInfo = await readResponseJsonOrThrow(
+      infoResp,
+      codecOptional(codecForKycProcessClientInformation()),
+    );
+
+    console.log(j2s(clientInfo));
+    t.assertDeepEqual(infoResp.status, 200);
+    t.assertDeepEqual(clientInfo?.requirements.length, 1);
+    t.assertDeepEqual(clientInfo?.requirements[0].form, "secondForm");
+  }
+}
+
+runKycTwoFormsTest.suites = ["wallet"];
diff --git a/packages/taler-harness/src/integrationtests/testrunner.ts 
b/packages/taler-harness/src/integrationtests/testrunner.ts
index 0816d2584..fefb35393 100644
--- a/packages/taler-harness/src/integrationtests/testrunner.ts
+++ b/packages/taler-harness/src/integrationtests/testrunner.ts
@@ -148,6 +148,7 @@ import { runWithdrawalHugeTest } from 
"./test-withdrawal-huge.js";
 import { runWithdrawalIdempotentTest } from "./test-withdrawal-idempotent.js";
 import { runWithdrawalManualTest } from "./test-withdrawal-manual.js";
 import { runWithdrawalPrepareTest } from "./test-withdrawal-prepare.js";
+import { runKycTwoFormsTest } from "./test-kyc-two-forms.js";
 
 /**
  * Test runner.
@@ -274,6 +275,7 @@ const allTests: TestMainFunction[] = [
   runKycBalanceWithdrawalTest,
   runKycNewMeasureTest,
   runKycSkipExpirationTest,
+  runKycTwoFormsTest,
   runKycDepositDepositTest,
   runKycMerchantDepositTest,
   runKycMerchantAggregateTest,

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]