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