commit dd7148285da1f6a9efe1ee55307acf1a02007ba9
parent 53d3b742e90dbd275b2d08e96613d12ac4280b77
Author: Christian Grothoff <christian@grothoff.org>
Date: Sun, 22 Dec 2024 16:00:55 +0100
work on AML programs
Diffstat:
9 files changed, 288 insertions(+), 27 deletions(-)
diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am
@@ -19,9 +19,11 @@ bin_SCRIPTS = \
taler-exchange-helper-measure-defaults-but-investigate \
taler-exchange-helper-measure-enable-deposits \
taler-exchange-helper-measure-freeze \
+ taler-exchange-helper-measure-inform-investigate \
taler-exchange-helper-measure-none \
taler-exchange-helper-measure-preserve-but-investigate \
taler-exchange-helper-measure-preserve-set-expiration \
+ taler-exchange-helper-measure-tops-address-check \
taler-exchange-helper-measure-tops-kyx-check \
taler-exchange-helper-measure-tops-postal-check \
taler-exchange-helper-measure-tops-sms-check \
diff --git a/src/kyclogic/taler-exchange-helper-measure-enable-deposits b/src/kyclogic/taler-exchange-helper-measure-enable-deposits
@@ -120,10 +120,10 @@ fi
# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome
# for the required output format.
jq \
- --jsonarg et "$EXPIRATION_TIME" \
- --jsonarg sm "$SUCCESSOR_MEASURE" \
- --jsonarg cm "$CUSTOM_MEASURES" \
- --jsonarg nr "$NEW_RULES" \
+ --argjson et "$EXPIRATION_TIME" \
+ --argjson sm "$SUCCESSOR_MEASURE" \
+ --argjson cm "$CUSTOM_MEASURES" \
+ --argjson nr "$NEW_RULES" \
'{"new_rules":$nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":($nr.custom_measures+$cm)}}|del(..|nulls)'
exit 0
diff --git a/src/kyclogic/taler-exchange-helper-measure-inform-investigate b/src/kyclogic/taler-exchange-helper-measure-inform-investigate
@@ -0,0 +1,100 @@
+#!/bin/bash
+#
+# This file is part of TALER
+# Copyright (C) 2024 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, If not, see <http://www.gnu.org/license>
+#
+
+# Hard error reporting on.
+set -eu
+
+
+
+# Exit, with error message (hard failure)
+function exit_fail() {
+ echo " FAIL: " "$@" >&2
+ EXIT_STATUS=1
+ exit "$EXIT_STATUS"
+}
+
+CONF="$HOME/.config/taler-exchange.conf"
+VERBOSE=0
+
+while getopts 'ac:hirvV' OPTION;
+do
+ case "$OPTION" in
+ a)
+ # No attributes are required.
+ exit 0
+ ;;
+ c)
+ # shellcheck disable=SC2034
+ CONF="$OPTARG"
+ ;;
+ h)
+ echo "This is a KYC measure program that flags and account for manual investigation and informs the user about it."
+ echo 'Supported options:'
+ echo ' -a -- show required attributes'
+ # shellcheck disable=SC2016
+ echo ' -c $CONF -- set configuration'
+ echo ' -h -- print this help'
+ echo ' -i -- show required inputs'
+ echo ' -r -- show required context'
+ echo ' -v -- show version'
+ echo ' -V -- be verbose'
+ exit 0
+ ;;
+ i)
+ # Need current rules.
+ echo "current_rules"
+ exit 0
+ ;;
+ r)
+ # No context is required.
+ exit 0
+ ;;
+ v)
+ echo "$0 v0.0.0"
+ exit 0
+ ;;
+ V)
+ VERBOSE=1
+ ;;
+ ?)
+ exit_fail "Unrecognized command line option"
+ ;;
+ esac
+done
+
+if [ 1 = "$VERBOSE" ]
+then
+ echo "Running $0" 1>&2
+fi
+
+# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlProgramInput
+# for the full JSON with possible inputs.
+
+# First, extract inputs we need
+CURRENT_RULES=$(jq '.current_rules')
+
+# FIXME: not generic, figure out how to do this nicely regardless of
+# what rule we are at.
+NEW_RULES=$(echo "$CURRENT_RULES" | jq '(.rules[] | select (.rule_name==\"kyc-rule-deposit-limit-zero\").measures=["form-info-investigation"])')
+
+
+# Finally, output the new rules.
+# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome
+# for the required output format.
+
+echo "$NEW_RULES" \
+ | jq '.+{"to_investigate": true}'
diff --git a/src/kyclogic/taler-exchange-helper-measure-preserve-set-expiration b/src/kyclogic/taler-exchange-helper-measure-preserve-set-expiration
@@ -100,8 +100,8 @@ SUCCESSOR_MEASURE=$(echo "$INPUTS" | jq '.context.successor_measure // null')
echo "$INPUTS" \
| jq \
- --jsonarg et "$EXPIRATION_TIME" \
- --jsonarg sm "$SUCCESSOR_MEASURE" \
+ --argjson et "$EXPIRATION_TIME" \
+ --argjson sm "$SUCCESSOR_MEASURE" \
'.current_rules+{"new_rules":(.new_rules+{"expiration_time":$et,"successor_measure":$sm})}|del(..|nulls)'
exit 0
diff --git a/src/kyclogic/taler-exchange-helper-measure-tops-address-check b/src/kyclogic/taler-exchange-helper-measure-tops-address-check
@@ -0,0 +1,160 @@
+#!/bin/bash
+#
+# This file is part of TALER
+# Copyright (C) 2024 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, If not, see <http://www.gnu.org/license>
+#
+
+# Hard error reporting on.
+set -eu
+
+
+# Exit, with error message (hard failure)
+function exit_fail() {
+ echo " FAIL: " "$@" >&2
+ EXIT_STATUS=1
+ exit "$EXIT_STATUS"
+}
+
+CONF="$HOME/.config/taler-exchange.conf"
+VERBOSE=0
+
+while getopts 'ac:hirvV' OPTION;
+do
+ case "$OPTION" in
+ a)
+ # Address data is required.
+ echo "ADDRESS_STREET_NAME"
+ echo "ADDRESS_ZIPCODE"
+ echo "ADDRESS_COUNTRY_CC"
+ exit 0
+ ;;
+ c)
+ # shellcheck disable=SC2034
+ CONF="$OPTARG"
+ ;;
+ h)
+ echo "This is a KYC measure program that sets up a measure to validate the address of the customer via Challenger."
+ echo 'Supported options:'
+ echo ' -a -- show required attributes'
+ # shellcheck disable=SC2016
+ echo ' -c $CONF -- set configuration'
+ echo ' -h -- print this help'
+ echo ' -i -- show required inputs'
+ echo ' -r -- show required context'
+ echo ' -v -- show version'
+ echo ' -V -- be verbose'
+ exit 0
+ ;;
+ i)
+ # Need context and current_rules.
+ echo "attributes"
+ echo "current_rules"
+ exit 0
+ ;;
+ r)
+ # Nothing needed from context
+ exit 0
+ ;;
+ v)
+ echo "$0 v0.0.0"
+ exit 0
+ ;;
+ V)
+ VERBOSE=1
+ ;;
+ ?)
+ exit_fail "Unrecognized command line option"
+ ;;
+ esac
+done
+
+if [ 1 = "$VERBOSE" ]
+then
+ echo "Running $0" 1>&2
+fi
+
+# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlProgramInput
+# for the full JSON with possible inputs.
+
+# First, extract inputs we need
+INPUTS=$(jq '{"current_rules":.current_rules,"attributes":.attributes}')
+
+# Get address data
+ADDRESS_NAME=$(echo "$INPUTS" | jq '.attributes.PERSON_FULL_NAME // .attributes.BUSINESS_DISPLAY_NAME // null')
+# FIXME:
+# Set 'name' to either of the two above, whichever one is non-null!
+
+ADDRESS_STREET_NAME=$(echo "$INPUTS" | jq '.attributes.ADDRESS_STREET_NAME // .attributes.ADDRESS_BUILDING_NAME // null')
+ADDRESS_STREET_NUMBER=$(echo "$INPUTS" | jq '.attributes.ADDRESS_STREET_NUMBER // .attributes.ADDRESS_BUILDING_NUMBER // null')
+ADDRESS_LINES=$(echo "$INPUTS" | jq '.attributes.ADDRESS_LINES // null')
+ADDRESS_ZIPCODE=$(echo "$INPUTS" | jq '.attributes.ADDRESS_ZIPCODE // null')
+ADDRESS_TOWN=$(echo "$INPUTS" | jq '.attributes.ADDRESS_TOWN_DISTRICT // .attributes.ADDRESS_TOWN_LOCATION // null')
+ADDRESS_COUNTRY_SUBDIVISION=$(echo "$INPUTS" | jq '.attributes.ADDRESS_COUNTRY_SUBDIVISION // null')
+ADDRESS_COUNTRY_CC=$(echo "$INPUTS" | jq '.attributes.ADDRESS_COUNTRY_CC // null')
+
+case "$ADDRESS_COUNTRY_CC"
+in
+ ch)
+ COUNTRY="Switzerland"
+ ;;
+ de)
+ COUNTRY="Germany"
+ ;;
+ fr)
+ COUNTRY="France"
+ ;;
+ it)
+ COUNTRY="Italy"
+ ;;
+ *)
+ echo "ERROR: Country code '${ADDDRESS_COUNTRY_CC}' not recognized" 1>&2
+ COUNTRY="${ADDRESS_COUNTRY_CC}"
+ ;;
+esac
+
+# Convert address data to Challenger format as best we can.
+ADDRESS=$(jq \
+ --argjson full_name "$ADDRESS_NAME $ADDRESS_LINES" \
+ --argjson street "$ADDRESS_STREET_NAME $ADDRESS_STREET_NUMBER" \
+ --argjson city "$ADDRESS_TOWN" \
+ --argjson postcode "$ADDRESS_ZIPCODE" \
+ --argjson country "$COUNTRY" \
+ '{"full_name":$full_name,"street":$street,"city":$city,"postcode":$postcode,"country":$country}')
+
+# Get current rules.
+CURRENT_RULES=$(echo "$INPUTS" | jq '.current_rules // null')
+# Get context values.
+EXPIRATION_TIME=$(echo "$INPUTS" | jq '.context.expiration_time // .current_rules.expiration_time // null')
+# Preserve successor measure.
+SUCCESSOR_MEASURE=$(echo "$INPUTS" | jq '.current_rules.successor_measure // null')
+
+# Define custom measure for address validation
+CUSTOM_MEASURES=$(jq \
+ --argjson address "$ADDRESS" \
+ '{"custom-address-investigation":{"context":{"initial_address":$address},"check_name":"postal-registration","prog_name":"inform-investigate","operation_type":"DEPOSIT"}}')
+
+# Then trigger Challenger address check via oauth2, kyc-check-postal-registration
+NEW_RULES=$(echo "$CURRENT_RULES" | jq '(.rules[] | select (.rule_name=="kyc-rule-deposit-limit-zero").measures=["custom-address-investigation"])' | jq --argjson cm "$CUSTOM_MEASURES" '.custom_measures=$cm')
+
+# Finally, output the new rules.
+# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome
+# for the required output format.
+jq \
+ --argjson et "$EXPIRATION_TIME" \
+ --argjson sm "$SUCCESSOR_MEASURE" \
+ --argjson cm "$CUSTOM_MEASURES" \
+ --argjson nr "$NEW_RULES" \
+ '{"new_rules":$nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":($nr.custom_measures+$cm)}}|del(..|nulls)'
+
+exit 0
diff --git a/src/kyclogic/taler-exchange-helper-measure-tops-kyx-check b/src/kyclogic/taler-exchange-helper-measure-tops-kyx-check
@@ -129,10 +129,9 @@ in
INVESTIGATE="true"
;;
"none")
- # Immediately trigger investigation.
- # FIXME: or rather: address validation!
- NEW_RULES=$(echo "$CURRENT_RULES" | jq '(.rules[] | select (.rule_name==\"kyc-rule-deposit-limit-zero\").measures=["form-info-investigation"])')
- INVESTIGATE="true"
+ # Immediately trigger address validation.
+ echo "$INPUTS" | taler-exchange-helper-measure-tops-address-check
+ exit $?
;;
*)
# Proceed to FORM.
@@ -148,11 +147,11 @@ esac
# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome
# for the required output format.
jq \
- --jsonarg inv "$INVESTIGATE" \
- --jsonarg et "$EXPIRATION_TIME" \
- --jsonarg sm "$SUCCESSOR_MEASURE" \
- --jsonarg cm "$CUSTOM_MEASURES" \
- --jsonarg nr "$NEW_RULES" \
+ --argjson inv "$INVESTIGATE" \
+ --argjson et "$EXPIRATION_TIME" \
+ --argjson sm "$SUCCESSOR_MEASURE" \
+ --argjson cm "$CUSTOM_MEASURES" \
+ --argjson nr "$NEW_RULES" \
'{"to_investigate":$inv,"new_rules":$nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":($nr.custom_measures+$cm)}}|del(..|nulls)'
exit 0
diff --git a/src/kyclogic/taler-exchange-helper-measure-tops-postal-check b/src/kyclogic/taler-exchange-helper-measure-tops-postal-check
@@ -124,10 +124,10 @@ fi
# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome
# for the required output format.
jq \
- --jsonarg et "$EXPIRATION_TIME" \
- --jsonarg sm "$SUCCESSOR_MEASURE" \
- --jsonarg cm "$CUSTOM_MEASURES" \
- --jsonarg nr "$NEW_RULES" \
+ --argjson et "$EXPIRATION_TIME" \
+ --argjson sm "$SUCCESSOR_MEASURE" \
+ --argjson cm "$CUSTOM_MEASURES" \
+ --argjson nr "$NEW_RULES" \
'{"new_rules":$nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":($nr.custom_measures+$cm)}}|del(..|nulls)'
exit 0
diff --git a/src/kyclogic/taler-exchange-helper-measure-tops-sms-check b/src/kyclogic/taler-exchange-helper-measure-tops-sms-check
@@ -121,10 +121,10 @@ fi
# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome
# for the required output format.
jq \
- --jsonarg et "$EXPIRATION_TIME" \
- --jsonarg sm "$SUCCESSOR_MEASURE" \
- --jsonarg cm "$CUSTOM_MEASURES" \
- --jsonarg nr "$NEW_RULES" \
+ --argjson et "$EXPIRATION_TIME" \
+ --argjson sm "$SUCCESSOR_MEASURE" \
+ --argjson cm "$CUSTOM_MEASURES" \
+ --argjson nr "$NEW_RULES" \
'{"new_rules":$nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":($nr.custom_measures+$cm)}}|del(..|nulls)'
exit 0
diff --git a/src/kyclogic/taler-exchange-helper-measure-update-from-context b/src/kyclogic/taler-exchange-helper-measure-update-from-context
@@ -104,10 +104,10 @@ NEW_RULES=$(echo "$INPUTS" | jq '.context.new_rules // null')
echo "$INPUTS" \
| jq \
- --jsonarg et "$EXPIRATION_TIME" \
- --jsonarg sm "$SUCCESSOR_MEASURE" \
- --jsonarg cm "$CUSTOM_MEASURES" \
- --jsonarg nr "$NEW_RULES" \
+ --argjson et "$EXPIRATION_TIME" \
+ --argjson sm "$SUCCESSOR_MEASURE" \
+ --argjson cm "$CUSTOM_MEASURES" \
+ --argjson nr "$NEW_RULES" \
'.current_rules+{"new_rules":(.current_rules.new_rules+{"expiration_time":$et,"successor_measure":$sm,"rules":(.current_rules.new_rules.rules+$nr),"custom_measures":(.current_rules.custom_measures+$cm)})}|del(..|nulls)'
exit 0