From 4c6f66e82553f0f3eacd6cac259a6001ce27a301 Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Fri, 10 Dec 2021 21:41:47 +0000 Subject: [PATCH 01/10] Clear ops/whitelist json before processing if override set --- scripts/start-finalExec | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/start-finalExec b/scripts/start-finalExec index 78603ebcb76..608cbc15c69 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -3,16 +3,20 @@ . ${SCRIPTS:-/}start-utils isDebugging && set -x +if isTrue "${OVERRIDE_OPS}"; then + log "Recreating ops.json file at server startup" + rm -f /data/ops.json +fi if [ -n "$OPS" ]; then log "Updating ops" rm -f /data/ops.txt.converted echo $OPS | awk -v RS=, '{print}' > /data/ops.txt fi -if isTrue "${OVERRIDE_OPS}"; then - log "Recreating ops.json file at server startup" - rm -f /data/ops.json -fi +if isTrue "${OVERRIDE_WHITELIST}"; then + log "Recreating whitelist.json file at server startup" + rm -f /data/whitelist.json +fi if [ -n "$WHITELIST" ]; then log "Updating whitelist" rm -f /data/white-list.txt.converted @@ -22,10 +26,6 @@ if [ -n "$WHITELIST" ]; then echo $WHITELIST | awk -v RS=, '{print}' > /data/white-list.txt fi fi -if isTrue "${OVERRIDE_WHITELIST}"; then - log "Recreating whitelist.json file at server startup" - rm -f /data/whitelist.json -fi if [ -n "$ICON" ]; then if [ ! -e server-icon.png ] || [ "${OVERRIDE_ICON}" == "TRUE" ]; then From e3d92cf34d43c02b12b3569d9443ac8e4ba0666e Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Fri, 10 Dec 2021 21:58:04 +0000 Subject: [PATCH 02/10] Implement support for ops/whitelist json This commit adds support for providing the JSON file used for ops and whitelist definitions. This is provided via the OPS_JSON and WHITELIST_JSON environment variables, and similar to OPS and WHITELIST they are copied on first run and only override the existing files if OVERRIDE_OPS and OVERRIDE_WHITELIST are set to true. If both forms of definition are provided, the JSON is processed first, with additional processing occuring with the user/uuid CSV variables. This ensures consistent behaviour with hiw options are currently used, and allows for override configuration to be provided at runtime or definition (for example a default whitelist/ops configuration, with additionals added for an event) --- scripts/start-finalExec | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/scripts/start-finalExec b/scripts/start-finalExec index 608cbc15c69..1f0b2eeeb5a 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -7,6 +7,25 @@ if isTrue "${OVERRIDE_OPS}"; then log "Recreating ops.json file at server startup" rm -f /data/ops.json fi +if [ -n "$OPS_JSON" ] && [ ! -e "/data/ops.json" ]; then + if isURL "${OPS_JSON}"; then + log "Downloading ops.json from ${OPS_JSON}" + if ! get -o /data/ops.json "${OPS_JSON}"; then + log "ERROR: failed to download from ${OPS_JSON}" + exit 2 + fi + else + log "Copying ops.json from ${OPS_JSON}" + if ! cp "${OPS_JSON}" /data/ops.json; then + log "ERROR: failed to copy from ${OPS_JSON}" + exit 1 + fi + fi + if ! cat /data/ops.json | jq empty; then + log "ERROR: ${OPS_JSON} is not valid JSON!" + exit 1 + fi +fi if [ -n "$OPS" ]; then log "Updating ops" rm -f /data/ops.txt.converted @@ -17,6 +36,25 @@ if isTrue "${OVERRIDE_WHITELIST}"; then log "Recreating whitelist.json file at server startup" rm -f /data/whitelist.json fi +if [ -n "$WHITELIST_JSON" ] && [ ! -e "/data/whitelist.json" ]; then + if isURL "${WHITELIST_JSON}"; then + log "Downloading whitelist.json from ${WHITELIST_JSON}" + if ! get -o /data/whitelist.json "${WHITELIST_JSON}"; then + log "ERROR: failed to download from ${WHITELIST_JSON}" + exit 2 + fi + else + log "Copying whitelist.json from ${WHITELIST_JSON}" + if ! cp "${WHITELIST_JSON}" /data/whitelist.json; then + log "ERROR: failed to copy from ${WHITELIST_JSON}" + exit 1 + fi + fi + if ! cat /data/whitelist.json | jq empty; then + log "ERROR: ${WHITELIST_JSON} is not valid JSON!" + exit 1 + fi +fi if [ -n "$WHITELIST" ]; then log "Updating whitelist" rm -f /data/white-list.txt.converted From 204482e5ec4f0220fa97674f6d98e2b460f3bdab Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Fri, 10 Dec 2021 23:51:22 +0000 Subject: [PATCH 03/10] Handle pre-json whitelist/ops configuration better Minecraft 1.7.6 added support for UUIDs via the JSON configuration file format for whitelist and ops. To handle 1.7.5 and earlier, we perform slightly different logic. If Minecraft 1.7.5 or earlier: - Delete the correct files for OVERRIDE_OPS/OVERRIDE_WHITELIST - Update ops.txt and white-list.txt with users provided via variables - Error on use of JSON environtment variables As part of this change, a fix to handle existing configuration for both JSON and text-based configurations was added. If existing files are found, we uniquely merge with them. --- scripts/start-finalExec | 54 +++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/scripts/start-finalExec b/scripts/start-finalExec index 1f0b2eeeb5a..01fec466f43 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -4,10 +4,19 @@ isDebugging && set -x if isTrue "${OVERRIDE_OPS}"; then - log "Recreating ops.json file at server startup" - rm -f /data/ops.json + if versionLessThan 1.7.6; then + log "Recreating ops.txt file at server startup" + rm -f /data/ops.txt + else + log "Recreating ops.json file at server startup" + rm -f /data/ops.json + fi fi if [ -n "$OPS_JSON" ] && [ ! -e "/data/ops.json" ]; then + if versionLessThan 1.7.6; then + log "ERROR: OPS_JSON not supported on 1.7.5 and below!" + exit 1 + fi if isURL "${OPS_JSON}"; then log "Downloading ops.json from ${OPS_JSON}" if ! get -o /data/ops.json "${OPS_JSON}"; then @@ -28,15 +37,29 @@ if [ -n "$OPS_JSON" ] && [ ! -e "/data/ops.json" ]; then fi if [ -n "$OPS" ]; then log "Updating ops" - rm -f /data/ops.txt.converted - echo $OPS | awk -v RS=, '{print}' > /data/ops.txt + if versionLessThan 1.7.6; then + echo $OPS | awk -v RS=, '{print}' >> /data/ops.txt + sort -u ops.txt -o ops.txt + else + rm -f /data/ops.txt.converted + echo $OPS | awk -v RS=, '{print}' > /data/ops.txt + fi fi if isTrue "${OVERRIDE_WHITELIST}"; then - log "Recreating whitelist.json file at server startup" - rm -f /data/whitelist.json + if versionLessThan 1.7.6; then + log "Recreating white-list.txt file at server startup" + rm -f /data/white-list.txt + else + log "Recreating whitelist.json file at server startup" + rm -f /data/whitelist.json + fi fi if [ -n "$WHITELIST_JSON" ] && [ ! -e "/data/whitelist.json" ]; then + if versionLessThan 1.7.6; then + log "ERROR: WHITELIST_JSON not supported on 1.7.5 and below!" + exit 1 + fi if isURL "${WHITELIST_JSON}"; then log "Downloading whitelist.json from ${WHITELIST_JSON}" if ! get -o /data/whitelist.json "${WHITELIST_JSON}"; then @@ -57,11 +80,22 @@ if [ -n "$WHITELIST_JSON" ] && [ ! -e "/data/whitelist.json" ]; then fi if [ -n "$WHITELIST" ]; then log "Updating whitelist" - rm -f /data/white-list.txt.converted - if [[ $WHITELIST == *"-"* ]]; then - echo $WHITELIST | awk -v RS=, '{print}' | xargs -l -i curl -s https://playerdb.co/api/player/minecraft/{} | jq -r '.["data"]["player"] | {"uuid": .id, "name": .username}' | jq -s . > "whitelist.json" + if versionLessThan 1.7.6; then + echo $WHITELIST | awk -v RS=, '{print}' >> /data/white-list.txt + sort -u white-list.txt -o white-list.txt else - echo $WHITELIST | awk -v RS=, '{print}' > /data/white-list.txt + if [[ $WHITELIST == *"-"* ]]; then + local newList=$(echo $WHITELIST | awk -v RS=, '{print}' | xargs -l -i curl -s https://playerdb.co/api/player/minecraft/{} | jq -r '.["data"]["player"] | {"uuid": .id, "name": .username}' | jq -s .) + if [ -e /data/whitelist.json ]; then + local currentList=$(cat /data/whitelist.json) + jq --argjson current "$currentList" --argjson new "$newList" -n '$new + $current | unique_by(.uuid)' > /data/whitelist.json + else + echo $newList > /data/whitelist.json + fi + else + rm -f /data/white-list.txt.converted + echo $WHITELIST | awk -v RS=, '{print}' > /data/white-list.txt + fi fi fi From f16c33c3722a3ce8f5ff0fa0f44ce9ead50a917c Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Sat, 11 Dec 2021 01:57:09 +0000 Subject: [PATCH 04/10] Implement file support for pre-1.7.6 releases OPS_JSON and WHITELIST_JSON have been switched to OPS_FILE and WHITELIST_FILE, to allow for their use as text files for Minecraft 1.7.5 and below. The JSON check has been removed for now. --- scripts/start-finalExec | 84 +++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 53 deletions(-) diff --git a/scripts/start-finalExec b/scripts/start-finalExec index 01fec466f43..5861890477e 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -3,80 +3,58 @@ . ${SCRIPTS:-/}start-utils isDebugging && set -x +if versionLessThan 1.7.6; then + opsFile=ops.txt + whitelistFile=white-list.txt +else + opsFile=ops.json + whitelistFile=whitelist.json +fi + if isTrue "${OVERRIDE_OPS}"; then - if versionLessThan 1.7.6; then - log "Recreating ops.txt file at server startup" - rm -f /data/ops.txt - else - log "Recreating ops.json file at server startup" - rm -f /data/ops.json - fi + log "Recreating ${opsFile} file at server startup" + rm -f /data/${opsFile} fi -if [ -n "$OPS_JSON" ] && [ ! -e "/data/ops.json" ]; then - if versionLessThan 1.7.6; then - log "ERROR: OPS_JSON not supported on 1.7.5 and below!" - exit 1 - fi - if isURL "${OPS_JSON}"; then - log "Downloading ops.json from ${OPS_JSON}" - if ! get -o /data/ops.json "${OPS_JSON}"; then - log "ERROR: failed to download from ${OPS_JSON}" +if [ -n "$OPS_FILE" ] && [ ! -e /data/${opsFile} ]; then + if isURL "${OPS_FILE}"; then + log "Downloading ${opsFile} from ${OPS_FILE}" + if ! get -o /data/${opsFile} "${OPS_FILE}"; then + log "ERROR: failed to download from ${OPS_FILE}" exit 2 fi else - log "Copying ops.json from ${OPS_JSON}" - if ! cp "${OPS_JSON}" /data/ops.json; then - log "ERROR: failed to copy from ${OPS_JSON}" + log "Copying ${opsFile} from ${OPS_FILE}" + if ! cp "${OPS_FILE}" /data/${opsFile}; then + log "ERROR: failed to copy from ${OPS_FILE}" exit 1 fi fi - if ! cat /data/ops.json | jq empty; then - log "ERROR: ${OPS_JSON} is not valid JSON!" - exit 1 - fi fi if [ -n "$OPS" ]; then log "Updating ops" - if versionLessThan 1.7.6; then - echo $OPS | awk -v RS=, '{print}' >> /data/ops.txt - sort -u ops.txt -o ops.txt - else - rm -f /data/ops.txt.converted - echo $OPS | awk -v RS=, '{print}' > /data/ops.txt - fi + echo $OPS | awk -v RS=, '{print}' >> /data/ops.txt + sort -u ops.txt -o ops.txt + rm -f /data/ops.txt.converted fi if isTrue "${OVERRIDE_WHITELIST}"; then - if versionLessThan 1.7.6; then - log "Recreating white-list.txt file at server startup" - rm -f /data/white-list.txt - else - log "Recreating whitelist.json file at server startup" - rm -f /data/whitelist.json - fi + log "Recreating ${whitelistFile} file at server startup" + rm -f /data/${whitelistFile} fi -if [ -n "$WHITELIST_JSON" ] && [ ! -e "/data/whitelist.json" ]; then - if versionLessThan 1.7.6; then - log "ERROR: WHITELIST_JSON not supported on 1.7.5 and below!" - exit 1 - fi - if isURL "${WHITELIST_JSON}"; then - log "Downloading whitelist.json from ${WHITELIST_JSON}" - if ! get -o /data/whitelist.json "${WHITELIST_JSON}"; then - log "ERROR: failed to download from ${WHITELIST_JSON}" +if [ -n "$WHITELIST_FILE" ] && [ ! -e "/data/${whitelistFile}" ]; then + if isURL "${WHITELIST_FILE}"; then + log "Downloading ${whitelistFile} from ${WHITELIST_FILE}" + if ! get -o /data/${whitelistFile} "${WHITELIST_FILE}"; then + log "ERROR: failed to download from ${WHITELIST_FILE}" exit 2 fi else - log "Copying whitelist.json from ${WHITELIST_JSON}" - if ! cp "${WHITELIST_JSON}" /data/whitelist.json; then - log "ERROR: failed to copy from ${WHITELIST_JSON}" + log "Copying ${whitelistFile} from ${WHITELIST_FILE}" + if ! cp "${WHITELIST_FILE}" /data/${whitelistFile}; then + log "ERROR: failed to copy from ${WHITELIST_FILE}" exit 1 fi fi - if ! cat /data/whitelist.json | jq empty; then - log "ERROR: ${WHITELIST_JSON} is not valid JSON!" - exit 1 - fi fi if [ -n "$WHITELIST" ]; then log "Updating whitelist" From 974e9fbd830b5bca91176b49a16f8302fb33ce8a Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Sat, 11 Dec 2021 02:41:55 +0000 Subject: [PATCH 05/10] Rewrite parser for OPS and WHITELIST The parser has been rewritten to individually work on usernames/UUIDs passed in the OPS and WHITELIST environment variables. If a username or UUID could not be looked up, we log a warning about the error. No failure state is created and the user is skipped. We no longer use the legacy .txt conversion for Minecraft >= 1.7.6, we now update the ops.json or whitelist.json automatically. For both old txt and new json formats we ensure uniqueness. As part of this change, support for UUIDs in OPS has been added. --- scripts/start-finalExec | 56 ++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/scripts/start-finalExec b/scripts/start-finalExec index 5861890477e..ca93e6ac77c 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -32,9 +32,27 @@ if [ -n "$OPS_FILE" ] && [ ! -e /data/${opsFile} ]; then fi if [ -n "$OPS" ]; then log "Updating ops" - echo $OPS | awk -v RS=, '{print}' >> /data/ops.txt - sort -u ops.txt -o ops.txt - rm -f /data/ops.txt.converted + for i in ${OPS//,/} + do + if ! playerData=$(get --json-path '.["data"]["player"]' "https://playerdb.co/api/player/minecraft/$i"); then + log "WARNING: Could not lookup user $i for ${opsFile} addition" + else + opsData=$opsData$(echo $playerData | jq -r '{"uuid": .id, "name": .username, "level": 4, "bypassesPlayerLimit": false}') + fi + done + local newOps=$(echo $opsData | jq -s .) + if [ $opsFile == ops.txt ]; then + # username list for ops.txt (Minecraft <= 1.7.5) + echo $newOps | jq -r '.[].name' >> /data/${opsFile} + sort -u /data/${opsFile} -o /data/${opsFile} + elif [ -e /data/${opsFile} ]; then + # Merge with existing ops.json file + local currentOps=$(cat /data/${opsFile}) + jq --argjson current "$currentOps" --argjson new "$newOps" -n '$new + $current | unique_by(.uuid)' > /data/${opsFile} + else + # New ops.json file + echo $newOps > /data/${opsFile} + fi fi if isTrue "${OVERRIDE_WHITELIST}"; then @@ -58,22 +76,26 @@ if [ -n "$WHITELIST_FILE" ] && [ ! -e "/data/${whitelistFile}" ]; then fi if [ -n "$WHITELIST" ]; then log "Updating whitelist" - if versionLessThan 1.7.6; then - echo $WHITELIST | awk -v RS=, '{print}' >> /data/white-list.txt - sort -u white-list.txt -o white-list.txt - else - if [[ $WHITELIST == *"-"* ]]; then - local newList=$(echo $WHITELIST | awk -v RS=, '{print}' | xargs -l -i curl -s https://playerdb.co/api/player/minecraft/{} | jq -r '.["data"]["player"] | {"uuid": .id, "name": .username}' | jq -s .) - if [ -e /data/whitelist.json ]; then - local currentList=$(cat /data/whitelist.json) - jq --argjson current "$currentList" --argjson new "$newList" -n '$new + $current | unique_by(.uuid)' > /data/whitelist.json - else - echo $newList > /data/whitelist.json - fi + for i in ${WHITELIST//,/} + do + if ! playerData=$(get --json-path '.["data"]["player"]' "https://playerdb.co/api/player/minecraft/$i"); then + log "WARNING: Could not lookup user $i for ${whitelistFile} addition" else - rm -f /data/white-list.txt.converted - echo $WHITELIST | awk -v RS=, '{print}' > /data/white-list.txt + listData=$listData$(echo $playerData | jq -r '{"uuid": .id, "name": .username}') fi + done + local newList=$(echo $listData | jq -s .) + if [ $whitelistFile == white-list.txt ]; then + # username list for white-list.txt (Minecraft <= 1.7.5) + echo $newList | jq -r '.[].name' >> /data/${whitelistFile} + sort -u /data/${whitelistFile} -o /data/${whitelistFile} + elif [ -e /data/${whitelistFile} ]; then + # Merge with existing whitelist.json file + local currentList=$(cat /data/${whitelistFile}) + jq --argjson current "$currentList" --argjson new "$newList" -n '$new + $current | unique_by(.uuid)' > /data/${whitelistFile} + else + # New whitelist.json file + echo $newList > /data/${whitelistFile} fi fi From abbd0378bbd21926bac72e696a1efe9d7f576113 Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Sat, 11 Dec 2021 03:30:02 +0000 Subject: [PATCH 06/10] Condense ops/whitelist processing into functions As both the csv and file based methods now contain identical code, this logic has been moved into processor functions. --- scripts/start-finalExec | 122 ++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 67 deletions(-) diff --git a/scripts/start-finalExec b/scripts/start-finalExec index ca93e6ac77c..60f30d97680 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -11,92 +11,80 @@ else whitelistFile=whitelist.json fi -if isTrue "${OVERRIDE_OPS}"; then - log "Recreating ${opsFile} file at server startup" - rm -f /data/${opsFile} -fi -if [ -n "$OPS_FILE" ] && [ ! -e /data/${opsFile} ]; then - if isURL "${OPS_FILE}"; then - log "Downloading ${opsFile} from ${OPS_FILE}" - if ! get -o /data/${opsFile} "${OPS_FILE}"; then - log "ERROR: failed to download from ${OPS_FILE}" +function process_user_file() { + local output=$1 + local source=$2 + + if isURL "$source"; then + log "Downloading $output from $source" + if ! get -o /data/$output "$source"; then + log "ERROR: failed to download from $source" exit 2 fi else - log "Copying ${opsFile} from ${OPS_FILE}" - if ! cp "${OPS_FILE}" /data/${opsFile}; then - log "ERROR: failed to copy from ${OPS_FILE}" + log "Copying $output from $source" + if ! cp "$source" /data/$output; then + log "ERROR: failed to copy from $source" exit 1 fi fi -fi -if [ -n "$OPS" ]; then - log "Updating ops" - for i in ${OPS//,/} +} + +function process_user_csv() { + local output=$1 + local list=$2 + + if [[ "$output" == *"ops"* ]]; then + # Extra data for ops.json + userData='{"uuid": .id, "name": .username, "level": 4}' + else + userData='{"uuid": .id, "name": .username}' + fi + + log "Updating ${output%.*}" + for i in ${list//,/ } do - if ! playerData=$(get --json-path '.["data"]["player"]' "https://playerdb.co/api/player/minecraft/$i"); then - log "WARNING: Could not lookup user $i for ${opsFile} addition" + if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then + log "WARNING: Could not lookup user $i for ${output} addition" else - opsData=$opsData$(echo $playerData | jq -r '{"uuid": .id, "name": .username, "level": 4, "bypassesPlayerLimit": false}') + playerDataList=$playerDataList$(echo $playerData | jq -r "$userData") fi done - local newOps=$(echo $opsData | jq -s .) - if [ $opsFile == ops.txt ]; then - # username list for ops.txt (Minecraft <= 1.7.5) - echo $newOps | jq -r '.[].name' >> /data/${opsFile} - sort -u /data/${opsFile} -o /data/${opsFile} - elif [ -e /data/${opsFile} ]; then - # Merge with existing ops.json file - local currentOps=$(cat /data/${opsFile}) - jq --argjson current "$currentOps" --argjson new "$newOps" -n '$new + $current | unique_by(.uuid)' > /data/${opsFile} + local newUsers=$(echo $playerDataList | jq -s .) + if [[ $output =~ .*\.txt ]]; then + # username list for txt config (Minecraft <= 1.7.5) + echo $newUsers | jq -r '.[].name' >> /data/${output} + sort -u /data/${output} -o /data/${output} + elif [ -e /data/${output} ]; then + # Merge with existing json file + local currentUsers=$(cat /data/${output}) + jq --argjson current "$currentUsers" --argjson new "$newUsers" -n '$new + $current | unique_by(.uuid)' > /data/${output} else - # New ops.json file - echo $newOps > /data/${opsFile} + # New json file + echo $newUsers > /data/${output} fi +} + +if isTrue "${OVERRIDE_OPS}"; then + log "Recreating ${opsFile} file at server startup" + rm -f /data/${opsFile} +fi +if [ -n "${OPS_FILE}" ] && [ ! -e "/data/${opsFile}" ]; then + process_user_file ${opsFile} "$OPS_FILE" +fi +if [ -n "${OPS}" ]; then + process_user_csv ${opsFile} "$OPS" fi if isTrue "${OVERRIDE_WHITELIST}"; then log "Recreating ${whitelistFile} file at server startup" rm -f /data/${whitelistFile} fi -if [ -n "$WHITELIST_FILE" ] && [ ! -e "/data/${whitelistFile}" ]; then - if isURL "${WHITELIST_FILE}"; then - log "Downloading ${whitelistFile} from ${WHITELIST_FILE}" - if ! get -o /data/${whitelistFile} "${WHITELIST_FILE}"; then - log "ERROR: failed to download from ${WHITELIST_FILE}" - exit 2 - fi - else - log "Copying ${whitelistFile} from ${WHITELIST_FILE}" - if ! cp "${WHITELIST_FILE}" /data/${whitelistFile}; then - log "ERROR: failed to copy from ${WHITELIST_FILE}" - exit 1 - fi - fi +if [ -n "${WHITELIST_FILE}" ] && [ ! -e "/data/${whitelistFile}" ]; then + process_user_file ${whitelistFile} "$WHITELIST_FILE" fi -if [ -n "$WHITELIST" ]; then - log "Updating whitelist" - for i in ${WHITELIST//,/} - do - if ! playerData=$(get --json-path '.["data"]["player"]' "https://playerdb.co/api/player/minecraft/$i"); then - log "WARNING: Could not lookup user $i for ${whitelistFile} addition" - else - listData=$listData$(echo $playerData | jq -r '{"uuid": .id, "name": .username}') - fi - done - local newList=$(echo $listData | jq -s .) - if [ $whitelistFile == white-list.txt ]; then - # username list for white-list.txt (Minecraft <= 1.7.5) - echo $newList | jq -r '.[].name' >> /data/${whitelistFile} - sort -u /data/${whitelistFile} -o /data/${whitelistFile} - elif [ -e /data/${whitelistFile} ]; then - # Merge with existing whitelist.json file - local currentList=$(cat /data/${whitelistFile}) - jq --argjson current "$currentList" --argjson new "$newList" -n '$new + $current | unique_by(.uuid)' > /data/${whitelistFile} - else - # New whitelist.json file - echo $newList > /data/${whitelistFile} - fi +if [ -n "${WHITELIST}" ]; then + process_user_csv ${whitelistFile} "$WHITELIST" fi if [ -n "$ICON" ]; then From e2b6618019f361a5a5120052a3c6a4bc9bf2e6c9 Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Sat, 11 Dec 2021 03:31:57 +0000 Subject: [PATCH 07/10] Documentation changes --- README.md | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2979a4475c4..52fda7c4042 100644 --- a/README.md +++ b/README.md @@ -846,30 +846,35 @@ values. > **NOTE** it is very important to set this with servers exposed to the internet where you want only limited players to join. -To whitelist players for your Minecraft server, pass the Minecraft usernames separated by commas via the `WHITELIST` environment variable, such as +To whitelist players for your Minecraft server, you can: +- Provide the url or path to a whitelist file via `WHITELIST_FILE` environment variable + `docker run -d -e WHITELIST_FILE=/extra/whitelist.json ...` +- Provide a list of usernames and/or UUIDs separated by commas via the `WHITELIST` environment variable + `docker run -d -e WHITELIST=user1,uuid2 ...` - docker run -d -e WHITELIST=user1,user2 ... +If either `WHITELIST_FILE` or `WHITELIST` is provided, the server properties `white-list` and `whitelist` will automatically get set to `true`. Therefore **by default** any user can join your Minecraft server if it's publicly accessible. -or +If whitelist configuration already exists, `WHITELIST_FILE` will not be retrieved and any usernames in `WHITELIST` are **added** to the whitelist configuration. You can enforce regeneration of the whitelist on each server startup by setting `OVERRIDE_WHITELIST` to "true". This will delete the whitelist file before processing whitelist configuration. - docker run -d -e WHITELIST=uuid1,uuid2 ... +> NOTE: You can provide both `WHITELIST_FILE` and `WHITELIST`, which are processed in that order. -If the `WHITELIST` environment variable is not used, any user can join your Minecraft server if it's publicly accessible. +> NOTE: UUIDs passed via `WHITELIST` need to be the dashed variant, otherwise it not be recognised and instead added as a username. -> NOTE: When using uuids in the whitelist, please make sure it is the dashed variant otherwise it will not parse correctly. - -> NOTE: When `WHITELIST` is used the server properties `white-list` and `whitelist` will automatically get set to `true`. - -> By default, the players in `WHITELIST` are **added** to the final `whitelist.json` file by the Minecraft server. If you set `OVERRIDE_WHITELIST` to "true" then the `whitelist.json` file will be recreated on each server startup. +> If running Minecraft 1.7.5 or earlier, these variables will apply to `white-list.txt`, with 1.7.6 implementing support for `whitelist.json`. Make sure your `WHITELIST_FILE` is in the appropriate format. Alternatively, you can set `ENABLE_WHITELIST=true` to only set the server properties `white-list` and `whitelist` without modifying the whitelist file. In this case the whitelist is solely managed using the `whitelist add` and `whitelist remove` commands. + ### Op/Administrator Players -To add more "op" (aka adminstrator) users to your Minecraft server, pass the Minecraft usernames separated by commas via the `OPS` environment variable, such as +Similar to the whitelist, to add users as operators (aka adminstrators) to your Minecraft server, you can: +- Provide te url or path to an ops file via `OPS_FILE` environment variable + `docker run -d -e OPS_FILE=https://config.example.com/extra/ops.json ...` +- Provide a list of usernames and/or UUIDs separated by commas via the `OPS` environment variable + `docker run -d -e OPS=user1,uuid2 ...` - docker run -d -e OPS=user1,user2 ... +If ops configuration already exists, `OPS_FILE` will not be retrieved and any usernames in `OPS` are **added** to the ops configuration. You can enforce regeneration of the ops configuration on each server startup by setting `OVERRIDE_OPS` to "true". This will delete the ops file before processing ops configuration. -> By default, the players in `OPS` are **added** to the final `ops.json` file by the Minecraft server. If you set `OVERRIDE_OPS` to "true" then the `ops.json` file will be recreated on each server startup. +> Similar to whitelists, you can provide both `OPS_FILE` and `OPS`, and Minecraft 1.7.5 or earlier will use `ops.txt` rather than `ops.json`. ### Server icon From 08bf2b046f4cd4c123e871204eb88849c98bcdf4 Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Sat, 11 Dec 2021 04:31:08 +0000 Subject: [PATCH 08/10] Clarify use of whitelist and enforcement Documentation has been updated to draw attention to the requirement of ENFORCE_WHITELIST to actually enforce the configured whitelist. A server log message has been added to warn if the whitelist functionality is enabled but not enforced. The duplicate setting of 'whitelist' and 'white-list' in server.properties has been removed, leaving only 'white-list' being applied. I believe this was an error introduced with the addition of whitelist functionality in 111883e, that was subsequently fixed in 32cb5f4. --- README.md | 4 ++-- scripts/start-setupServerProperties | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 52fda7c4042..3d7c037390b 100644 --- a/README.md +++ b/README.md @@ -852,7 +852,7 @@ To whitelist players for your Minecraft server, you can: - Provide a list of usernames and/or UUIDs separated by commas via the `WHITELIST` environment variable `docker run -d -e WHITELIST=user1,uuid2 ...` -If either `WHITELIST_FILE` or `WHITELIST` is provided, the server properties `white-list` and `whitelist` will automatically get set to `true`. Therefore **by default** any user can join your Minecraft server if it's publicly accessible. +To enforce the whitelist and auto-kick players not included in whitelist configuration, set `ENFORCE_WHITELIST=TRUE`. **By default** any user can join your Minecraft server if it's publicly accessible, regardless of your whitelist configuration. If whitelist configuration already exists, `WHITELIST_FILE` will not be retrieved and any usernames in `WHITELIST` are **added** to the whitelist configuration. You can enforce regeneration of the whitelist on each server startup by setting `OVERRIDE_WHITELIST` to "true". This will delete the whitelist file before processing whitelist configuration. @@ -862,7 +862,7 @@ If whitelist configuration already exists, `WHITELIST_FILE` will not be retrieve > If running Minecraft 1.7.5 or earlier, these variables will apply to `white-list.txt`, with 1.7.6 implementing support for `whitelist.json`. Make sure your `WHITELIST_FILE` is in the appropriate format. -Alternatively, you can set `ENABLE_WHITELIST=true` to only set the server properties `white-list` and `whitelist` without modifying the whitelist file. In this case the whitelist is solely managed using the `whitelist add` and `whitelist remove` commands. +If either `WHITELIST_FILE` or `WHITELIST` is provided, the server property `white-list` is automatically set to `true`, enabline whitelist functionality. Alternatively you can set `ENABLE_WHITELIST=TRUE` to only set the server property `white-list` without modifying the whitelist file. In this case the whitelist can be managed using the `whitelist add` and `whitelist remove` commands. Remember you can set enforcement via the `ENFORCE_WHITELIST` variable. ### Op/Administrator Players diff --git a/scripts/start-setupServerProperties b/scripts/start-setupServerProperties index 0855da5ecbb..0febd09694e 100755 --- a/scripts/start-setupServerProperties +++ b/scripts/start-setupServerProperties @@ -33,15 +33,18 @@ function setServerProp { } function customizeServerProps { - if [ -n "$WHITELIST" ] || isTrue "${ENABLE_WHITELIST:-false}"; then - log "Creating whitelist" - setServerPropValue "whitelist" "true" + # Whitelist processing + if [ -n "$WHITELIST" ] || [ -n "$WHITELIST_FILE" ] || isTrue "${ENABLE_WHITELIST:-false}"; then + log "Enabling whitelist functionality" setServerPropValue "white-list" "true" else - log "Disabling whitelist" - setServerPropValue "whitelist" "false" + log "Disabling whitelist functionality" setServerPropValue "white-list" "false" fi + setServerProp "enforce-whitelist" ENFORCE_WHITELIST + if [[ $(grep "enforce-whitelist" $SERVER_PROPERTIES) != *true ]]; then + log "WARNING: whitelist enabled but not enforced. Set ENFORCE_WHITELIST=TRUE or update 'enforce-whitelist' in server.properties to enforce the whitelist." + fi # If not provided, generate a reasonable default message-of-the-day, # which shows up in the server listing in the client @@ -104,7 +107,6 @@ function customizeServerProps { setServerProp "op-permission-level" OP_PERMISSION_LEVEL setServerProp "prevent-proxy-connections" PREVENT_PROXY_CONNECTIONS setServerProp "use-native-transport" USE_NATIVE_TRANSPORT - setServerProp "enforce-whitelist" ENFORCE_WHITELIST setServerProp "simulation-distance" SIMULATION_DISTANCE setServerPropValue "motd" "$(echo "$MOTD" | mc-image-helper asciify)" [[ $LEVEL_TYPE ]] && setServerPropValue "level-type" "${LEVEL_TYPE^^}" From 831085b4767b32002260ff55d5de0fd76f786521 Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Sat, 11 Dec 2021 07:57:27 +0000 Subject: [PATCH 09/10] Skip usernames & UUIDs already present in config This significantly speeds up processing for large csv lists. --- scripts/start-finalExec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/start-finalExec b/scripts/start-finalExec index 60f30d97680..47e7368338b 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -44,6 +44,10 @@ function process_user_csv() { log "Updating ${output%.*}" for i in ${list//,/ } do + if [ -e "$output" ] && grep -q "$i" "$output"; then + log "$i already present in $output, skipping" + continue + fi if ! playerData=$(get "https://playerdb.co/api/player/minecraft/$i" | jq -re ".data.player"); then log "WARNING: Could not lookup user $i for ${output} addition" else From 392cd70cbb4feed1da8de33c666847493ae05c63 Mon Sep 17 00:00:00 2001 From: Daniel Porter Date: Sat, 11 Dec 2021 21:49:26 +0000 Subject: [PATCH 10/10] Fix issue with level being added to whitelist.json The playerDataList variable was being re-used, and adding to whitelist after Ops processing. --- scripts/start-finalExec | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/start-finalExec b/scripts/start-finalExec index 47e7368338b..686c4dd69d8 100755 --- a/scripts/start-finalExec +++ b/scripts/start-finalExec @@ -33,6 +33,7 @@ function process_user_file() { function process_user_csv() { local output=$1 local list=$2 + local playerDataList if [[ "$output" == *"ops"* ]]; then # Extra data for ops.json