setup-sandcastle.sh (41254B)
1 #!/usr/bin/env bash 2 3 # This scripts provisions all configuration and 4 # services for the Taler sandcastle container. 5 # 6 # Important: This script needs to be completely 7 # idempotent, nothing must break if it is executed 8 # multiple times. 9 10 set -eu 11 set -x 12 export LC_ALL="C.UTF-8" 13 14 if [[ -n ${SANDCASTLE_SKIP_SETUP:-} ]]; then 15 echo "skipping sandcastle setup, requested by environment var SANDCASTLE_SKIP_SETUP" 16 exit 1 17 fi 18 19 20 # Helper to replace a comment-delimited block of lines in a config file with 21 # the desired content. If the block doesn't exist yet, append it. 22 update_config_block() { 23 local config_file="$1" 24 local marker_tag="$2" 25 local new_content="$3" 26 local begin_marker="# begin ${marker_tag}" 27 local end_marker="# end ${marker_tag}" 28 if [[ ! -f "$config_file" ]]; then 29 echo "Error: Config file '$config_file' not found." >&2 30 return 1 31 fi 32 if grep -qF "$begin_marker" "$config_file"; then 33 # Markers exist. Replace the block. 34 # Escape newlines in the content so sed processes it as a single block 35 local escaped_content="${new_content//$'\n'/\\n}" 36 sed -i "/$begin_marker/,/$end_marker/c\\$begin_marker\n$escaped_content\n$end_marker" "$config_file" 37 else 38 # Markers do not exist. Append to the end. 39 printf "\n%s\n%s\n%s\n" "$begin_marker" "$new_content" "$end_marker" >> "$config_file" 40 fi 41 } 42 43 echo "Provisioning sandcastle" 44 45 # General configuration. 46 # Might eventually be moved to an external file. 47 48 # Source any overrides from external file 49 if [[ -e /overrides ]]; then 50 source /overrides 51 fi 52 53 # When serving on an external port (for localhost deployments), 54 # we use http. 55 if [[ ${EXTERNAL_PORT:-} =~ ^[0-9]+$ ]]; then 56 PROTO=http 57 PORT_SUFFIX=:$EXTERNAL_PORT 58 else 59 PROTO=https 60 PORT_SUFFIX= 61 fi 62 63 : ${CURRENCY:="KUDOS"} 64 : ${WIRE_METHOD:=x-taler-bank} 65 66 67 if [[ $WIRE_METHOD = iban ]]; then 68 EXCHANGE_IBAN=DE159593 69 EXCHANGE_PAYTO="payto://iban/$EXCHANGE_IBAN?receiver-name=Sandcastle+Echange+Inc" 70 71 # Randomly generated IBANs for the merchants 72 MERCHANT_IBAN_ADMIN=DE85500105175178585583 73 MERCHANT_IBAN_POS=DE4218710 74 MERCHANT_IBAN_BLOG=DE8292195 75 MERCHANT_IBAN_GNUNET=DE9709960 76 MERCHANT_IBAN_TALER=DE1740597 77 MERCHANT_IBAN_TOR=DE2648777 78 MERCHANT_IBAN_SANDBOX=DE949115029592 79 MERCHANT_IBAN_UMAMI=DE358841382499 80 MERCHANT_IBAN_TESTING=DE38936850270207298566 81 82 MERCHANT_PAYTO_ADMIN="payto://iban/$MERCHANT_IBAN_ADMIN?receiver-name=Default+Merchant" 83 MERCHANT_PAYTO_TESTING="payto://iban/$MERCHANT_IBAN_TESTING?receiver-name=Testing+Merchant" 84 MERCHANT_PAYTO_POS="payto://iban/$MERCHANT_IBAN_POS?receiver-name=PoS+Merchant" 85 MERCHANT_PAYTO_BLOG="payto://iban/$MERCHANT_IBAN_BLOG?receiver-name=Blog+Merchant" 86 MERCHANT_PAYTO_GNUNET="payto://iban/$MERCHANT_IBAN_GNUNET?receiver-name=GNUnet+Merchant" 87 MERCHANT_PAYTO_TALER="payto://iban/$MERCHANT_IBAN_TALER?receiver-name=Taler+Merchant" 88 MERCHANT_PAYTO_TOR="payto://iban/$MERCHANT_IBAN_TOR?receiver-name=Tor+Merchant" 89 MERCHANT_PAYTO_UMAMI="payto://iban/$MERCHANT_IBAN_UMAMI?receiver-name=Umami" 90 MERCHANT_PAYTO_SANDBOX="payto://iban/$MERCHANT_IBAN_SANDBOX?receiver-name=Sandbox+Merchant" 91 elif [[ $WIRE_METHOD = x-taler-bank ]]; then 92 XTBHOST=sandcastle 93 EXCHANGE_PAYTO="payto://x-taler-bank/$XTBHOST/exchange?receiver-name=Sandcastle+Exchange+Inc" 94 MERCHANT_PAYTO_ADMIN="payto://x-taler-bank/$XTBHOST/merchant-admin?receiver-name=Admin+Merchant" 95 MERCHANT_PAYTO_TESTING="payto://x-taler-bank/$XTBHOST/merchant-testing?receiver-name=Default+Merchant" 96 MERCHANT_PAYTO_POS="payto://x-taler-bank/$XTBHOST/merchant-pos?receiver-name=PoS+Merchant" 97 MERCHANT_PAYTO_BLOG="payto://x-taler-bank/$XTBHOST/merchant-blog?receiver-name=Blog+Merchant" 98 MERCHANT_PAYTO_GNUNET="payto://x-taler-bank/$XTBHOST/merchant-gnunet?receiver-name=GNUnet+Merchant" 99 MERCHANT_PAYTO_TALER="payto://x-taler-bank/$XTBHOST/merchant-taler?receiver-name=Taler+Merchant" 100 MERCHANT_PAYTO_TOR="payto://x-taler-bank/$XTBHOST/merchant-tor?receiver-name=Tor+Merchant" 101 MERCHANT_PAYTO_UMAMI="payto://x-taler-bank/$XTBHOST/merchant-umami?receiver-name=Umami" 102 MERCHANT_PAYTO_SANDBOX="payto://x-taler-bank/$XTBHOST/merchant-sandbox?receiver-name=Sandbox+Merchant" 103 else 104 echo "wire method $WIRE_METHOD not supported" 105 exit 1 106 fi 107 108 MYDOMAIN=${MYDOMAIN:="demo.taler.net"} 109 LANDING_DOMAIN=$MYDOMAIN 110 BANK_DOMAIN=bank.$MYDOMAIN 111 EXCHANGE_DOMAIN=exchange.$MYDOMAIN 112 MERCHANT_DOMAIN=backend.$MYDOMAIN 113 DONAU_DOMAIN=donau.$MYDOMAIN 114 BLOG_DOMAIN=shop.$MYDOMAIN 115 DONATIONS_DOMAIN=donations.$MYDOMAIN 116 DRUPAL_DOMAIN=drupal.$MYDOMAIN 117 CHALLENGER_DOMAIN=challenger.$MYDOMAIN 118 AUDITOR_DOMAIN=auditor.$MYDOMAIN 119 120 # Ports of the services running inside the container. 121 # Should be synchronized with the sandcastle-run script. 122 PORT_INTERNAL_EXCHANGE=8201 123 PORT_INTERNAL_MERCHANT=8301 124 PORT_INTERNAL_LIBEUFIN_BANK=8080 125 PORT_INTERNAL_LANDING=8501 126 PORT_INTERNAL_BLOG=8502 127 PORT_INTERNAL_DONATIONS=8503 128 PORT_INTERNAL_PROVISION=8504 129 PORT_INTERNAL_BANK_SPA=8505 130 PORT_INTERNAL_CHALLENGER=8506 131 PORT_INTERNAL_AUDITOR=8507 132 PORT_INTERNAL_DONAU=8508 133 PORT_INTERNAL_DRUPAL=8509 134 135 136 ENABLE_AUDITOR=0 137 138 # Just make sure the services are stopped 139 systemctl stop postgresql.service 140 systemctl stop taler-auditor.target 141 systemctl stop taler-exchange.target 142 systemctl stop taler-exchange-offline.timer 143 systemctl stop taler-merchant-httpd.service 144 systemctl stop taler-merchant.target 145 systemctl stop taler-demo-landing.service 146 systemctl stop taler-demo-blog.service 147 systemctl stop taler-demo-donations.service 148 systemctl stop libeufin-bank.service 149 systemctl stop donau-httpd.service 150 151 # libeufin-nexus is not used 152 systemctl stop libeufin-nexus-ebics-fetch.service 153 systemctl disable libeufin-nexus-ebics-fetch.service 154 systemctl stop libeufin-nexus-ebics-submit.service 155 systemctl disable libeufin-nexus-ebics-submit.service 156 157 systemctl reset-failed 158 159 # We now make sure that some important locations are symlinked to 160 # the persistent storage volume. 161 # Files that already exist in this location are moved to the storage volume 162 # and then symlinked. 163 # These locations are: 164 # /etc/taler 165 # /etc/libeufin 166 # /var/lib/taler 167 # postgres DB directory 168 169 function lift_dir() { 170 where=$1 171 src=$2 172 target=$3 173 if [[ -L $src ]]; then 174 # be idempotent 175 echo "$src is already a symlink" 176 elif [[ -d /$where/$target ]]; then 177 echo "symlinking existing /$where/$target" 178 rm -rf "$src" 179 ln -s "/$where/$target" "$src" 180 else 181 echo "symlinking new /$where/$target" 182 mv "$src" "/$where/$target" 183 ln -s "/$where/$target" "$src" 184 fi 185 } 186 187 lift_dir talerdata /var/lib/taler-exchange var-lib-taler-exchange 188 lift_dir talerdata /etc/taler-merchant etc-taler-merchant 189 lift_dir talerdata /etc/taler-exchange etc-taler-exchange 190 lift_dir talerdata /etc/taler-exchange etc-taler-auditor 191 lift_dir talerdata /etc/donau etc-donau 192 lift_dir talerdata /etc/libeufin etc-libeufin 193 # lift both config and data 194 lift_dir talerdata /etc/postgresql etc-postgresql 195 lift_dir talerdata /var/lib/postgresql var-lib-postgresql 196 # offline keys are in a separate volume 197 lift_dir talerdata_persistent /var/lib/taler-exchange/offline exchange-offline 198 199 # Usage: get_credential_pw COMPONENT/ACCOUNT 200 function get_credential_pw() { 201 if [[ ${USE_INSECURE_SANDBOX_PASSWORDS:-0} = 1 ]]; then 202 echo "sandbox" 203 return 204 fi 205 p=/credentials/$1 206 if [[ ! -f $p ]]; then 207 mkdir -p $(dirname "$p") 208 uuidgen -r >$p 209 fi 210 cat "$p" 211 } 212 213 import_instr=none 214 if [[ -d /exported && -e /exported/import-request ]]; then 215 import_instr=$(cat /exported/import-request) 216 fi 217 218 # If necessary, import the offline key. 219 # Done before everything else, as we need the key 220 # to generate the config. 221 222 if [[ $import_instr = all ]]; then 223 echo "Importing exchange offline key" 224 rm -rf /var/lib/taler-exchange/offline/* 225 cp -r /exported/taler-exchange/offline/* /var/lib/taler-exchange/offline/ 226 fi 227 228 # Adjust ownership. 229 # Necessary when the container is rebuilt with different user IDs. 230 chown --recursive taler-exchange-offline:taler-exchange-offline /var/lib/taler-exchange/offline/. || true 231 chown root:taler-exchange-db /etc/taler-exchange/secrets/exchange-db.secret.conf 232 chown taler-exchange-wire:root /etc/taler-exchange/secrets/exchange-accountcredentials-*.conf 233 chown taler-merchant-httpd:root /etc/taler-merchant/secrets/merchant-db.secret.conf 234 chown root:donau-db /etc/donau/secrets/donau-db.secret.conf 235 236 237 MASTER_PUBLIC_KEY=$(sudo -u taler-exchange-offline taler-exchange-offline -LDEBUG setup) 238 239 240 # 241 # Create the basic configuration files 242 # 243 244 mkdir -p /etc/challenger/conf.d 245 cat <<EOF >/etc/challenger/conf.d/setup-sandcastle.conf 246 [challenger] 247 BASE_URL = $PROTO://$CHALLENGER_DOMAIN$PORT_SUFFIX/ 248 ADDRESS_TYPE = email 249 AUTH_COMMAND = /data/sandcastle-challenger-auth 250 ADDRESS_RESTRICTIONS = {"email":{"hint":"not an e-mail address","regex":"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$"}} 251 EOF 252 253 cat <<EOF >/etc/libeufin/libeufin-bank.conf 254 [libeufin-bank] 255 BASE_URL = $PROTO://$BANK_DOMAIN$PORT_SUFFIX/ 256 CURRENCY = $CURRENCY 257 DEFAULT_DEBT_LIMIT = $CURRENCY:500 258 REGISTRATION_BONUS = $CURRENCY:100 259 SPA_CAPTCHA_URL = $PROTO://$BANK_DOMAIN$PORT_SUFFIX/webui/#/operation/{woid} 260 SUGGESTED_WITHDRAWAL_EXCHANGE = $PROTO://$EXCHANGE_DOMAIN$PORT_SUFFIX/ 261 ALLOW_REGISTRATION = yes 262 SERVE = tcp 263 PORT = 8080 264 # Bind address. 265 # Option soon to be deprecated! 266 ADDRESS = 0.0.0.0 267 WIRE_TYPE = $WIRE_METHOD 268 269 # Compat mode for now 270 PWD_CHECK = no 271 PWD_AUTH_COMPAT = yes 272 273 [currency-$CURRENCY] 274 ENABLED = YES 275 name = "${NAME:=Kudos}" 276 code = "$CURRENCY" 277 decimal_separator = "." 278 fractional_input_digits = ${FRACTIONALS:=2} 279 fractional_normal_digits = ${FRACTIONALS:=2} 280 fractional_trailing_zero_digits = ${FRACTIONALS:=2} 281 is_currency_name_leading = NO 282 alt_unit_names = {"0":"${ALT_UNIT_NAME:=ク}"} 283 EOF 284 285 cat <<EOF >/etc/libeufin/settings.json 286 { 287 "topNavSites": { 288 "Landing": "$PROTO://$LANDING_DOMAIN$PORT_SUFFIX/", 289 "Bank": "$PROTO://$BANK_DOMAIN$PORT_SUFFIX", 290 "Essay Shop": "$PROTO://$BLOG_DOMAIN$PORT_SUFFIX", 291 "Donations": "$PROTO://$DONATIONS_DOMAIN$PORT_SUFFIX", 292 } 293 } 294 EOF 295 296 # Generate /tmp/sandcastle-setup.conf 297 cat <<EOF >/tmp/sandcastle-setup.conf 298 [currency-$CURRENCY] 299 ENABLED = YES 300 name = "${NAME:=Kudos}" 301 code = "$CURRENCY" 302 decimal_separator = "." 303 fractional_input_digits = ${FRACTIONALS:=2} 304 fractional_normal_digits = ${FRACTIONALS:=2} 305 fractional_trailing_zero_digits = ${FRACTIONALS:=2} 306 is_currency_name_leading = NO 307 alt_unit_names = {"0":"${ALT_UNIT_NAME:=ク}"} 308 EOF 309 310 cp /tmp/sandcastle-setup.conf /etc/taler-exchange/conf.d/sandcastle-setup.conf 311 cp /tmp/sandcastle-setup.conf /etc/taler-merchant/conf.d/sandcastle-setup.conf 312 313 314 cat <<EOF >/etc/taler-exchange/conf.d/sandcastle-exchange.conf 315 [exchange] 316 CURRENCY = $CURRENCY 317 CURRENCY_ROUND_UNIT = $CURRENCY:0.01 318 TINY_AMOUNT = $CURRENCY:0.01 319 AML_THRESHOLD = $CURRENCY:1000000 320 MASTER_PUBLIC_KEY = $MASTER_PUBLIC_KEY 321 BASE_URL = $PROTO://$EXCHANGE_DOMAIN$PORT_SUFFIX/ 322 323 [taler-exchange-secmod-rsa] 324 LOOKAHEAD_SIGN = 4 weeks 325 326 [taler-exchange-secmod-eddsa] 327 LOOKAHEAD_SIGN = 4 weeks 328 329 [taler-exchange-secmod-cs] 330 LOOKAHEAD_SIGN = 4 weeks 331 332 [exchange-account-default] 333 PAYTO_URI = $EXCHANGE_PAYTO 334 ENABLE_DEBIT = YES 335 ENABLE_CREDIT = YES 336 @inline-secret@ exchange-accountcredentials-default ../secrets/exchange-accountcredentials-default.secret.conf 337 EOF 338 339 340 cat <<EOF >/etc/taler-exchange/secrets/exchange-accountcredentials-default.secret.conf 341 [exchange-accountcredentials-default] 342 WIRE_GATEWAY_URL = $PROTO://$BANK_DOMAIN$PORT_SUFFIX/accounts/exchange/taler-wire-gateway/ 343 WIRE_GATEWAY_AUTH_METHOD = basic 344 USERNAME = exchange 345 PASSWORD = $(get_credential_pw bank/exchange) 346 EOF 347 348 if [[ $ENABLE_AUDITOR = 1 ]]; then 349 # Make sandcastle exchange config available to auditor 350 cp /etc/taler-exchange/conf.d/sandcastle-exchange.conf /etc/taler-auditor/conf.d/sandcastle-exchange.conf 351 352 # We run the offline tooling as root, maybe in the future there should be 353 # a separate user created by the Debian package for that. 354 AUDITOR_PUB=$(taler-auditor-offline setup) 355 356 cat <<EOF >/etc/taler-auditor/conf.d/sandcastle-auditor.conf 357 [auditor] 358 PUBLIC_KEY = $AUDITOR_PUB 359 360 [exchangedb] 361 362 $(dup_exchange_opt exchangedb IDLE_RESERVE_EXPIRATION_TIME) 363 $(dup_exchange_opt exchangedb LEGAL_RESERVE_EXPIRATION_TIME) 364 $(dup_exchange_opt exchangedb AGGREGATOR_SHIFT) 365 $(dup_exchange_opt exchangedb DEFAULT_PURSE_LIMIT) 366 367 [exchangedb-postgres] 368 $(dup_exchange_opt exchangedb-postgres CONFIG) 369 370 [exchange] 371 $(dup_exchange_opt exchange CURRENCY) 372 $(dup_exchange_opt exchange CURRENCY_ROUND_UNIT) 373 $(dup_exchange_opt exchange DB) 374 375 376 EOF 377 fi 378 379 # The config shipped with the package can conflict with the 380 # trusted sandcastle exchange if the currency is KUDOS. 381 rm -f /usr/share/taler-exchange/config.d/kudos.conf 382 rm -f /usr/share/taler-merchant/config.d/kudos.conf 383 384 MY_HELPER_EMAIL=${OVERRIDE_MERCHANT_HELPER_EMAIL:-/data/sandcastle-merchant-email-helper} 385 386 # We need to define the default currency for the UI. 387 cat <<EOF >/etc/taler-merchant/conf.d/sandcastle-merchant.conf 388 [merchant] 389 # Default currency 390 CURRENCY = $CURRENCY 391 ENABLE_SELF_PROVISIONING = YES 392 MANDATORY_TAN_CHANNELS = email 393 HELPER_EMAIL = $MY_HELPER_EMAIL 394 395 BASE_URL = $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/ 396 397 # Will be the default in future merchant versions 398 # => Can be removed after 1.6 release 399 BACKOFFICE_SPA_DIR = /usr/share/taler-merchant-webui/ 400 401 EOF 402 403 cat <<EOF >/etc/taler-merchant/conf.d/sandcastle-merchant-exchanges.conf 404 [merchant-exchange-sandcastle] 405 EXCHANGE_BASE_URL = $PROTO://$EXCHANGE_DOMAIN$PORT_SUFFIX/ 406 MASTER_KEY = $MASTER_PUBLIC_KEY 407 CURRENCY = $CURRENCY 408 EOF 409 410 # Allow overrides to modify merchant config 411 [[ $(type -t hook_merchant_config) == function ]] && hook_merchant_config 412 413 # FIXME: This is a workaround, fix the packaging of taler-merchant-frontends here! 414 mkdir -p /etc/taler 415 416 cat <<EOF >/etc/taler/taler-merchant-frontends.conf 417 # Different entry point, we need to repeat some settings. 418 # In the future, taler-merchant-demos should become 419 # robust enough to read from the main config. 420 [taler] 421 CURRENCY = $CURRENCY 422 423 [frontend-demo-landing] 424 SERVE = http 425 HTTP_PORT = $PORT_INTERNAL_LANDING 426 427 [frontend-demo-blog] 428 SERVE = http 429 HTTP_PORT = $PORT_INTERNAL_BLOG 430 BACKEND_URL = $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/blog/ 431 BACKEND_APIKEY = secret-token:$(get_credential_pw merchant/blog) 432 ENABLE_TOKENS = ${ENABLE_SUBSCRIPTIONS:-no} 433 434 [frontend-demo-donations] 435 DONAU_URL = $PROTO://$DONAU_DOMAIN$PORT_SUFFIX/ 436 SERVE = http 437 HTTP_PORT = $PORT_INTERNAL_DONATIONS 438 BACKEND_URL_TOR = $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/tor/ 439 BACKEND_APIKEY_TOR = secret-token:$(get_credential_pw merchant/tor) 440 BACKEND_URL_TALER = $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/taler/ 441 BACKEND_APIKEY_TALER = secret-token:$(get_credential_pw merchant/taler) 442 BACKEND_URL_GNUNET = $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/gnunet/ 443 BACKEND_APIKEY_GNUNET = secret-token:$(get_credential_pw merchant/gnunet) 444 EOF 445 446 # This really should not exist, the taler-merchant-frontends 447 # should be easier to configure! 448 cat <<EOF >/etc/taler/taler-merchant-frontends.env 449 TALER_ENV_URL_INTRO=$PROTO://$LANDING_DOMAIN$PORT_SUFFIX/ 450 TALER_ENV_URL_LANDING=$PROTO://$LANDING_DOMAIN$PORT_SUFFIX/ 451 TALER_ENV_URL_BANK=$PROTO://$BANK_DOMAIN$PORT_SUFFIX/ 452 TALER_ENV_URL_MERCHANT_BLOG=$PROTO://$BLOG_DOMAIN$PORT_SUFFIX/ 453 TALER_ENV_URL_MERCHANT_DONATIONS=$PROTO://$DONATIONS_DOMAIN$PORT_SUFFIX/ 454 EOF 455 456 # 457 # Create databases 458 # 459 460 function wait_pg_ready() { 461 while true; do 462 ret=0 463 pg_isready || ret=$? 464 case "$ret" in 465 0) 466 echo "Postgres is ready" >&2 467 break 468 ;; 469 1|2) 470 echo "pg_isready returned status $ret, waiting" >&2 471 sleep 1 472 ;; 473 3) 474 echo "pg_isready returned status $ret, giving up" >&2 475 exit 3 476 ;; 477 esac 478 done 479 } 480 481 PG_VERSION="17" 482 483 # Since the sandcastle is a test system, we turn fsync off for performance 484 # reasons (especially with the drupal setup). 485 # CAUTION: You do not want to set this in production, 486 # especially not for the taler-exchange. 487 pg_conftool $PG_VERSION main set fsync off 488 # Higher limits needed for migration 489 pg_conftool $PG_VERSION main set max_locks_per_transaction 512 490 pg_conftool $PG_VERSION main set max_pred_locks_per_transaction 512 491 492 backup_file=/exported/postgres-backup.sql 493 if [[ $import_instr = singledump ]]; then 494 echo "Importing database dump" 495 if [[ ! -e "$backup_file" ]]; then 496 echo "Requested import, but backup file does not exist" >&2 497 exit 1 498 fi 499 pg_dropcluster --stop 17 main || true 500 pg_createcluster 17 main 501 systemctl start postgresql.service 502 wait_pg_ready 503 sudo -u postgres psql postgres -f "$backup_file" 504 else 505 systemctl start postgresql.service 506 wait_pg_ready 507 fi 508 509 # Set up databases. 510 # Do that *before* we potentially do a per-service restore-from-backup. 511 512 challenger-dbconfig 513 514 # Sets up the database for both libeufin-bank and libeufin-nexus. We only need 515 # the libeufin-bank DB though. 516 libeufin-dbconfig 517 518 if [[ $ENABLE_AUDITOR = 1 ]]; then 519 # Add auditor user to DB group *before* running taler-exchange-dbconfig, 520 # so that DB permissions are adjusted accordingly. 521 usermod taler-auditor-httpd -aG taler-exchange-db 522 taler-auditor-dbconfig 523 fi 524 525 taler-exchange-dbconfig 526 527 taler-merchant-dbconfig 528 529 530 # 531 # Import backup if necessary. 532 # 533 534 if [[ $import_instr = all ]]; then 535 echo "Importing databases" 536 537 # FIXME: Consider backing up old DB before importing new one 538 # FIXME: This is rather hacky, it would be better to use "pg_dump -Fc" and "pg_restore" 539 sudo -u postgres dropdb taler-exchange 540 sudo -u postgres dropdb taler-merchant 541 sudo -u postgres dropdb libeufin 542 543 sudo -u postgres createdb taler-exchange 544 sudo -u postgres createdb taler-merchant 545 sudo -u postgres createdb libeufin 546 547 sudo -u postgres psql taler-exchange -f /exported/taler-exchange/taler-exchange.sql 548 sudo -u postgres psql taler-merchant -f /exported/taler-merchant/taler-merchant.sql 549 sudo -u postgres psql libeufin -f /exported/libeufin/libeufin.sql 550 551 libeufin-dbconfig 552 taler-exchange-dbconfig 553 taler-merchant-dbconfig 554 555 rm -rf /var/lib/taler-exchange/secmod-eddsa/* 556 cp -r /exported/taler-exchange/secmod-eddsa/* /var/lib/taler-exchange/secmod-eddsa/ 557 558 rm -rf /var/lib/taler-exchange/secmod-rsa/* 559 cp -r /exported/taler-exchange/secmod-rsa/* /var/lib/taler-exchange/secmod-rsa/ 560 561 rm -rf /var/lib/taler-exchange/secmod-cs/* 562 cp -r /exported/taler-exchange/secmod-cs/* /var/lib/taler-exchange/secmod-cs/ 563 fi 564 565 if [[ $import_instr != none ]]; then 566 echo "Marking import as done" 567 rm /exported/import-request 568 fi 569 570 # We need to adjust file ownership, as the container might have different user and group 571 # IDs than the volume. That can happen when the packages in the container are installed 572 # in a different order. 573 # This is only relevant for non-root ownership. 574 chown --recursive taler-exchange-offline:taler-exchange-offline /var/lib/taler-exchange/offline/* || true 575 chown --recursive taler-exchange-secmod-cs:taler-exchange-secmod /var/lib/taler-exchange/secmod-cs 576 chown --recursive taler-exchange-secmod-rsa:taler-exchange-secmod /var/lib/taler-exchange/secmod-rsa 577 chown --recursive taler-exchange-secmod-eddsa:taler-exchange-secmod /var/lib/taler-exchange/secmod-eddsa 578 chown root:taler-exchange-db /etc/taler-exchange/secrets/exchange-db.secret.conf 579 chown root:taler-auditor-httpd /etc/taler-auditor/secrets/auditor-db.secret.conf 580 chmod 440 /etc/taler-merchant/secrets/merchant-db.secret.conf 581 chown taler-merchant-httpd:root /etc/taler-merchant/secrets/merchant-db.secret.conf 582 chown root:taler-exchange-db /etc/taler-exchange/secrets/exchange-db.secret.conf 583 chown taler-exchange-wire:taler-exchange-db /etc/taler-exchange/secrets/exchange-accountcredentials-default.secret.conf 584 585 586 # Caddy configuration. 587 # We use the caddy reverse proxy with automatic 588 # internal TLS setup to ensure that the services are 589 # reachable inside the container without any external 590 # DNS setup under the same domain name and with TLS 591 # from inside the container. 592 593 systemctl stop caddy.service 594 595 cat <<EOF >/etc/caddy/Caddyfile 596 { 597 servers { 598 trusted_proxies static private_ranges 599 } 600 } 601 602 # Services that only listen on unix domain sockets 603 # are reverse-proxied to serve on a TCP port. 604 605 :$PORT_INTERNAL_EXCHANGE { 606 reverse_proxy unix//run/taler-exchange/httpd/exchange-http.sock 607 } 608 609 :$PORT_INTERNAL_MERCHANT { 610 reverse_proxy unix//run/taler-merchant/httpd/merchant-http.sock { 611 # Set this, or otherwise wrong taler://pay URIs will be generated. 612 header_up X-Forwarded-Proto "https" 613 } 614 } 615 616 :$PORT_INTERNAL_DONAU { 617 reverse_proxy unix//run/donau/httpd/http.sock { 618 header_up X-Forwarded-Proto "https" 619 } 620 } 621 622 :$PORT_INTERNAL_BANK_SPA { 623 root * /usr/share/libeufin/spa 624 root /settings.json /etc/libeufin/ 625 file_server 626 } 627 628 :$PORT_INTERNAL_DRUPAL { 629 root * /talerdata/sandcastle-drupal/web/ 630 php_fastcgi unix/var/run/php/php8.4-fpm.sock 631 file_server 632 } 633 634 :$PORT_INTERNAL_AUDITOR { 635 reverse_proxy unix//run/taler-auditor/httpd/auditor-http.sock 636 } 637 638 :$PORT_INTERNAL_CHALLENGER { 639 handle { 640 reverse_proxy unix//run/challenger/httpd/challenger.http { 641 # Set this, or otherwise wrong taler://pay URIs will be generated. 642 header_up X-Forwarded-Proto "https" 643 } 644 } 645 646 # Serve challenges via HTTP. 647 # This is obviously completely insecure, but fine 648 # for the demo sandcastle. 649 handle_path /challenges/* { 650 root * /tmp/challenges/ 651 file_server { 652 browse 653 } 654 } 655 } 656 EOF 657 658 if [[ $PROTO = https ]]; then 659 cat <<EOF >>/etc/caddy/Caddyfile 660 661 # Internally reverse-proxy https://, 662 # so that service can talk to each other via 663 # https:// inside the container. 664 665 https://$BANK_DOMAIN { 666 tls internal 667 reverse_proxy :8080 { 668 # libeufin-bank should eventually not require this anymore, 669 # but currently doesn't work without this header. 670 header_up X-Forwarded-Prefix "" 671 } 672 } 673 674 https://$EXCHANGE_DOMAIN { 675 tls internal 676 reverse_proxy unix//run/taler-exchange/httpd/exchange-http.sock 677 } 678 679 https://$MERCHANT_DOMAIN { 680 tls internal 681 reverse_proxy unix//run/taler-merchant/httpd/merchant-http.sock { 682 # Set this, or otherwise wrong taler://pay URIs will be generated. 683 header_up X-Forwarded-Proto "https" 684 } 685 } 686 687 https://$DONAU_DOMAIN { 688 tls internal 689 reverse_proxy unix//run/donau/httpd/http.sock { 690 header_up X-Forwarded-Proto "https" 691 } 692 } 693 694 https://$AUDITOR_DOMAIN { 695 tls internal 696 reverse_proxy unix//run/taler-auditor/httpd/auditor-http.sock 697 } 698 699 https://$CHALLENGER_DOMAIN { 700 tls internal 701 reverse_proxy unix//run/challenger/httpd/challenger.http 702 } 703 704 EOF 705 706 else 707 # Config for HTTP without TLS. 708 709 cat <<EOF >>/etc/caddy/Caddyfile 710 711 http://$BANK_DOMAIN$PORT_SUFFIX { 712 reverse_proxy :8080 { 713 # libeufin-bank should eventually not require this anymore, 714 # but currently doesn't work without this header. 715 header_up X-Forwarded-Prefix "" 716 } 717 } 718 719 http://$EXCHANGE_DOMAIN$PORT_SUFFIX { 720 reverse_proxy unix//run/taler-exchange/httpd/exchange-http.sock 721 } 722 723 http://$MERCHANT_DOMAIN$PORT_SUFFIX { 724 reverse_proxy unix//run/taler-merchant/httpd/merchant-http.sock 725 } 726 727 http://$DONAU_DOMAIN$PORT_SUFFIX { 728 reverse_proxy unix//run/donau/httpd/http.sock 729 } 730 731 http://$AUDITOR_DOMAIN$PORT_SUFFIX { 732 reverse_proxy unix//run/taler-auditor/httpd/auditor-http.sock 733 } 734 735 http://$CHALLENGER_DOMAIN$PORT_SUFFIX { 736 reverse_proxy unix//run/challenger/httpd/challenger.http 737 } 738 739 http://$LANDING_DOMAIN$PORT_SUFFIX { 740 reverse_proxy :$PORT_INTERNAL_LANDING 741 } 742 743 http://$BLOG_DOMAIN$PORT_SUFFIX { 744 reverse_proxy :$PORT_INTERNAL_BLOG 745 } 746 747 http://$DONATIONS_DOMAIN$PORT_SUFFIX { 748 reverse_proxy :$PORT_INTERNAL_DONATIONS 749 } 750 751 http://$DRUPAL_DOMAIN$PORT_SUFFIX { 752 reverse_proxy :$PORT_INTERNAL_DRUPAL 753 } 754 755 EOF 756 757 fi 758 759 cat <<EOF >>/etc/hosts 760 # Start of Taler Sandcastle Domains 761 127.0.0.1 $LANDING_DOMAIN 762 127.0.0.1 $BANK_DOMAIN 763 127.0.0.1 $EXCHANGE_DOMAIN 764 127.0.0.1 $MERCHANT_DOMAIN 765 127.0.0.1 $BLOG_DOMAIN 766 127.0.0.1 $DONATIONS_DOMAIN 767 127.0.0.1 $CHALLENGER_DOMAIN 768 127.0.0.1 $DRUPAL_DOMAIN 769 # End of Taler Sandcastle Domains 770 EOF 771 772 systemctl start caddy.service 773 774 # Install local, internal CA certs for caddy 775 caddy trust 776 777 # Set up challenger 778 779 CHALLENGER_CLIENT_SECRET=secret-token:sandbox 780 CHALLENGER_CLIENT_ID=$(sudo -u challenger-httpd challenger-admin -q --add="$CHALLENGER_CLIENT_SECRET" https://$EXCHANGE_DOMAIN/kyc-proof/mychallenger) 781 echo Challenger client ID: $CHALLENGER_CLIENT_ID 782 783 systemctl enable --now challenger-httpd.service 784 785 # Set up bank 786 787 sudo -u libeufin-bank libeufin-bank edit-account admin --debit_threshold=$CURRENCY:10000000 788 sudo -u libeufin-bank libeufin-bank passwd admin $(get_credential_pw bank/admin) 789 790 systemctl enable --now libeufin-bank.service 791 792 BANK_BASEURL=$PROTO://$BANK_DOMAIN$PORT_SUFFIX/ 793 794 taler-harness deployment wait-taler-service taler-corebank ${BANK_BASEURL}config 795 796 sudo -u libeufin-bank libeufin-bank passwd exchange $(get_credential_pw bank/exchange) || true 797 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 798 --login exchange --exchange --public \ 799 --payto $EXCHANGE_PAYTO \ 800 --name Exchange \ 801 --password $(get_credential_pw bank/exchange) 802 803 sudo -u libeufin-bank libeufin-bank passwd merchant-admin $(get_credential_pw bank/merchant-admin) || true 804 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 805 --login merchant-admin --public \ 806 --payto $MERCHANT_PAYTO_ADMIN \ 807 --name "Default Demo Merchant" \ 808 --password $(get_credential_pw bank/merchant-admin) 809 810 sudo -u libeufin-bank libeufin-bank passwd merchant-admin $(get_credential_pw bank/merchant-testing) || true 811 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 812 --login merchant-testing --public \ 813 --payto $MERCHANT_PAYTO_TESTING \ 814 --name "Testing Merchant" \ 815 --password $(get_credential_pw bank/merchant-testing) 816 817 sudo -u libeufin-bank libeufin-bank passwd merchant-pos $(get_credential_pw bank/merchant-pos) || true 818 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 819 --login merchant-pos --public \ 820 --payto $MERCHANT_PAYTO_POS \ 821 --name "PoS Merchant" \ 822 --password $(get_credential_pw bank/merchant-pos) 823 824 sudo -u libeufin-bank libeufin-bank passwd merchant-blog $(get_credential_pw bank/merchant-blog) || true 825 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 826 --login merchant-blog --public \ 827 --payto $MERCHANT_PAYTO_BLOG \ 828 --name "Blog Merchant" \ 829 --password $(get_credential_pw bank/merchant-blog) 830 831 sudo -u libeufin-bank libeufin-bank passwd merchant-gnunet $(get_credential_pw bank/merchant-gnunet) || true 832 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 833 --login merchant-gnunet --public \ 834 --payto "$MERCHANT_PAYTO_GNUNET" \ 835 --name "GNUnet Donations Merchant" \ 836 --password $(get_credential_pw bank/merchant-gnunet) 837 838 sudo -u libeufin-bank libeufin-bank passwd merchant-taler $(get_credential_pw bank/merchant-taler) || true 839 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 840 --login merchant-taler --public \ 841 --payto "$MERCHANT_PAYTO_TALER" \ 842 --name "Taler Donations Merchant" \ 843 --password $(get_credential_pw bank/merchant-taler) 844 845 sudo -u libeufin-bank libeufin-bank passwd merchant-tor $(get_credential_pw bank/merchant-tor) || true 846 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 847 --login merchant-tor --public \ 848 --payto "$MERCHANT_PAYTO_TOR" \ 849 --name "Tor Donations Merchant" \ 850 --password $(get_credential_pw bank/merchant-tor) 851 852 sudo -u libeufin-bank libeufin-bank passwd merchant-umami $(get_credential_pw bank/merchant-umami) || true 853 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 854 --login merchant-umami --public \ 855 --payto "$MERCHANT_PAYTO_UMAMI" \ 856 --name "Umami Merchant" \ 857 --password $(get_credential_pw bank/merchant-umami) 858 859 # Special bank account without a secure password 860 sudo -u libeufin-bank libeufin-bank passwd merchant-sandbox sandbox || true 861 taler-harness deployment provision-bank-account "${BANK_BASEURL}" \ 862 --login merchant-sandbox --public \ 863 --payto "$MERCHANT_PAYTO_SANDBOX" \ 864 --name "Sandbox Merchant" \ 865 --password sandbox 866 867 # Set up exchange 868 869 ## 870 ## Configure KYC if enabled 871 ## 872 873 if [[ ${ENABLE_KYC:-0} = 1 ]]; then 874 # KYC config 875 if [[ ${KYC_DIALECT:-simple} = simple ]]; then 876 source /data/setup-kyc-simple.sh 877 elif [[ ${KYC_DIALECT:-simple} = tops ]]; then 878 source /data/setup-kyc-tops.sh 879 fi 880 else 881 rm -f /etc/taler-exchange/conf.d/sandcastle-kyc.conf 882 fi 883 884 885 if [[ ! -e /etc/taler-exchange/conf.d/sandcastle-$CURRENCY-coins.conf ]]; then 886 # Only create if necessary, as each [COIN-...] section 887 # has a unique name with a timestamp. 888 taler-harness deployment gen-coin-config \ 889 --min-amount "${CURRENCY}:0.01" \ 890 --max-amount "${CURRENCY}:100" \ 891 --no-fees \ 892 >"/etc/taler-exchange/conf.d/sandcastle-$CURRENCY-coins.conf" 893 else 894 # Exchange broke backwards compatibility, fix up existing config file. 895 sed -i 's/COIN-/COIN_/gI' "/etc/taler-exchange/conf.d/sandcastle-$CURRENCY-coins.conf" 896 fi 897 898 taler-terms-generator -i /usr/share/taler-exchange/terms/exchange-tos-v0 899 taler-terms-generator -i /usr/share/taler-exchange/terms/exchange-pp-v0 900 901 systemctl enable --now taler-exchange.target 902 903 taler-harness deployment wait-taler-service taler-exchange $PROTO://$EXCHANGE_DOMAIN$PORT_SUFFIX/config 904 taler-harness deployment wait-endpoint $PROTO://$EXCHANGE_DOMAIN$PORT_SUFFIX/management/keys 905 906 sudo -u taler-exchange-offline \ 907 taler-exchange-offline \ 908 -c /etc/taler-exchange/taler-exchange.conf \ 909 download \ 910 sign \ 911 upload 912 913 sudo -u taler-exchange-offline \ 914 taler-exchange-offline \ 915 enable-account "${EXCHANGE_PAYTO}" \ 916 wire-fee now "$WIRE_METHOD" "${CURRENCY}":0 "${CURRENCY}":0 \ 917 global-fee now "${CURRENCY}":0 "${CURRENCY}":0 "${CURRENCY}":0 1h 6a 0 \ 918 upload 919 920 systemctl enable --now taler-exchange-offline.timer 921 922 function dup_exchange_opt() { 923 echo "$2 = $(taler-exchange-config -c /etc/taler-exchange/taler-exchange.conf -s $1 -o $2)" 924 } 925 926 # 927 # Set up exchange auditor 928 # 929 930 if [[ $ENABLE_AUDITOR = 1 ]]; then 931 systemctl enable --now taler-auditor.target 932 fi 933 934 # Set up merchant backend 935 936 MERCHANT_BASEURL=$PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/ 937 938 cat <<EOF >/etc/taler-merchant/conf.d/sandcastle-merchant-terms.conf 939 [merchant] 940 TERMS_ETAG = merchant-tos-demo-v0 941 TERMS_DIR = \${TALER_DATA_HOME}terms/ 942 EOF 943 944 taler-terms-generator -i /usr/share/taler-merchant/terms/merchant-tos-demo-v0.en.rst -o "$(taler-merchant-config -f -s merchant -o terms_dir)" 945 946 systemctl enable --now taler-merchant.target 947 taler-harness deployment wait-taler-service taler-merchant ${MERCHANT_BASEURL}config 948 949 function reset_merchant_pw() { 950 pw=$(get_credential_pw merchant/$1) 951 sudo -u taler-merchant-httpd taler-merchant-passwd --instance "$1" "$pw" 952 if [[ $? -eq 2 ]]; then 953 echo "Instance $1 does not exist" >&2 954 return 2 955 fi 956 if [[ $? -ne 0 ]]; then 957 echo "Failed to reset password for merchant instance $1" >&2 958 exit 1 959 fi 960 } 961 962 # FIXME: Move this into a harness tool (that just reads a config file)? 963 964 instance_missing=no 965 reset_merchant_pw admin || instance_missing=yes 966 if [[ $instance_missing = yes ]]; then 967 taler-harness deployment provision-merchant-instance \ 968 ${MERCHANT_BASEURL} \ 969 --management-token "secret-token:none" \ 970 --instance-password $(get_credential_pw merchant/admin) \ 971 --name Merchant \ 972 --id admin \ 973 --payto "$MERCHANT_PAYTO_ADMIN" 974 fi 975 976 ADMIN_TOK=$(taler-harness merchant token ${MERCHANT_BASEURL} admin --password $(get_credential_pw merchant/admin)) 977 978 instance_missing=no 979 reset_merchant_pw pos || instance_missing=yes 980 if [[ $instance_missing = yes ]]; then 981 taler-harness deployment provision-merchant-instance \ 982 ${MERCHANT_BASEURL} \ 983 --management-token $ADMIN_TOK \ 984 --instance-password $(get_credential_pw merchant/pos) \ 985 --name "POS Merchant" \ 986 --id pos \ 987 --payto "$MERCHANT_PAYTO_POS" 988 fi 989 990 instance_missing=no 991 reset_merchant_pw testing || instance_missing=yes 992 if [[ $instance_missing = yes ]]; then 993 taler-harness deployment provision-merchant-instance \ 994 ${MERCHANT_BASEURL} \ 995 --management-token $ADMIN_TOK \ 996 --instance-password $(get_credential_pw merchant/testing) \ 997 --name "Testing Merchant" \ 998 --id testing \ 999 --payto "$MERCHANT_PAYTO_TESTING" 1000 fi 1001 1002 instance_missing=no 1003 reset_merchant_pw blog || instance_missing=yes 1004 if [[ $instance_missing = yes ]]; then 1005 taler-harness deployment provision-merchant-instance \ 1006 ${MERCHANT_BASEURL} \ 1007 --management-token $ADMIN_TOK \ 1008 --instance-password $(get_credential_pw merchant/blog) \ 1009 --name "Blog Merchant" \ 1010 --id blog \ 1011 --payto "$MERCHANT_PAYTO_BLOG" 1012 fi 1013 1014 instance_missing=no 1015 reset_merchant_pw gnunet || instance_missing=yes 1016 if [[ $instance_missing = yes ]]; then 1017 taler-harness deployment provision-merchant-instance \ 1018 ${MERCHANT_BASEURL} \ 1019 --management-token $ADMIN_TOK \ 1020 --instance-password $(get_credential_pw merchant/gnunet) \ 1021 --name "GNUnet Merchant" \ 1022 --id gnunet \ 1023 --payto "$MERCHANT_PAYTO_GNUNET" 1024 fi 1025 1026 instance_missing=no 1027 reset_merchant_pw taler || instance_missing=yes 1028 if [[ $instance_missing = yes ]]; then 1029 taler-harness deployment provision-merchant-instance \ 1030 ${MERCHANT_BASEURL} \ 1031 --management-token $ADMIN_TOK \ 1032 --instance-password $(get_credential_pw merchant/taler) \ 1033 --name "Taler Merchant" \ 1034 --id taler \ 1035 --payto "$MERCHANT_PAYTO_TALER" 1036 fi 1037 1038 instance_missing=no 1039 reset_merchant_pw tor || instance_missing=yes 1040 if [[ $instance_missing = yes ]]; then 1041 taler-harness deployment provision-merchant-instance \ 1042 ${MERCHANT_BASEURL} \ 1043 --management-token $ADMIN_TOK \ 1044 --instance-password $(get_credential_pw merchant/tor) \ 1045 --name "Tor Merchant" \ 1046 --id tor \ 1047 --payto "$MERCHANT_PAYTO_TOR" 1048 fi 1049 1050 instance_missing=no 1051 reset_merchant_pw umami || instance_missing=yes 1052 if [[ $instance_missing = yes ]]; then 1053 taler-harness deployment provision-merchant-instance \ 1054 ${MERCHANT_BASEURL} \ 1055 --management-token $ADMIN_TOK \ 1056 --instance-password $(get_credential_pw merchant/umami) \ 1057 --name "Umami Merchant" \ 1058 --id umami \ 1059 --payto "$MERCHANT_PAYTO_UMAMI" 1060 fi 1061 1062 # Special instance with fixed "sandbox" password 1063 sudo -u taler-merchant-httpd taler-merchant-passwd --instance sandbox sandbox || true 1064 taler-harness deployment provision-merchant-instance \ 1065 ${MERCHANT_BASEURL} \ 1066 --management-token $ADMIN_TOK \ 1067 --instance-password sandbox \ 1068 --name "sandbox merchant" \ 1069 --id sandbox \ 1070 --payto "$MERCHANT_PAYTO_SANDBOX" 1071 1072 # token families needed by demo blog 1073 1074 langs=(de en ar zh fr hi it ja ko pt pt_BR ru es sv tr uk) 1075 valid_before_ts=$(date -u +%s -d '+1 year') # one year later 1076 duration_us=$((30 * 24 * 60 * 60 * 1000000)) # 30 days 1077 validity_granularity_us=$((24 * 60 * 60 * 1000000)) # 1 day 1078 1079 # FIXME: Move this into a harness tool? 1080 for lang in "${langs[@]}"; do 1081 curl -X POST "${MERCHANT_BASEURL}instances/blog/private/tokenfamilies" \ 1082 -H "Authorization: Bearer secret-token:$(get_credential_pw merchant/blog)" \ 1083 -H "Content-Type: application/json" \ 1084 --data-raw "{ 1085 \"kind\": \"subscription\", 1086 \"slug\": \"blog_abo_${lang}\", 1087 \"name\": \"One month of access (${lang})\", 1088 \"description\": \"One month of access (${lang})\", 1089 \"description_i18n\": { 1090 \"de\": \"Ein monat lang Zugang zu den Artikeln\", 1091 \"en\": \"One month of access to articles\", 1092 \"fr\": \"Un mois d'accès aux articles\", 1093 \"es\": \"Un mes de acceso a los artículos\" 1094 }, 1095 \"valid_before\": { \"t_s\": ${valid_before_ts} }, 1096 \"duration\": { \"d_us\": ${duration_us} }, 1097 \"validity_granularity\": { \"d_us\": ${validity_granularity_us} } 1098 }" 1099 done 1100 1101 1102 1103 # Set up Donau 1104 1105 cat <<EOF >/etc/donau/conf.d/sandcastle.conf 1106 [donau] 1107 CURRENCY = $CURRENCY 1108 LEGAL_DOMAIN = Gnuland 1109 EXPIRE_LEGAL_YEARS = 3 1110 # We don't do the token yet, as the merchant doesn't support 1111 # authenticating with donau. 1112 # ADMIN_BEARER_TOKEN = secret-token:secret 1113 EOF 1114 1115 donau-dbconfig 1116 1117 if [[ ! -e /etc/donau/conf.d/sandcastle-$CURRENCY-units.conf ]]; then 1118 # Only create if necessary 1119 taler-harness deployment gen-doco-config \ 1120 --min-amount "${CURRENCY}:0.01" \ 1121 --max-amount "${CURRENCY}:100" \ 1122 >"/etc/donau/conf.d/sandcastle-$CURRENCY-units.conf" 1123 fi 1124 1125 systemctl enable --now donau.target 1126 1127 DONAU_BASE_URL=$PROTO://$DONAU_DOMAIN$PORT_SUFFIX/ 1128 1129 taler-harness deployment wait-taler-service donau ${DONAU_BASE_URL}config 1130 1131 if [[ ${ENABLE_TALDIR:-0} == 1 ]]; then 1132 # Mailbox and Directory 1133 mkdir -p /etc/taler-directory 1134 cp /usr/share/taler-directory/taldir.conf.example /etc/taler-directory/taler-directory.conf 1135 taler-directory-dbconfig 1136 systemctl enable --now taler-directory.service 1137 fi 1138 1139 if [[ ${ENABLE_MAILBOX:-0} == 1 ]]; then 1140 mkdir -p /etc/taler-mailbox 1141 cp /usr/share/taler-mailbox/mailbox.conf.example /etc/taler-mailbox/taler-mailbox.conf 1142 sed -i 's/localhost:11000/localhost:12000/' /etc/taler-mailbox/taler-mailbox.conf 1143 taler-mailbox-dbconfig 1144 systemctl enable --now taler-mailbox.service 1145 fi 1146 1147 GNUNET_TOK=$(taler-harness merchant token ${MERCHANT_BASEURL}instances/gnunet/ gnunet --password $(get_credential_pw merchant/gnunet)) 1148 taler-harness deployment provision-merchant-donau \ 1149 --merchant-auth-token $GNUNET_TOK \ 1150 --merchant-base-url $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/gnunet/ \ 1151 --donau-base-url $DONAU_BASE_URL \ 1152 --donau-auth-token secret-token:secret \ 1153 --currency $CURRENCY 1154 1155 TALER_TOK=$(taler-harness merchant token ${MERCHANT_BASEURL}instances/taler/ taler --password $(get_credential_pw merchant/taler)) 1156 taler-harness deployment provision-merchant-donau \ 1157 --merchant-auth-token $TALER_TOK \ 1158 --merchant-base-url $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/taler/ \ 1159 --donau-base-url $DONAU_BASE_URL \ 1160 --donau-auth-token secret-token:secret \ 1161 --currency $CURRENCY 1162 1163 TOR_TOK=$(taler-harness merchant token ${MERCHANT_BASEURL}instances/tor/ tor --password $(get_credential_pw merchant/tor)) 1164 taler-harness deployment provision-merchant-donau \ 1165 --merchant-auth-token $TOR_TOK \ 1166 --merchant-base-url $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/tor/ \ 1167 --donau-base-url $DONAU_BASE_URL \ 1168 --donau-auth-token secret-token:secret \ 1169 --currency $CURRENCY 1170 1171 UMAMI_TOK=$(taler-harness merchant token ${MERCHANT_BASEURL}instances/umami/ umami --password $(get_credential_pw merchant/umami)) 1172 1173 # Now we set up the taler-merchant-demos 1174 1175 systemctl enable --now taler-demo-landing 1176 systemctl enable --now taler-demo-blog 1177 systemctl enable --now taler-demo-donations 1178 1179 # Turnstile (drupal/php) 1180 1181 1182 systemctl enable --now php8.4-fpm 1183 1184 DRUPAL_DB_PW=$(get_credential_pw db/drupal) 1185 DRUPAL_ADMIN_PW=$(get_credential_pw drupal/admin) 1186 1187 sudo -i -u postgres psql postgres -c "CREATE ROLE drupal WITH login;" || true 1188 sudo -i -u postgres psql postgres -c "ALTER ROLE drupal password '$DRUPAL_DB_PW';" 1189 sudo -u postgres createdb drupal --owner=drupal || true 1190 1191 # Needed by PHP's composer 1192 export HOME=/root 1193 1194 # FIXME: Would probably be better to checkout output of 1195 # drush status --fields=bootstrap --format=string 1196 1197 cd /talerdata/ 1198 if [[ ! -e /talerdata/sandcastle-drupal ]]; then 1199 composer create-project drupal/recommended-project:^10 sandcastle-drupal 1200 cd /talerdata/sandcastle-drupal 1201 composer require drush/drush 1202 # This can take a ridiculous amount of time! 1203 COMPOSER_PROCESS_TIMEOUT=0 composer exec -- drush site-install demo_umami --account-name=admin --account-pass=$DRUPAL_ADMIN_PW --account-mail=admin@localhost --db-url=pgsql://drupal:$DRUPAL_DB_PW@localhost/drupal --site-name=SandcastleUmami --yes 1204 fi 1205 1206 chown -R www-data:www-data /talerdata/sandcastle-drupal/ 1207 1208 ln -sf /opt/turnstile /talerdata/sandcastle-drupal/web/modules/taler_turnstile 1209 1210 snip=$(cat <<'EOF' 1211 $settings['reverse_proxy'] = TRUE; 1212 $settings['reverse_proxy_addresses'] = ['127.0.0.1', '10.0.0.0/8']; 1213 $settings['trusted_host_patterns'] = ['.*']; 1214 EOF 1215 ) 1216 1217 update_config_block /talerdata/sandcastle-drupal/web/sites/default/settings.php SANDCASTLE "$snip" 1218 1219 cd /talerdata/sandcastle-drupal 1220 composer exec -- drush upwd admin $DRUPAL_ADMIN_PW 1221 composer exec -- drush en taler_turnstile 1222 composer exec -- drush config:set taler_turnstile.settings access_token "$UMAMI_TOK" --yes 1223 composer exec -- drush config:set taler_turnstile.settings payment_backend_url "$PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/umami/" --yes 1224 composer exec -- drush config:set --input-format=yaml taler_turnstile.settings enabled_content_types '["article", "recipe"]' --yes 1225 1226 snip=$(cat <<'EOF' | sed "s/@CURRENCY@/$CURRENCY/" 1227 $storage = \Drupal::entityTypeManager()->getStorage('taler_turnstile_price_category'); 1228 $e = $storage->create(['id'=>"normal", 'label'=>'Normal', 'description' => "Normal Article Price", 'prices' => ['%none%' => ['@CURRENCY@' => '0.3']]]); 1229 try { 1230 $e->save(); 1231 } catch (Exception $ex) { 1232 echo $ex->getMessage(); 1233 echo "\n"; 1234 } 1235 EOF 1236 ) 1237 composer exec -- drush php:eval "$snip" 1238 1239 snip=$(cat <<'EOF' 1240 $prcat_storage = \Drupal::entityTypeManager()->getStorage('taler_turnstile_price_category'); 1241 $node_storage = \Drupal::entityTypeManager()->getStorage('node'); 1242 $prcat = $prcat_storage->load('normal'); 1243 $nodes = $node_storage->loadByProperties(['type'=> ['article', 'recipe']]); 1244 foreach ($nodes as $k => $node) { 1245 echo 'updating node ' . $k . "\n"; 1246 if (!$node->hasField('field_taler_turnstile_prcat')) { 1247 echo 'prcat missing' . "\n"; 1248 continue; 1249 } 1250 $node->set('field_taler_turnstile_prcat', $prcat); 1251 $node->save(); 1252 } 1253 EOF 1254 ) 1255 composer exec -- drush php:eval "$snip" 1256 1257 composer exec -- drush cr 1258 1259 cd / 1260 1261 # FIXME: Maybe do some taler-wallet-cli test? 1262 # FIXME: How do we report errors occurring during the setup script?