diff --git a/.github/jobs/baseinstall.sh b/.github/jobs/baseinstall.sh index 719f065608..dd6a209457 100755 --- a/.github/jobs/baseinstall.sh +++ b/.github/jobs/baseinstall.sh @@ -11,8 +11,6 @@ export APP_ENV="${4:-prod}" # In the test environment, we need to use a different database [ "$APP_ENV" = "prod" ] && DATABASE_NAME=domjudge || DATABASE_NAME=domjudge_test -MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:-root} - set -euxo pipefail if [ -z "$phpversion" ]; then @@ -34,9 +32,9 @@ yarnpkg install cd .. section_end -section_start "Set simple admin password" -echo "password" > ./etc/initial_admin_password.secret -echo "default login admin password password" > ~/.netrc +section_start "Set admin password" +echo "${ADMIN_PASSWORD}" > ./etc/initial_admin_password.secret +echo "default login admin password ${ADMIN_PASSWORD}" > ~/.netrc section_end section_start "Install domserver" @@ -74,34 +72,30 @@ EOF cat ~/.my.cnf # TODO: Remove after fixing https://github.com/DOMjudge/domjudge/issues/2848 -mysql_root "SET GLOBAL innodb_snapshot_isolation = OFF;" +mysql_log "SET GLOBAL innodb_snapshot_isolation = OFF;" + +echo "unused:sqlserver:$DATABASE_NAME:domjudge:"'domjudge_db-pw+% #$*")@(!/;,.ßéçü主機:3306' > /opt/domjudge/domserver/etc/dbpasswords.secret -mysql_root "CREATE DATABASE IF NOT EXISTS \`$DATABASE_NAME\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" -mysql_root "CREATE USER IF NOT EXISTS \`domjudge\`@'%' IDENTIFIED BY 'domjudge';" -mysql_root "GRANT SELECT, INSERT, UPDATE, DELETE ON \`$DATABASE_NAME\`.* TO 'domjudge'@'%';" -mysql_root "FLUSH PRIVILEGES;" +/opt/domjudge/domserver/bin/dj_setup_database create-db-users # Show some MySQL debugging -mysql_root "show databases" -mysql_root "SELECT CURRENT_USER();" -mysql_root "SELECT USER();" -mysql_root "SELECT user,host FROM mysql.user" -mysql_root "SET GLOBAL max_allowed_packet=1073741824" -mysql_root "SHOW GLOBAL STATUS LIKE 'Connection_errors_%'" -mysql_root "SHOW VARIABLES LIKE 'innodb_snapshot_isolation'" -mysql_root "SHOW VARIABLES LIKE '%_timeout'" -echo "unused:sqlserver:$DATABASE_NAME:domjudge:domjudge:3306" > /opt/domjudge/domserver/etc/dbpasswords.secret -mysql_user "SELECT CURRENT_USER();" -mysql_user "SELECT USER();" +mysql_log "show databases" +mysql_log "SELECT CURRENT_USER();" +mysql_log "SELECT USER();" +mysql_log "SELECT user,host FROM mysql.user" +mysql_log "SET GLOBAL max_allowed_packet=1073741824" +mysql_log "SHOW GLOBAL STATUS LIKE 'Connection_errors_%'" +mysql_log "SHOW VARIABLES LIKE '%_timeout'" section_end if [ "${db}" = "install" ]; then section_start "Install DOMjudge database" - /opt/domjudge/domserver/bin/dj_setup_database -uroot -p${MYSQL_ROOT_PASSWORD} bare-install + /opt/domjudge/domserver/bin/dj_setup_database bare-install section_end elif [ "${db}" = "upgrade" ]; then section_start "Upgrade DOMjudge database" - /opt/domjudge/domserver/bin/dj_setup_database -uroot -p${MYSQL_ROOT_PASSWORD} upgrade + /opt/domjudge/domserver/bin/dj_setup_database upgrade + /opt/domjudge/domserver/webapp/bin/console domjudge:reset-user-password admin "${ADMIN_PASSWORD}" section_end fi @@ -141,31 +135,31 @@ if [ "${db}" = "install" ]; then section_start "Install the example data" if [ "$version" = "unit" ]; then # Make sure admin has no team associated so we will not insert submissions during unit tests. - mysql_root "UPDATE user SET teamid=null WHERE userid=1;" $DATABASE_NAME + mysql_log "UPDATE user SET teamid=null WHERE userid=1;" $DATABASE_NAME fi - /opt/domjudge/domserver/bin/dj_setup_database -uroot -p${MYSQL_ROOT_PASSWORD} install-examples | tee -a "$ARTIFACTS/mysql.txt" + /opt/domjudge/domserver/bin/dj_setup_database install-examples | tee -a "$ARTIFACTS/mysql.txt" section_end fi section_start "Setup user" # We're using the admin user in all possible roles -mysql_root "DELETE FROM userrole WHERE userid=1;" $DATABASE_NAME +mysql_log "DELETE FROM userrole WHERE userid=1;" $DATABASE_NAME if [ "$version" = "team" ]; then # Add team to admin user - mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 3);" $DATABASE_NAME - mysql_root "UPDATE user SET teamid = 1 WHERE userid = 1;" $DATABASE_NAME + mysql_log "INSERT INTO userrole (userid, roleid) VALUES (1, 3);" $DATABASE_NAME + mysql_log "UPDATE user SET teamid = 1 WHERE userid = 1;" $DATABASE_NAME elif [ "$version" = "jury" ]; then # Add jury to admin user - mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 2);" $DATABASE_NAME + mysql_log "INSERT INTO userrole (userid, roleid) VALUES (1, 2);" $DATABASE_NAME elif [ "$version" = "balloon" ]; then # Add balloon to admin user - mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 4);" $DATABASE_NAME + mysql_log "INSERT INTO userrole (userid, roleid) VALUES (1, 4);" $DATABASE_NAME elif [ "$version" = "admin" ]; then # Add admin to admin user - mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 1);" $DATABASE_NAME + mysql_log "INSERT INTO userrole (userid, roleid) VALUES (1, 1);" $DATABASE_NAME elif [ "$version" = "all" ] || [ "$version" = "unit" ]; then - mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 1);" $DATABASE_NAME - mysql_root "INSERT INTO userrole (userid, roleid) VALUES (1, 3);" $DATABASE_NAME - mysql_root "UPDATE user SET teamid = 1 WHERE userid = 1;" $DATABASE_NAME + mysql_log "INSERT INTO userrole (userid, roleid) VALUES (1, 1);" $DATABASE_NAME + mysql_log "INSERT INTO userrole (userid, roleid) VALUES (1, 3);" $DATABASE_NAME + mysql_log "UPDATE user SET teamid = 1 WHERE userid = 1;" $DATABASE_NAME fi section_end diff --git a/.github/jobs/ci_settings.sh b/.github/jobs/ci_settings.sh old mode 100644 new mode 100755 index 391996752b..b807178e67 --- a/.github/jobs/ci_settings.sh +++ b/.github/jobs/ci_settings.sh @@ -24,14 +24,9 @@ section_end_internal () { trace_on } -mysql_root () { +mysql_log () { # shellcheck disable=SC2086 - echo "$1" | mysql -uroot -proot ${2:-} | tee -a "$ARTIFACTS"/mysql.txt -} - -mysql_user () { - # shellcheck disable=SC2086 - echo "$1" | mysql -udomjudge -pdomjudge ${2:-} | tee -a "$ARTIFACTS"/mysql.txt + echo "$1" | mysql ${2:-} | tee -a "$ARTIFACTS"/mysql.txt } show_phpinfo() { diff --git a/.github/jobs/unit-tests.sh b/.github/jobs/unit-tests.sh index 3357a7868b..8a9f821cc2 100755 --- a/.github/jobs/unit-tests.sh +++ b/.github/jobs/unit-tests.sh @@ -14,7 +14,7 @@ unittest=$2 export unit=1 # Add team to admin user -echo "UPDATE user SET teamid = 1 WHERE userid = 1;" | mysql domjudge_test +mysql_log "UPDATE user SET teamid = 1 WHERE userid = 1;" domjudge_test # Copy the .env.test file, as this is normally not done during # installation and we need it. @@ -25,6 +25,9 @@ cp webapp/composer.json /opt/domjudge/domserver/webapp/ cd /opt/domjudge/domserver +# The tests add a '_test' suffix to the database name already. +sed -i "s!:domjudge_test:!:domjudge:!" /opt/domjudge/domserver/etc/dbpasswords.secret + # Run phpunit tests. pcov="" phpcov="" @@ -33,7 +36,6 @@ if [ "$CODECOVERAGE" -eq 1 ]; then pcov="--coverage-html=${DIR}/coverage-html --coverage-clover coverage.xml" fi set +e -echo "unused:sqlserver:domjudge:domjudge:domjudge:3306" > /opt/domjudge/domserver/etc/dbpasswords.secret php $phpcov webapp/bin/phpunit -c webapp/phpunit.xml.dist webapp/tests/$unittest --log-junit ${ARTIFACTS}/unit-tests.xml --colors=never $pcov | tee "$ARTIFACTS"/phpunit.out UNITSUCCESS=$? diff --git a/.github/jobs/webstandard.sh b/.github/jobs/webstandard.sh index a48fd70f77..4a5331398c 100755 --- a/.github/jobs/webstandard.sh +++ b/.github/jobs/webstandard.sh @@ -20,19 +20,18 @@ section_start "Setup pa11y" section_end section_start "Setup the test user" -ADMINPASS=$(cat etc/initial_admin_password.secret) export COOKIEJAR COOKIEJAR=$(mktemp --tmpdir) export CURLOPTS="--fail -sq -m 30 -b $COOKIEJAR" if [ "$ROLE" = "public" ]; then - ADMINPASS="failedlogin" + ADMIN_PASSWORD="failedlogin" fi # Make an initial request which will get us a session id, and grab the csrf token from it CSRFTOKEN=$(curl $CURLOPTS -c $COOKIEJAR "http://localhost/domjudge/login" 2>/dev/null | sed -n 's/.*_csrf_token.*value="\(.*\)".*/\1/p') # Make a second request with our session + csrf token to actually log in # shellcheck disable=SC2086 -curl $CURLOPTS -c "$COOKIEJAR" -F "_csrf_token=$CSRFTOKEN" -F "_username=admin" -F "_password=$ADMINPASS" "http://localhost/domjudge/login" +curl $CURLOPTS -c "$COOKIEJAR" -F "_csrf_token=$CSRFTOKEN" -F "_username=admin" -F "_password=$ADMIN_PASSWORD" "http://localhost/domjudge/login" # Move back to the default directory cd "$DIR" diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml deleted file mode 100644 index 0dbddf8f72..0000000000 --- a/.github/workflows/codestyle.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: Codestandard -on: - merge_group: - pull_request: - branches: - - main - - '[0-9]+.[0-9]+' - -jobs: - syntax-job: - runs-on: ubuntu-latest - container: - image: domjudge/gitlabci:24.04 - steps: - - uses: actions/checkout@v4 - - name: Run the syntax checks - run: .github/jobs/syntax.sh - - detect-dump: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: "Search for leftover dump( statements" - run: .github/jobs/detect_dump.sh - - php-linter: - runs-on: ubuntu-latest - container: - image: pipelinecomponents/php-linter:latest - steps: - - uses: actions/checkout@v4 - - name: Detect PHP linting issues - run: > - parallel-lint --colors - lib/lib.*.php - etc - judge - webapp/src - webapp/tests - webapp/public - webapp/config - - phpcs_compatibility: - runs-on: ubuntu-latest - container: - image: pipelinecomponents/php-codesniffer:latest - strategy: - matrix: - PHPVERSION: ["8.1", "8.2", "8.3", "8.4"] - steps: - - run: apk add git - - uses: actions/checkout@v4 - - name: Various fixes to this image - run: .github/jobs/fix_pipelinecomponents_image.sh - - name: Detect compatibility with supported PHP version - run: > - phpcs -s -p --colors - --standard=PHPCompatibility - --extensions=php - --runtime-set testVersion ${{ matrix.PHPVERSION }} - lib/lib.*.php - etc - judge - webapp/src - webapp/tests - webapp/public - webapp/config - - pycodestyle: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Download pycodestyle python file - run: > - curl -L -o /tmp/pycodestyle.py 'https://github.com/PyCQA/pycodestyle/raw/refs/tags/2.12.1/pycodestyle.py' - - name: Check codestyle in python files - run: > - python3 /tmp/pycodestyle.py \ - --exclude='./example_problems/,./doc/,./gitlab/,./webapp/vendor/' \ - --max-line-length 120 \ - --show-pep8 --show-source \ - . - - pyright: - runs-on: ubuntu-latest - steps: - - uses: jakebailey/pyright-action@v2 - with: - version: 1.1.311 diff --git a/.github/workflows/database-upgrade.yml b/.github/workflows/database-upgrade.yml index 251844a882..57833acf39 100644 --- a/.github/workflows/database-upgrade.yml +++ b/.github/workflows/database-upgrade.yml @@ -9,6 +9,9 @@ on: jobs: upgrade_test: runs-on: ubuntu-latest + env: + ADMIN_PASSWORD: admin_password + MYSQL_ROOT_PASSWORD: mysql_root_password container: image: domjudge/gitlabci:24.04 services: @@ -17,9 +20,7 @@ jobs: ports: - 3306:3306 env: - MYSQL_ROOT_PASSWORD: root - MYSQL_USER: domjudge - MYSQL_PASSWORD: domjudge + MYSQL_ROOT_PASSWORD: ${{ env.MYSQL_ROOT_PASSWORD }} options: --health-cmd="healthcheck.sh --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - uses: actions/checkout@v4 @@ -38,18 +39,16 @@ jobs: restore-keys: | composer- - name: Import Database - run: mysql -hsqlserver -uroot -proot < .github/jobs/data/dj733.sql + run: mysql -hsqlserver -uroot -p${{ env.MYSQL_ROOT_PASSWORD }} < .github/jobs/data/dj733.sql - name: Upgrade DOMjudge run: .github/jobs/baseinstall.sh default upgrade - - name: Setting initial Admin Password - run: echo "pass" > /opt/domjudge/domserver/etc/initial_admin_password.secret - name: Check for Errors in the Upgrade - run: mysql -hsqlserver -uroot -proot -e "SHOW TABLES FROM domjudge;" + run: mysql -hsqlserver -uroot -p${{ env.MYSQL_ROOT_PASSWORD }} -e "SHOW TABLES FROM domjudge;" - name: Check for Errors in DOMjudge Webinterface run: .github/jobs/webstandard.sh none admin - name: dump the db if: ${{ !cancelled() }} - run: mysqldump -uroot -proot --quick --max_allowed_packet=1024M domjudge > /tmp/db.sql + run: mysqldump -hsqlserver -uroot -p${{ env.MYSQL_ROOT_PASSWORD }} --quick --max_allowed_packet=1024M domjudge > /tmp/db.sql - name: Upload database dump for debugging if: ${{ !cancelled() }} uses: actions/upload-artifact@v4 diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 0fdadf5350..ec5fc282d6 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -9,6 +9,9 @@ on: jobs: integration: runs-on: ubuntu-24.04 + env: + ADMIN_PASSWORD: admin_password + MYSQL_ROOT_PASSWORD: mysql_root_password timeout-minutes: 30 container: image: domjudge/gitlabci:24.04 @@ -19,9 +22,7 @@ jobs: ports: - 3306:3306 env: - MYSQL_ROOT_PASSWORD: root - MYSQL_USER: domjudge - MYSQL_PASSWORD: domjudge + MYSQL_ROOT_PASSWORD: ${{ env.MYSQL_ROOT_PASSWORD }} options: --health-cmd="healthcheck.sh --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=3 steps: - uses: actions/checkout@v4 @@ -57,11 +58,10 @@ jobs: - name: Check nginx run: curl -v https://localhost/domjudge/ - name: Configure print command - working-directory: submit run: | - curl --fail -u 'admin:password' -X 'GET' 'http://localhost/domjudge/api/v4/config?strict=false' \ + curl --fail -u "admin:${ADMIN_PASSWORD}" -X 'GET' 'http://localhost/domjudge/api/v4/config?strict=false' \ | jq '.print_command |= "cp [file] /tmp/dj-printfile"' \ - | curl --fail -u 'admin:password' -X 'PUT' -T - 'http://localhost/domjudge/api/v4/config?strict=false' \ + | curl --fail -u "admin:${ADMIN_PASSWORD}" -X 'PUT' -T - 'http://localhost/domjudge/api/v4/config?strict=false' \ - name: Testing submit client working-directory: submit run: make check-full @@ -95,7 +95,7 @@ jobs: done - name: dump the db if: ${{ !cancelled() }} - run: mysqldump -uroot -proot --quick --max_allowed_packet=1024M domjudge > /tmp/db.sql + run: mysqldump --quick --max_allowed_packet=1024M domjudge > /tmp/db.sql - name: Upload database dump for debugging if: ${{ !cancelled() }} uses: actions/upload-artifact@v4 @@ -127,7 +127,7 @@ jobs: # Make an initial request which will get us a session id, and grab the csrf token from it CSRFTOKEN=$(curl $CURLOPTS -c /tmp/cookiejar "http://localhost/domjudge/login" | sed -n 's/.*_csrf_token.*value="\(.*\)".*/\1/p') # Make a second request with our session + csrf token to actually log in - curl $CURLOPTS -c /tmp/cookiejar -F "_csrf_token=$CSRFTOKEN" -F "_username=admin" -F "_password=password" "http://localhost/domjudge/login" + curl $CURLOPTS -c /tmp/cookiejar -F "_csrf_token=$CSRFTOKEN" -F "_username=admin" -F "_password=${ADMIN_PASSWORD}" "http://localhost/domjudge/login" # Send a general clarification to later test if we see the event. curl $CURLOPTS -F "sendto=" -F "problem=1-" -F "bodytext=Testing" -F "submit=Send" \ "http://localhost/domjudge/jury/clarifications/send" -o /dev/null @@ -172,4 +172,4 @@ jobs: export CCS_SPECS_PINNED_SHA1='a68aff54c4e60fc2bff2fc5c36c119bffa4d30f1' ( cd ccs-specs && git reset --hard $CCS_SPECS_PINNED_SHA1 ) export CHECK_API="${HOME}/ccs-specs/check-api.sh -j ${HOME}/yajsv" - $CHECK_API -n -C -e -a 'strict=1' http://admin:password@localhost/domjudge/api + $CHECK_API -n -C -e -a 'strict=1' "http://admin:${ADMIN_PASSWORD}@localhost/domjudge/api" diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index d6d53f8712..c966aaadf8 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -28,6 +28,9 @@ jobs: permissions: checks: write runs-on: ubuntu-24.04 + env: + ADMIN_PASSWORD: admin_password + MYSQL_ROOT_PASSWORD: mysql_root_password timeout-minutes: 30 container: image: domjudge/gitlabci:24.04 @@ -37,9 +40,7 @@ jobs: ports: - 3306:3306 env: - MYSQL_ROOT_PASSWORD: root - MYSQL_USER: domjudge - MYSQL_PASSWORD: domjudge + MYSQL_ROOT_PASSWORD: ${{ env.MYSQL_ROOT_PASSWORD }} options: --health-cmd="healthcheck.sh --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=3 strategy: matrix: diff --git a/.github/workflows/webstandard.yml b/.github/workflows/webstandard.yml index 165a70596b..ab1343f2c0 100644 --- a/.github/workflows/webstandard.yml +++ b/.github/workflows/webstandard.yml @@ -9,6 +9,9 @@ on: jobs: standards: runs-on: ubuntu-latest + env: + ADMIN_PASSWORD: admin_password + MYSQL_ROOT_PASSWORD: mysql_root_password container: image: domjudge/gitlabci:24.04 services: @@ -17,9 +20,7 @@ jobs: ports: - 3306:3306 env: - MYSQL_ROOT_PASSWORD: root - MYSQL_USER: domjudge - MYSQL_PASSWORD: domjudge + MYSQL_ROOT_PASSWORD: ${{ env.MYSQL_ROOT_PASSWORD }} options: --health-cmd="healthcheck.sh --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=3 strategy: matrix: diff --git a/sql/dj_setup_database.in b/sql/dj_setup_database.in index fc803939c3..691b193261 100755 --- a/sql/dj_setup_database.in +++ b/sql/dj_setup_database.in @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # @configure_input@ # This script allows one to perform DOMjudge database setup actions. @@ -52,30 +52,48 @@ not have to pass any of the options above. EOF } +urlencode() +{ + # Redirect via stdin to prevent ugly escaping hacks. + echo -n "$1" | php -r "echo rawurlencode(file_get_contents('php://stdin'));" +} + +# This is global variable to be able to return the output from +# mysql_options() below as an array, which is not possible otherwise. +declare -a _mysql_options + mysql_options() { + local user pass + _mysql_options=() + # shellcheck disable=SC2153 if [ -n "$DBUSER" ]; then - _user="-u $DBUSER" - else - _user="${DBA_USER:+-u ${DBA_USER}}" + _mysql_options+=('-u' "$DBUSER") + elif [ -n "$DBA_USER" ]; then + _mysql_options+=('-u' "$DBA_USER") fi # shellcheck disable=SC2153 if [ -n "$PASSWD" ]; then - _pass="-p$PASSWD" - else - [ -n "$PROMPT_PASSWD" ] && _pass="-p" - [ -n "$DBA_PASSWD" ] && _pass="-p$DBA_PASSWD" + _mysql_options+=("-p$PASSWD") + elif [ -n "$DBA_PASSWD" ]; then + _mysql_options+=("-p$DBA_PASSWD") + elif [ -n "$PROMPT_PASSWD" ]; then + _mysql_options+=('-p') fi - [ -z "$USE_SOCKET" ] && port="-P$DBPORT" - echo $_user ${_pass:+"$_pass"} -h "$DBHOST" ${port:+"$port"} + _mysql_options+=('-h' "$DBHOST") + + if [ -z "$USE_SOCKET" ]; then + _mysql_options+=("-P$DBPORT") + fi } # Wrapper around mysql command to allow setting options, user, etc. mysql() { - command mysql $(mysql_options) --silent --skip-column-names "$@" + mysql_options + command mysql "${_mysql_options[@]}" --silent --skip-column-names "$@" } # Quick shell hack to get a key from an INI file. @@ -126,12 +144,17 @@ symfony_console() fi if [ -n "$DBA_USER" ]; then + user=$(urlencode "${DBA_USER}") + host=$(urlencode "${domjudge_DBHOST}") + db=$(urlencode "${domjudge_DBNAME}") if [ -n "$DBA_PASSWD" ]; then - DATABASE_URL=mysql://${DBA_USER}:${DBA_PASSWD}@${domjudge_DBHOST}:${domjudge_DBPORT}/${domjudge_DBNAME} + DATABASE_URL="mysql://$user:$(urlencode "${DBA_PASSWD}")@$host:${domjudge_DBPORT}/$db" else - DATABASE_URL=mysql://${DBA_USER}@${domjudge_DBHOST}:${domjudge_DBPORT}/${domjudge_DBNAME} + DATABASE_URL="mysql://$user@$host:${domjudge_DBPORT}/$db" fi fi + else + DATABASE_URL="mysql://$DBUSER:$(urlencode "${PASSWD}")@$host:${domjudge_DBPORT}/$db" fi if [ -n "$DATABASE_URL" ]; then @@ -216,8 +239,8 @@ create_db_users() # in etc/domserver-config.php updated after installation. echo "CREATE DATABASE IF NOT EXISTS \`$DBNAME\` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" - echo "CREATE USER IF NOT EXISTS '$domjudge_DBUSER'@'localhost' IDENTIFIED BY '$domjudge_PASSWD';" - echo "GRANT SELECT, INSERT, UPDATE, DELETE ON \`$DBNAME\`.* TO '$domjudge_DBUSER'@'localhost';" + echo "CREATE USER IF NOT EXISTS '$domjudge_DBUSER'@'%' IDENTIFIED BY '$domjudge_PASSWD';" + echo "GRANT SELECT, INSERT, UPDATE, DELETE ON \`$DBNAME\`.* TO '$domjudge_DBUSER'@'%';" echo "FLUSH PRIVILEGES;" ) | mysql @@ -228,7 +251,7 @@ remove_db_users() { ( echo "DROP DATABASE IF EXISTS \`$DBNAME\`;" - echo "DROP USER IF EXISTS '$domjudge_DBUSER'@'localhost';" + echo "DROP USER IF EXISTS '$domjudge_DBUSER'@'%';" echo "FLUSH PRIVILEGES;" ) | mysql -f verbose "DOMjudge database and user(s) removed." @@ -236,18 +259,17 @@ remove_db_users() update_password() { - read_dbpasswords ( - echo "ALTER USER '$domjudge_DBUSER'@'localhost' IDENTIFIED BY '$domjudge_PASSWD';" + echo "ALTER USER '$domjudge_DBUSER'@'%' IDENTIFIED BY '$domjudge_PASSWD';" echo "FLUSH PRIVILEGES;" ) | mysql - verbose "ALTER USER '$domjudge_DBUSER'@'localhost' IDENTIFIED BY '$domjudge_PASSWD';" + verbose "ALTER USER '$domjudge_DBUSER'@'%' IDENTIFIED BY '$domjudge_PASSWD';" verbose "Database user password updated from credentials file." } install_examples() { - DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-example-data + symfony_console domjudge:load-example-data "$EXAMPLEPROBDIR"/generate-contest-yaml ( cd "$EXAMPLEPROBDIR" && yes y | "$BINDIR"/import-contest ) } @@ -321,8 +343,8 @@ install-loadtest) read_dbpasswords create_db_users symfony_console doctrine:migrations:migrate -n - DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-default-data - DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-gatling-data + symfony_console domjudge:load-default-data + symfony_console domjudge:load-gatling-data ;; create-db-users) @@ -331,6 +353,7 @@ create-db-users) ;; update-password) + read_dbpasswords update_password ;; @@ -338,7 +361,7 @@ bare-install|install) read_dbpasswords create_db_users symfony_console doctrine:migrations:migrate -n - DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-default-data + symfony_console domjudge:load-default-data if [ "$1" = "install" ]; then install_examples verbose "SQL structure and default/example data installed." @@ -356,15 +379,14 @@ upgrade) # shellcheck disable=SC2016,SC2028 echo 'INSERT INTO `doctrine_migration_versions` (version, executed_at, execution_time) - SELECT concat("DoctrineMigrations\\\\Version", version), executed_at, 1 + SELECT concat("DoctrineMigrations\\Version", version), executed_at, 1 FROM migration_versions;' | mysql "$DBNAME" echo "DROP TABLE \`migration_versions\`" | mysql "$DBNAME" fi symfony_console doctrine:migrations:migrate -n - DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-default-data - symfony_console domjudge:refresh-cache + symfony_console domjudge:load-default-data verbose "DOMjudge database upgrade completed." ;; diff --git a/webapp/config/load_db_secrets.php b/webapp/config/load_db_secrets.php index ea4ca11b83..c3a8b3dfb5 100644 --- a/webapp/config/load_db_secrets.php +++ b/webapp/config/load_db_secrets.php @@ -36,7 +36,11 @@ function get_db_url(): string break; } - return sprintf('mysql://%s:%s@%s:%d/%s?serverVersion=5.7.0', $user, $pass, $host, $port ?? 3306, $db); + return sprintf( + 'mysql://%s:%s@%s:%d/%s?serverVersion=5.7.0', + rawurlencode($user), rawurlencode($pass), rawurlencode($host), + $port ?? 3306, rawurlencode($db) + ); } function get_app_secret(): string diff --git a/webapp/config/packages/doctrine.yaml b/webapp/config/packages/doctrine.yaml index 89bf0223b3..b919a7bd43 100644 --- a/webapp/config/packages/doctrine.yaml +++ b/webapp/config/packages/doctrine.yaml @@ -7,7 +7,7 @@ doctrine: charset: utf8mb4 collate: utf8mb4_unicode_ci - url: '%env(resolve:DATABASE_URL)%' + url: '%env(DATABASE_URL)%' profiling_collect_backtrace: '%kernel.debug%' types: tinyint: App\Doctrine\DBAL\Types\TinyIntType