Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/jobs/baseinstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ mysql_root "show databases"
mysql_root "SELECT CURRENT_USER();"
mysql_root "SELECT USER();"
mysql_root "SELECT user,host FROM mysql.user"
echo "unused:sqlserver:domjudge:domjudge:domjudge:3306" > /opt/domjudge/domserver/etc/dbpasswords.secret
#echo "unused:sqlserver:domjudge:domjudge:domjudge:3306" > /opt/domjudge/domserver/etc/dbpasswords.secret
echo 'unused:sqlserver:domjudge:domjudge:simplepw:3306' > /opt/domjudge/domserver/etc/dbpasswords.secret
mysql_user "SELECT CURRENT_USER();"
mysql_user "SELECT USER();"
section_end
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ inplace-install-l:
ln -sf $(CURDIR)/judge/runpipe $(judgehost_bindir)
ln -sf $(CURDIR)/judge/create_cgroups $(judgehost_bindir)
ln -sf $(CURDIR)/sql/dj_setup_database $(domserver_bindir)
ln -sf $(CURDIR)/webapp/bin/console $(domserver_bindir)/dj_console
# Create tmpdir and make tmpdir writable for webserver,
# because judgehost-create-dirs sets wrong permissions:
$(MKDIR_P) $(domserver_tmpdir)
Expand Down
8 changes: 5 additions & 3 deletions misc-tools/force-passwords.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import subprocess

webappdir = '@domserver_webappdir@'
bindir = '@domserver_bindir@'
etcdir = '@domserver_etcdir@'

subprocess.run([bindir + '/dj_setup_database', 'update-password'])

with open(f'{etcdir}/restapi.secret', 'r') as f:
while True:
line = f.readline()
Expand All @@ -14,9 +16,9 @@ with open(f'{etcdir}/restapi.secret', 'r') as f:
if len(tokens) == 4 and tokens[0] == 'default':
user = tokens[2]
password = tokens[3]
subprocess.run([webappdir + '/bin/console', 'domjudge:reset-user-password', user, password])
subprocess.run([bindir + '/dj_console', 'domjudge:reset-user-password', user, password])
break

with open(f'{etcdir}/initial_admin_password.secret', 'r') as f:
password = f.readline().strip()
subprocess.run([webappdir + '/bin/console', 'domjudge:reset-user-password', 'admin', password])
subprocess.run([bindir + '/dj_console', 'domjudge:reset-user-password', 'admin', password])
103 changes: 58 additions & 45 deletions sql/dj_setup_database.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# @configure_input@

# This script allows one to perform DOMjudge database setup actions.
Expand Down Expand Up @@ -29,6 +29,7 @@ Commands:
status check database installation status
genpass generate DB,API,Symfony,admin password files
create-db-users create (empty) database and users
update-password update DB user database to that in 'etc/dbpasswords.secret'
install create database, example contest and users if not existing
bare-install create database, setup defaults if not existing
uninstall remove database users and database, INCLUDING ALL DATA!
Expand All @@ -51,30 +52,47 @@ not have to pass any of the options above.
EOF
}

urlencode()
{
php -r "echo rawurlencode('$1');"
}

# 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.
Expand Down Expand Up @@ -125,10 +143,13 @@ 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
fi
Expand Down Expand Up @@ -233,28 +254,22 @@ remove_db_users()
verbose "DOMjudge database and user(s) removed."
}

install_examples()
{
DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-example-data
"$EXAMPLEPROBDIR"/generate-contest-yaml
( cd "$EXAMPLEPROBDIR" && yes y | "$BINDIR"/import-contest )
}

uninstall_helper()
update_password()
{
read_dbpasswords
remove_db_users
(
echo "ALTER USER '$domjudge_DBUSER'@'localhost' IDENTIFIED BY '$domjudge_PASSWD';"
echo "FLUSH PRIVILEGES;"
) | mysql
verbose "ALTER USER '$domjudge_DBUSER'@'localhost' IDENTIFIED BY '$domjudge_PASSWD';"
verbose "Database user password updated from credentials file."
}

create_db_users_helper()
install_examples()
{
read_dbpasswords
create_db_users
verbose "Created empty database and users."
}

create_database_dump () {
mysqldump $(mysql_options) --opt --skip-lock-tables "$DBNAME" | pv | gzip > "$DATABASEDUMPDIR/${1}.sql.gz"
DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-example-data
"$EXAMPLEPROBDIR"/generate-contest-yaml
( cd "$EXAMPLEPROBDIR" && yes y | "$BINDIR"/import-contest )
}

### Script starts here ###
Expand Down Expand Up @@ -313,7 +328,8 @@ genpass)
;;

uninstall)
uninstall_helper
read_dbpasswords
remove_db_users
;;

install-examples)
Expand All @@ -324,23 +340,24 @@ install-examples)
install-loadtest)
read_dbpasswords
create_db_users
export DB_FIRST_INSTALL=1
symfony_console doctrine:migrations:migrate -n
unset DB_FIRST_INSTALL
DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-default-data
DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-gatling-data
;;

create-db-users)
create_db_users_helper
read_dbpasswords
create_db_users
;;

update-password)
update_password
;;

bare-install|install)
read_dbpasswords
create_db_users
export DB_FIRST_INSTALL=1
symfony_console doctrine:migrations:migrate -n
unset DB_FIRST_INSTALL
DBUSER=$domjudge_DBUSER PASSWD=$domjudge_PASSWD symfony_console domjudge:load-default-data
if [ "$1" = "install" ]; then
install_examples
Expand All @@ -351,11 +368,6 @@ bare-install|install)
;;

upgrade)
# check for legacy dbpasswords.secret content
if grep -Eq ^team: $PASSWDFILE >/dev/null 2>&1 ; then
echo "Warning: please remove all non-jury users from $PASSWDFILE"
echo "You may also remove those users from MySQL."
fi
read_dbpasswords

# Check if we need to upgrade the Doctrine migrations table
Expand All @@ -382,7 +394,8 @@ dump)
exit 1
fi

if [ -f "${DATABASEDUMPDIR}/${DUMPNAME}.sql.gz" ]; then
DUMPFILE="${DATABASEDUMPDIR}/${DUMPNAME}.sql.gz"
if [ -f "$DUMPFILE" ]; then
while true; do
printf "Overwrite existing database dump (y/N)? "
read -r yn
Expand All @@ -392,7 +405,7 @@ dump)
esac
done
fi
create_database_dump "$DUMPNAME"
mysqldump $(mysql_options) --opt --skip-lock-tables "$DBNAME" | pv | gzip > "$DUMPFILE"
;;

load)
Expand Down Expand Up @@ -434,8 +447,8 @@ load)
fi

read_dbpasswords
uninstall_helper
create_db_users_helper
remove_db_users
create_db_users
pv "${FILE}" | gunzip | mysql "$DBNAME"
;;

Expand Down
2 changes: 2 additions & 0 deletions webapp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ install-domserver:
for d in bin config migrations public resources src templates tests vendor; do \
$(call install_tree,$(DESTDIR)$(domserver_webappdir),$$d) ; \
done
# Add Symlink to Symfony console that is in the standard path
ln -s $(domserver_webappdir)/bin/console $(DESTDIR)$(domserver_bindir)/dj_console
# Change webapp/public/doc symlink
ln -sf $(domjudge_docdir) $(DESTDIR)$(domserver_webappdir)/public/doc
$(INSTALL_DATA) -t $(DESTDIR)$(domserver_webappdir) phpunit.xml.dist .env
Expand Down
6 changes: 5 additions & 1 deletion webapp/config/load_db_secrets.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php declare(strict_types=1);

Check warning on line 1 in webapp/config/load_db_secrets.php

View workflow job for this annotation

GitHub Actions / phpcs

A file should declare new symbols (classes, functions, constants, etc.) and cause no other side effects, or it should execute logic with side effects, but should not do both. The first symbol is defined on line 11 and the first side effect is on line 9.

// This file fetches credentials on the fly from files in etc.
// These settings can later be overridden by Symfony files
Expand Down Expand Up @@ -36,7 +36,11 @@
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
Expand Down
2 changes: 1 addition & 1 deletion webapp/config/packages/doctrine.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading