taler-exchange-helper-measure-tops-kyx-check (8975B)
1 #!/bin/bash 2 # 3 # This file is part of TALER 4 # Copyright (C) 2024 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 # Legal entity type is required. 37 echo "CUSTOMER_TYPE" 38 echo "CUSTOMER_TYPE_VQF" 39 exit 0 40 ;; 41 c) 42 # shellcheck disable=SC2034 43 CONF="$OPTARG" 44 ;; 45 h) 46 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." 47 echo 'Supported options:' 48 echo ' -a -- show required attributes' 49 # shellcheck disable=SC2016 50 echo ' -c $CONF -- set configuration' 51 echo ' -h -- print this help' 52 echo ' -i -- show required inputs' 53 echo ' -r -- show required context' 54 echo ' -v -- show version' 55 echo ' -V -- be verbose' 56 exit 0 57 ;; 58 i) 59 # Need context and current_rules. 60 echo "attributes" 61 echo "current_rules" 62 exit 0 63 ;; 64 r) 65 # Nothing needed from context 66 exit 0 67 ;; 68 v) 69 echo "$0 v0.0.3" 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,"attributes":.attributes}') 91 92 93 # Check form ID, must be 'vqf-902.11' 94 FORM_ID=$(echo "$INPUTS" | jq -r '.attributes.FORM_ID') 95 96 # The 'form' here should be the VQF 902.11 customer form 97 if [ "$FORM_ID" != "vqf_902_1_customer" ] 98 then 99 echo "Unexpected form ID $FORM_ID" 1>&2 100 echo "$INPUTS" | exec taler-exchange-helper-measure-freeze 101 exit 1 102 fi 103 104 # Get entity type 105 LEGAL_ENTITY=$(echo "$INPUTS" | jq -r '.attributes.CUSTOMER_TYPE_VQF // null') 106 # Get current rules. 107 CURRENT_RULES=$(echo "$INPUTS" | jq '.current_rules // null') 108 # Get context values. 109 EXPIRATION_TIME=$(echo "$INPUTS" | jq '.context.expiration_time // .current_rules.expiration_time // null') 110 111 # What is the next form to show? 112 FORM="error" 113 INVESTIGATE="false" 114 115 case "$LEGAL_ENTITY" 116 in 117 "NATURAL_PERSON") 118 FORM="none" 119 # Check all mandatory attributes are present. 120 echo "$INPUTS" \ 121 | jq '.attributes' \ 122 | jq -r 'def get($k): 123 if has($k) 124 then .[$k] 125 else error("attribute \($k) missing") 126 end; 127 {"FULL_NAME":get("FULL_NAME"), 128 "DOMICILE_ADDRESS":get("DOMICILE_ADDRESS"), 129 "DATE_OF_BIRTH":get("DATE_OF_BIRTH"), 130 "NATIONALITY":get("NATIONALITY"), 131 "PERSONAL_IDENTIFICATION_DOCUMENT_COPY":get("PERSONAL_IDENTIFICATION_DOCUMENT_COPY"), 132 "CUSTOMER_IS_SOLE_PROPRIETOR":get("CUSTOMER_IS_SOLE_PROPRIETOR") 133 }' \ 134 > /dev/null \ 135 || exec taler-exchange-helper-measure-freeze 136 ;; 137 "OPERATIONAL") 138 FORM="form-vqf-902.11" 139 # Check all mandatory attributes are present. 140 echo "$INPUTS" \ 141 | jq '.attributes' \ 142 | jq -r 'def get($k): 143 if has($k) 144 then .[$k] 145 else error("attribute \($k) missing") 146 end; 147 {"COMPANY_NAME":get("COMPANY_NAME"), 148 "REGISTERED_OFFICE_ADDRESS":get("REGISTERED_OFFICE_ADDRESS"), 149 "LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY":get("LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY"), 150 "ESTABLISHER_LIST":get("ESTABLISHER_LIST") 151 }' \ 152 > /dev/null \ 153 || exec taler-exchange-helper-measure-freeze 154 ;; 155 "FOUNDATION") 156 # FIXME: #9825: Not yet supported! 157 # FORM="vqf-902.12" 158 FORM=error 159 INVESTIGATE="true" 160 # Check all mandatory attributes are present. 161 echo "$INPUTS" \ 162 | jq '.attributes' \ 163 | jq -r 'def get($k): 164 if has($k) 165 then .[$k] 166 else error("attribute \($k) missing") 167 end; 168 {"COMPANY_NAME":get("COMPANY_NAME"), 169 "REGISTERED_OFFICE_ADDRESS":get("REGISTERED_OFFICE_ADDRESS"), 170 "LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY":get("LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY"), 171 "ESTABLISHER_LIST":get("ESTABLISHER_LIST") 172 }' \ 173 > /dev/null \ 174 || exec taler-exchange-helper-measure-freeze 175 ;; 176 "TRUST") 177 # FIXME: #9027: Not yet supported! 178 # FORM="vqf-902.13" 179 FORM=error 180 INVESTIGATE="true" 181 # Check all mandatory attributes are present. 182 echo "$INPUTS" \ 183 | jq '.attributes' \ 184 | jq -r 'def get($k): 185 if has($k) 186 then .[$k] 187 else error("attribute \($k) missing") 188 end; 189 {"COMPANY_NAME":get("COMPANY_NAME"), 190 "REGISTERED_OFFICE_ADDRESS":get("REGISTERED_OFFICE_ADDRESS"), 191 "LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY":get("LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY"), 192 "ESTABLISHER_LIST":get("ESTABLISHER_LIST") 193 }' \ 194 > /dev/null \ 195 || exec taler-exchange-helper-measure-freeze 196 ;; 197 "LIFE_INSURANCE") 198 # FIXME: #9826: Not yet supported! 199 # FORM="vqf-902.15" 200 FORM=error 201 INVESTIGATE="true" 202 # Check all mandatory attributes are present. 203 echo "$INPUTS" \ 204 | jq '.attributes' \ 205 | jq -r 'def get($k): 206 if has($k) 207 then .[$k] 208 else error("attribute missing") 209 end; 210 {"COMPANY_NAME":get("COMPANY_NAME"), 211 "REGISTERED_OFFICE_ADDRESS":get("REGISTERED_OFFICE_ADDRESS"), 212 "LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY":get("LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY"), 213 "ESTABLISHER_LIST":get("ESTABLISHER_LIST") 214 }' \ 215 > /dev/null \ 216 || exec taler-exchange-helper-measure-freeze 217 ;; 218 "OTHER") 219 FORM="form-vqf-902.9" 220 INVESTIGATE="true" 221 ;; 222 esac 223 224 NEW_MEASURES="null" 225 # Check high-level case 226 case "$FORM" 227 in 228 "error") 229 # This should not happen, immediately trigger investigation and show error to the user. 230 echo "ERROR: Unexpected legal entity '${LEGAL_ENTITY}'" 1>&2 231 NEW_RULES=$(echo "$CURRENT_RULES" | jq '(.rules[] |= if (.measures[0]=="kyx") then .measures=["inform-internal-error"] else . end)') 232 INVESTIGATE="true" 233 ;; 234 "none") 235 # Immediately trigger address validation. 236 echo "$INPUTS" | taler-exchange-helper-measure-tops-address-check 237 exit $? 238 ;; 239 *) 240 # Proceed to FORM. 241 echo "Selected VQF form ${FORM}." 1>&2 242 # Force user to fill in $FORM 243 NEW_RULES=$(echo "$CURRENT_RULES" | jq --arg form "$FORM" '(.rules[] |= if (.measures[0]=="kyx") then .measures=[$form] else . end)') 244 NEW_MEASURES="\"$FORM\"" 245 ;; 246 esac 247 248 # When the information expires, simply ask the user to do the 249 # same form again. 250 SUCCESSOR_MEASURE='"kyx"' 251 252 # Finally, output the new rules. 253 # See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome 254 # for the required output format. 255 256 jq -n \ 257 --argjson inv "$INVESTIGATE" \ 258 --argjson et "$EXPIRATION_TIME" \ 259 --argjson sm "$SUCCESSOR_MEASURE" \ 260 --argjson nm "$NEW_MEASURES" \ 261 --argjson nr "$NEW_RULES" \ 262 ' 263 { 264 "to_investigate": $inv, 265 "new_measures": $nm, 266 "new_rules": ( 267 $nr + { 268 "expiration_time": $et, 269 "successor_measure": $sm, 270 "custom_measures": ({} + $nr.custom_measures) 271 } 272 ) 273 } | del(..|nulls) 274 ' 275 276 exit 0