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-address-check (5947B)


      1 #!/bin/bash
      2 #
      3 #  This file is part of TALER
      4 #  Copyright (C) 2024, 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 # Exit, with error message (hard failure)
     22 function exit_fail() {
     23     echo " FAIL: " "$@" >&2
     24     EXIT_STATUS=1
     25     exit "$EXIT_STATUS"
     26 }
     27 
     28 CONF="$HOME/.config/taler-exchange.conf"
     29 VERBOSE=0
     30 
     31 while getopts 'ac:hirvV' OPTION;
     32 do
     33     case "$OPTION" in
     34         a)
     35             # Address data is required.
     36             echo "ADDRESS_LINES"
     37             echo "ADDRESS_COUNTRY"
     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 sets up a measure to validate the address of the customer via Challenger."
     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.2"
     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 # Get address data
     93 CUSTOMER_TYPE=$(echo "$INPUTS" | jq -r '.attributes.CUSTOMER_TYPE // null')
     94 case "$CUSTOMER_TYPE"
     95 in
     96     "NATURAL_PERSON")
     97         CONTACT_NAME=$(echo "$INPUTS" | jq -r '.attributes.FULL_NAME')
     98         ;;
     99     "LEGAL_ENTITY")
    100         BUSINESS_NAME=$(echo "$INPUTS" | jq -r '.attributes.COMPANY_NAME')
    101         CONTACT_PERSON=$(echo "$INPUTS" | jq -r '.attributes.CONTACT_PERSON_NAME // null')
    102         if [ "null" != "$CONTACT_PERSON" ]
    103         then
    104             CONTACT_NAME=$(echo -en "${BUSINESS_NAME}\nAttn. ${CONTACT_PERSON}")
    105         else
    106             CONTACT_NAME="$BUSINESS_NAME"
    107         fi
    108         ;;
    109     *)
    110         # Strange, we don't know. Let's try everything...
    111         CONTACT_NAME=$(echo "$INPUTS" | jq -r '.attributes.CONTACT_NAME // .attributes.FULL_NAME // .attributes.COMPANY_NAME')
    112         ;;
    113 esac
    114 
    115 ADDRESS_LINES=$(echo "$INPUTS" | jq '.attributes.DOMICILE_ADDRESS')
    116 # We ONLY allow Swiss addresses
    117 ADDRESS_COUNTRY='"CH"'
    118 
    119 # Convert address data to Challenger format as best we can.
    120 ADDRESS=$(jq -n \
    121     --argjson contact_name \""$CONTACT_NAME"\" \
    122     --argjson address_lines "$ADDRESS_LINES" \
    123     --argjson address_country "$ADDRESS_COUNTRY" \
    124     '{"CONTACT_NAME":$contact_name,"ADDRESS_LINES":$address_lines,"ADDRESS_COUNTRY":$address_country,"read_only":true}')
    125 
    126 # Get current rules.
    127 CURRENT_RULES=$(echo "$INPUTS" | jq '.current_rules // null')
    128 # Get context values.
    129 EXPIRATION_TIME=$(echo "$INPUTS" | jq '.context.expiration_time // .current_rules.expiration_time // null')
    130 # Preserve successor measure.
    131 SUCCESSOR_MEASURE=$(echo "$INPUTS" | jq '.current_rules.successor_measure // null')
    132 CUSTOM_MEASURES=$(echo "$INPUTS" | jq '.context.custom_measures // null')
    133 
    134 # Define custom measure for address validation
    135 CUSTOM_AMEASURES=$(jq -n \
    136     --argjson address "$ADDRESS" \
    137     '{"custom-address-investigation":{"context":{"initial_address":$address},"check_name":"postal-registration","prog_name":"inform-investigate","operation_type":"DEPOSIT"}}')
    138 
    139 # Then trigger Challenger address check via oauth2, kyc-check-postal-registration
    140 NEW_RULES=$(echo "$CURRENT_RULES" | jq --argjson cm "$CUSTOM_MEASURES" '(.rules[] |= if (.measures[0]=="kyx" or .rule_name=="deposit-limit-zero" or .rule_name=="p2p-domestic-identification-requirement") then .measures=["custom-address-investigation"] else . end) | .custom_measures=$cm')
    141 
    142 # Replace all existing 'postal-registration' measures with 'custom-address-investigation'
    143 NEW_RULES=$(echo "$NEW_RULES" | jq --argjson cm "$CUSTOM_MEASURES" '(.rules[].measures[] |= if (. =="postal-registration") then "custom-address-investigation" else . end) | .custom_measures=$cm')
    144 
    145 # Finally, output the new rules.
    146 # See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome
    147 # for the required output format.
    148 
    149 jq -n \
    150     --argjson et "$EXPIRATION_TIME" \
    151     --argjson sm "$SUCCESSOR_MEASURE" \
    152     --argjson nm '"custom-address-investigation"' \
    153     --argjson cm "$CUSTOM_MEASURES" \
    154     --argjson cma "$CUSTOM_AMEASURES" \
    155     --argjson nr "$NEW_RULES" \
    156     '{"new_measures":$nm,"new_rules":($nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":({}+$nr.custom_measures+$cm+$cma)})}|del(..|nulls)'
    157 
    158 exit 0