exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

taler-exchange-helper-measure-tops-3rdparty-check (5951B)


      1 #!/bin/bash
      2 #
      3 #  This file is part of TALER
      4 #  Copyright (C) 2025 Taler Systems SA
      5 #
      6 #  TALER is free software; you can redistribute it and/or modify it under the
      7 #  terms of the GNU General Public License as published by the Free Software
      8 #  Foundation; either version 3, or (at your option) any later version.
      9 #
     10 #  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     11 #  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     12 #  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     13 #
     14 #  You should have received a copy of the GNU General Public License along with
     15 #  TALER; see the file COPYING.  If not, If not, see <http://www.gnu.org/license>
     16 #
     17 
     18 # Hard error reporting on.
     19 set -eu
     20 
     21 
     22 # Exit, with error message (hard failure)
     23 function exit_fail() {
     24     echo " FAIL: " "$@" >&2
     25     EXIT_STATUS=1
     26     exit "$EXIT_STATUS"
     27 }
     28 
     29 CONF="$HOME/.config/taler-exchange.conf"
     30 VERBOSE=0
     31 
     32 while getopts 'ac:hirvV' OPTION;
     33 do
     34     case "$OPTION" in
     35         a)
     36             # Controlling entity 3rd person field is required.
     37             echo "THIRD_PARTY_OWNERSHIP"
     38             exit 0
     39             ;;
     40         c)
     41             # shellcheck disable=SC2034
     42             CONF="$OPTARG"
     43             ;;
     44         h)
     45             echo "This is a KYC measure program that determines the next VQF form to ask for (if any) based on the type of legal entity the customer claimed to be on the primary form."
     46             echo 'Supported options:'
     47             echo '  -a           -- show required attributes'
     48             # shellcheck disable=SC2016
     49             echo '  -c $CONF     -- set configuration'
     50             echo '  -h           -- print this help'
     51             echo '  -i           -- show required inputs'
     52             echo '  -r           -- show required context'
     53             echo '  -v           -- show version'
     54             echo '  -V           -- be verbose'
     55             exit 0
     56             ;;
     57         i)
     58             # Need context and current_rules.
     59             echo "attributes"
     60             echo "current_rules"
     61             echo "default_rules"
     62             exit 0
     63             ;;
     64         r)
     65             # Nothing needed from context
     66             exit 0
     67             ;;
     68         v)
     69             echo "$0 v0.0.4"
     70             exit 0
     71             ;;
     72         V)
     73             VERBOSE=1
     74             ;;
     75         ?)
     76         exit_fail "Unrecognized command line option"
     77         ;;
     78     esac
     79 done
     80 
     81 if [ 1 = "$VERBOSE" ]
     82 then
     83     echo "Running $0" 1>&2
     84 fi
     85 
     86 # See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlProgramInput
     87 # for the full JSON with possible inputs.
     88 
     89 # First, extract inputs we need
     90 INPUTS=$(jq '{"current_rules":(.current_rules // .default_rules // error("neither current_rules nor default_rules provided")),"attributes":.attributes}')
     91 
     92 # Check form ID, must be 'vqf-902.11'
     93 FORM_ID=$(echo "$INPUTS" | jq -r '.attributes.FORM_ID')
     94 
     95 # The 'form' here should be the VQF 902.11 customer form
     96 if [ "$FORM_ID" != "vqf_902_11_customer" ]
     97 then
     98     echo "Unexpected form ID $FORM_ID" 1>&2
     99     exec taler-exchange-helper-measure-freeze
    100 fi
    101 
    102 # Check all mandatory attributes are present.
    103 echo "$INPUTS" \
    104     | jq '.attributes' \
    105     | jq -r 'def get($k):
    106              if has($k)
    107                then .[$k]
    108                else error("attribute \($k) missing")
    109            end;
    110            {"THIRD_PARTY_OWNERSHIP":get("THIRD_PARTY_OWNERSHIP"),
    111             "CONTROL_REASON":get("CONTROL_REASON"),
    112             "SIGN_DATE":get("SIGN_DATE"),
    113             "SIGNATURE":get("SIGNATURE")}' \
    114                 > /dev/null \
    115                 || exec taler-exchange-helper-measure-freeze
    116 
    117 
    118 # Get entity type
    119 CONTROL3P=$(echo "$INPUTS" | jq -r '.attributes.THIRD_PARTY_OWNERSHIP')
    120 # Get current rules.
    121 CURRENT_RULES=$(echo "$INPUTS" | jq '.current_rules // null')
    122 # Get context values.
    123 EXPIRATION_TIME=$(echo "$INPUTS" | jq '.context.expiration_time // .current_rules.expiration_time // null')
    124 
    125 FORM="error"
    126 
    127 INVESTIGATE="false"
    128 case "$CONTROL3P"
    129 in
    130     "false")
    131         FORM="none"
    132     ;;
    133     "true")
    134         FORM="vqf-902.9"
    135     ;;
    136 esac
    137 
    138 NEW_MEASURES="null"
    139 # Check high-level case
    140 case "$FORM"
    141 in
    142     "error")
    143         # This should not happen, immediately trigger investigation and show error to the user.
    144         echo "ERROR: Unexpected value for controlling entity is 3rd person '${CONTROL3P}'" 1>&2
    145         NEW_RULES=$(echo "$CURRENT_RULES" | jq '(.rules[] |= if (.rule_name=="deposit-limit-zero" or .measures[0] == "form-vqf-902.11") then .measures=["inform-internal-error"] else . end)')
    146         INVESTIGATE="true"
    147         ;;
    148     "none")
    149         # Move into investigation mode.
    150         echo "INFO: Passing data to taler-exchange-helper-measure-inform-investigate" 1>&2
    151         NEW_RULES=$(echo "$CURRENT_RULES" | jq '(.rules[] |= if (.rule_name=="deposit-limit-zero" or .measures[0] == "form-vqf-902.11") then .measures=["form-'${FORM}'"] else . end)')
    152         echo "$INPUTS" | taler-exchange-helper-measure-inform-investigate
    153         exit $?
    154         ;;
    155     *)
    156         # Proceed to FORM.
    157         echo "Selected VQF form ${FORM}." 1>&2
    158         # Force user to fill in $FORM
    159         NEW_RULES=$(echo "$CURRENT_RULES" | jq '(.rules[] |= if (.rule_name=="deposit-limit-zero" or .measures[0] == "form-vqf-902.11") then .measures=["form-'${FORM}'"] else . end)')
    160         NEW_MEASURES='"form-'${FORM}'"'
    161         ;;
    162 esac
    163 
    164 # When the information expires, we start the full KYX process
    165 # again.
    166 SUCCESSOR_MEASURE='"kyx"'
    167 
    168 # Finally, output the new rules.
    169 # See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome
    170 # for the required output format.
    171 jq -n \
    172     --argjson inv "$INVESTIGATE" \
    173     --argjson et "$EXPIRATION_TIME" \
    174     --argjson sm "$SUCCESSOR_MEASURE" \
    175     --argjson nm "$NEW_MEASURES" \
    176     --argjson nr "$NEW_RULES" \
    177     '{"to_investigate":$inv,"new_measures":$nm,"new_rules":($nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":({}+$nr.custom_measures)})}|del(..|nulls)'
    178 
    179 exit 0