feat(deploy): 自动初始化画布协作认证密钥
This commit is contained in:
Executable
+121
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
# shellcheck source=scripts/init-security-env.sh
|
||||
. "${SCRIPT_DIR}/init-security-env.sh"
|
||||
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
write_env() {
|
||||
local file="$1"
|
||||
shift
|
||||
printf '%s\n' "$@" > "$file"
|
||||
}
|
||||
|
||||
assert_min_length() {
|
||||
local file="$1"
|
||||
local key="$2"
|
||||
local minimum="$3"
|
||||
local value
|
||||
value="$(read_env_value "$file" "$key")"
|
||||
[ "${#value}" -ge "$minimum" ] || fail "$key must contain at least $minimum characters"
|
||||
}
|
||||
|
||||
assert_value() {
|
||||
local file="$1"
|
||||
local key="$2"
|
||||
local expected="$3"
|
||||
local actual
|
||||
actual="$(read_env_value "$file" "$key")"
|
||||
[ "$actual" = "$expected" ] || fail "$key expected '$expected', got '$actual'"
|
||||
}
|
||||
|
||||
assert_single_key() {
|
||||
local file="$1"
|
||||
local key="$2"
|
||||
local count
|
||||
count="$(grep -c "^${key}=" "$file" || true)"
|
||||
[ "$count" -eq 1 ] || fail "$key must appear exactly once"
|
||||
}
|
||||
|
||||
file_sha256() {
|
||||
local file="$1"
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
sha256sum "$file" | awk '{print $1}'
|
||||
else
|
||||
shasum -a 256 "$file" | awk '{print $1}'
|
||||
fi
|
||||
}
|
||||
|
||||
upgrade_env="$TMP_DIR/upgrade.env"
|
||||
upgrade_log="$TMP_DIR/upgrade.log"
|
||||
write_env "$upgrade_env" \
|
||||
"CONFIG_JWT_SECRET='this is a very secret secret'" \
|
||||
"CONFIG_SECURITY_CONFIG_ENCRYPTION_KEY=" \
|
||||
"WS_AUTH_WS_TICKET_SECRET=" \
|
||||
"WS_AUTH_METHODS=none,bearer"
|
||||
init_security_env "$upgrade_env" upgrade > "$upgrade_log"
|
||||
|
||||
assert_min_length "$upgrade_env" "CONFIG_JWT_SECRET" 32
|
||||
assert_min_length "$upgrade_env" "WS_AUTH_WS_TICKET_SECRET" 32
|
||||
assert_value "$upgrade_env" "CONFIG_SECURITY_CONFIG_ENCRYPTION_KEY" ""
|
||||
assert_value "$upgrade_env" "WS_AUTH_METHODS" "none,bearer,ws_ticket"
|
||||
assert_single_key "$upgrade_env" "WS_AUTH_WS_TICKET_SECRET"
|
||||
assert_single_key "$upgrade_env" "WS_AUTH_METHODS"
|
||||
|
||||
upgrade_jwt="$(read_env_value "$upgrade_env" "CONFIG_JWT_SECRET")"
|
||||
upgrade_ws="$(read_env_value "$upgrade_env" "WS_AUTH_WS_TICKET_SECRET")"
|
||||
if grep -Fq "$upgrade_jwt" "$upgrade_log" || grep -Fq "$upgrade_ws" "$upgrade_log"; then
|
||||
fail "security initialization output must not reveal generated secrets"
|
||||
fi
|
||||
|
||||
before_repeat="$(file_sha256 "$upgrade_env")"
|
||||
init_security_env "$upgrade_env" upgrade > "$TMP_DIR/repeat.log"
|
||||
after_repeat="$(file_sha256 "$upgrade_env")"
|
||||
[ "$before_repeat" = "$after_repeat" ] || fail "repeated upgrade must preserve generated values byte-for-byte"
|
||||
|
||||
preserved_secret="existing-ws-ticket-secret-that-is-long-enough"
|
||||
preserved_env="$TMP_DIR/preserved.env"
|
||||
write_env "$preserved_env" \
|
||||
"CONFIG_JWT_SECRET=existing-jwt-secret-that-is-long-enough" \
|
||||
"WS_AUTH_WS_TICKET_SECRET=$preserved_secret" \
|
||||
"WS_AUTH_METHODS=bearer,ws_ticket"
|
||||
init_security_env "$preserved_env" upgrade > "$TMP_DIR/preserved.log"
|
||||
assert_value "$preserved_env" "WS_AUTH_WS_TICKET_SECRET" "$preserved_secret"
|
||||
assert_value "$preserved_env" "WS_AUTH_METHODS" "bearer,ws_ticket"
|
||||
|
||||
new_env="$TMP_DIR/new.env"
|
||||
write_env "$new_env" \
|
||||
"CONFIG_JWT_SECRET=" \
|
||||
"CONFIG_SECURITY_CONFIG_ENCRYPTION_KEY=" \
|
||||
"CONFIG_OTP_HASH_SECRET=" \
|
||||
"CONFIG_AUDIT_HASH_PEPPER=" \
|
||||
"CONFIG_AUDIT_INTEGRITY_KEY=" \
|
||||
"CONFIG_INITIAL_ADMIN_PASSWORD=" \
|
||||
"WS_AUTH_WS_TICKET_SECRET=" \
|
||||
"WS_AUTH_METHODS="
|
||||
init_security_env "$new_env" new > "$TMP_DIR/new.log"
|
||||
for key in \
|
||||
CONFIG_JWT_SECRET \
|
||||
CONFIG_SECURITY_CONFIG_ENCRYPTION_KEY \
|
||||
CONFIG_OTP_HASH_SECRET \
|
||||
CONFIG_AUDIT_HASH_PEPPER \
|
||||
CONFIG_AUDIT_INTEGRITY_KEY \
|
||||
WS_AUTH_WS_TICKET_SECRET; do
|
||||
assert_min_length "$new_env" "$key" 32
|
||||
done
|
||||
assert_min_length "$new_env" "CONFIG_INITIAL_ADMIN_PASSWORD" 12
|
||||
assert_value "$new_env" "WS_AUTH_METHODS" "none,bearer,ws_ticket"
|
||||
|
||||
mode="$(stat -c '%a' "$new_env" 2>/dev/null || stat -f '%Lp' "$new_env")"
|
||||
[ "$mode" = "600" ] || fail "generated environment file mode must be 600, got $mode"
|
||||
|
||||
echo "Security environment shell tests passed"
|
||||
Reference in New Issue
Block a user