taler-exchange-helper-measure-tops-kyx-check (9089B)
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 echo "default_rules" 63 exit 0 64 ;; 65 r) 66 # Nothing needed from context 67 exit 0 68 ;; 69 v) 70 echo "$0 v0.0.3" 71 exit 0 72 ;; 73 V) 74 VERBOSE=1 75 ;; 76 ?) 77 exit_fail "Unrecognized command line option" 78 ;; 79 esac 80 done 81 82 if [ 1 = "$VERBOSE" ] 83 then 84 echo "Running $0" 1>&2 85 fi 86 87 # See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlProgramInput 88 # for the full JSON with possible inputs. 89 90 # First, extract inputs we need 91 INPUTS=$(jq '{"current_rules":(.current_rules // .default_rules // error("neither current_rules nor default_rules provided")),"attributes":.attributes}') 92 93 94 # Check form ID, must be 'vqf-902.11' 95 FORM_ID=$(echo "$INPUTS" | jq -r '.attributes.FORM_ID') 96 97 # The 'form' here should be the VQF 902.11 customer form 98 if [ "$FORM_ID" != "vqf_902_1_customer" ] 99 then 100 echo "Unexpected form ID $FORM_ID" 1>&2 101 echo "$INPUTS" | exec taler-exchange-helper-measure-freeze 102 exit 1 103 fi 104 105 # Get entity type 106 LEGAL_ENTITY=$(echo "$INPUTS" | jq -r '.attributes.CUSTOMER_TYPE_VQF // null') 107 # Get current rules. 108 CURRENT_RULES=$(echo "$INPUTS" | jq '.current_rules // null') 109 # Get context values. 110 EXPIRATION_TIME=$(echo "$INPUTS" | jq '.context.expiration_time // .current_rules.expiration_time // null') 111 112 # What is the next form to show? 113 FORM="error" 114 INVESTIGATE="false" 115 116 case "$LEGAL_ENTITY" 117 in 118 "NATURAL_PERSON") 119 FORM="none" 120 # Check all mandatory attributes are present. 121 echo "$INPUTS" \ 122 | jq '.attributes' \ 123 | jq -r 'def get($k): 124 if has($k) 125 then .[$k] 126 else error("attribute \($k) missing") 127 end; 128 {"FULL_NAME":get("FULL_NAME"), 129 "DOMICILE_ADDRESS":get("DOMICILE_ADDRESS"), 130 "DATE_OF_BIRTH":get("DATE_OF_BIRTH"), 131 "NATIONALITY":get("NATIONALITY"), 132 "PERSONAL_IDENTIFICATION_DOCUMENT_COPY":get("PERSONAL_IDENTIFICATION_DOCUMENT_COPY"), 133 "CUSTOMER_IS_SOLE_PROPRIETOR":get("CUSTOMER_IS_SOLE_PROPRIETOR") 134 }' \ 135 > /dev/null \ 136 || exec taler-exchange-helper-measure-freeze 137 ;; 138 "OPERATIONAL") 139 FORM="form-vqf-902.11" 140 # Check all mandatory attributes are present. 141 echo "$INPUTS" \ 142 | jq '.attributes' \ 143 | jq -r 'def get($k): 144 if has($k) 145 then .[$k] 146 else error("attribute \($k) missing") 147 end; 148 {"COMPANY_NAME":get("COMPANY_NAME"), 149 "REGISTERED_OFFICE_ADDRESS":get("REGISTERED_OFFICE_ADDRESS"), 150 "LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY":get("LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY"), 151 "ESTABLISHER_LIST":get("ESTABLISHER_LIST") 152 }' \ 153 > /dev/null \ 154 || exec taler-exchange-helper-measure-freeze 155 ;; 156 "FOUNDATION") 157 # FIXME: #9825: Not yet supported! 158 # FORM="vqf-902.12" 159 FORM=error 160 INVESTIGATE="true" 161 # Check all mandatory attributes are present. 162 echo "$INPUTS" \ 163 | jq '.attributes' \ 164 | jq -r 'def get($k): 165 if has($k) 166 then .[$k] 167 else error("attribute \($k) missing") 168 end; 169 {"COMPANY_NAME":get("COMPANY_NAME"), 170 "REGISTERED_OFFICE_ADDRESS":get("REGISTERED_OFFICE_ADDRESS"), 171 "LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY":get("LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY"), 172 "ESTABLISHER_LIST":get("ESTABLISHER_LIST") 173 }' \ 174 > /dev/null \ 175 || exec taler-exchange-helper-measure-freeze 176 ;; 177 "TRUST") 178 # FIXME: #9027: Not yet supported! 179 # FORM="vqf-902.13" 180 FORM=error 181 INVESTIGATE="true" 182 # Check all mandatory attributes are present. 183 echo "$INPUTS" \ 184 | jq '.attributes' \ 185 | jq -r 'def get($k): 186 if has($k) 187 then .[$k] 188 else error("attribute \($k) missing") 189 end; 190 {"COMPANY_NAME":get("COMPANY_NAME"), 191 "REGISTERED_OFFICE_ADDRESS":get("REGISTERED_OFFICE_ADDRESS"), 192 "LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY":get("LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY"), 193 "ESTABLISHER_LIST":get("ESTABLISHER_LIST") 194 }' \ 195 > /dev/null \ 196 || exec taler-exchange-helper-measure-freeze 197 ;; 198 "LIFE_INSURANCE") 199 # FIXME: #9826: Not yet supported! 200 # FORM="vqf-902.15" 201 FORM=error 202 INVESTIGATE="true" 203 # Check all mandatory attributes are present. 204 echo "$INPUTS" \ 205 | jq '.attributes' \ 206 | jq -r 'def get($k): 207 if has($k) 208 then .[$k] 209 else error("attribute missing") 210 end; 211 {"COMPANY_NAME":get("COMPANY_NAME"), 212 "REGISTERED_OFFICE_ADDRESS":get("REGISTERED_OFFICE_ADDRESS"), 213 "LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY":get("LEGAL_ENTITY_IDENTIFICATION_DOCUMENT_COPY"), 214 "ESTABLISHER_LIST":get("ESTABLISHER_LIST") 215 }' \ 216 > /dev/null \ 217 || exec taler-exchange-helper-measure-freeze 218 ;; 219 "OTHER") 220 FORM="form-vqf-902.9" 221 INVESTIGATE="true" 222 ;; 223 esac 224 225 NEW_MEASURES="null" 226 # Check high-level case 227 case "$FORM" 228 in 229 "error") 230 # This should not happen, immediately trigger investigation and show error to the user. 231 echo "ERROR: Unexpected legal entity '${LEGAL_ENTITY}'" 1>&2 232 NEW_RULES=$(echo "$CURRENT_RULES" | jq '(.rules[] |= if (.measures[0]=="kyx") then .measures=["inform-internal-error"] else . end)') 233 INVESTIGATE="true" 234 ;; 235 "none") 236 # Immediately trigger address validation. 237 echo "$INPUTS" | taler-exchange-helper-measure-tops-address-check 238 exit $? 239 ;; 240 *) 241 # Proceed to FORM. 242 echo "Selected VQF form ${FORM}." 1>&2 243 # Force user to fill in $FORM 244 NEW_RULES=$(echo "$CURRENT_RULES" | jq --arg form "$FORM" '(.rules[] |= if (.measures[0]=="kyx") then .measures=[$form] else . end)') 245 NEW_MEASURES="\"$FORM\"" 246 ;; 247 esac 248 249 # When the information expires, simply ask the user to do the 250 # same form again. 251 SUCCESSOR_MEASURE='"kyx"' 252 253 # Finally, output the new rules. 254 # See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome 255 # for the required output format. 256 257 jq -n \ 258 --argjson inv "$INVESTIGATE" \ 259 --argjson et "$EXPIRATION_TIME" \ 260 --argjson sm "$SUCCESSOR_MEASURE" \ 261 --argjson nm "$NEW_MEASURES" \ 262 --argjson nr "$NEW_RULES" \ 263 ' 264 { 265 "to_investigate": $inv, 266 "new_measures": $nm, 267 "new_rules": ( 268 $nr + { 269 "expiration_time": $et, 270 "successor_measure": $sm, 271 "custom_measures": ({} + $nr.custom_measures) 272 } 273 ) 274 } | del(..|nulls) 275 ' 276 277 exit 0