Enhance Dockerfile and start.sh: add curl, openssl, and jq; update HOMESERVER_URL to use HTTPS; improve admin user registration logic and error handling
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing

This commit is contained in:
gyurix
2025-09-01 16:08:08 +02:00
parent 6732bc332a
commit 1134fd915c
2 changed files with 58 additions and 70 deletions

View File

@@ -1,6 +1,6 @@
FROM alpine:latest
RUN apk add --no-cache yq
RUN apk add --no-cache yq curl openssl jq
COPY start.sh /start.sh

118
start.sh
View File

@@ -8,10 +8,9 @@ POSTGRES_HOST=matrixpostgres-db
DB_PORT="5432"
SYNAPSE_HOST="${SYNAPSE_SERVER_NAME:-localhost}"
SYNAPSE_PORT="${SYNAPSE_PORT:-8008}"
ADMIN_USERNAME="${ADMIN_USERNAME:-admin}"
ADMIN_PASSWORD="${ADMIN_PASSWORD:-changeme}"
HOMESERVER_URL="${HOMESERVER_URL:-http://$SYNAPSE_HOST:$SYNAPSE_PORT}"
HOMESERVER_URL="${HOMESERVER_URL:-https://$SYNAPSE_HOST}"
prepare_postgres () {
if [ -f /data/homeserver.yaml ]; then
@@ -37,6 +36,10 @@ prepare_postgres () {
get_registration_secret() {
if [ -f "/data/homeserver.yaml" ]; then
SHARED_SECRET=$(yq '.registration_shared_secret' /data/homeserver.yaml 2>/dev/null)
echo "$SHARED_SECRET"
if [ -n "$SHARED_SECRET" ] && [ "$SHARED_SECRET" != "null" ]; then
return 0
fi
fi
}
@@ -47,7 +50,7 @@ wait_for_synapse() {
local attempt=1
while [ $attempt -le $max_attempts ]; do
if curl -s "$HOMESERVER_URL/_matrix/client/versions" >/dev/null 2>&1; then
if curl -sk "$HOMESERVER_URL/_matrix/client/versions" >/dev/null 2>&1; then
echo "Synapse is ready!"
return 0
fi
@@ -60,30 +63,6 @@ wait_for_synapse() {
return 1
}
# Check if any admin users exist using admin API
check_admin_exists() {
# Try to get a temporary admin token first
local temp_token=$(get_admin_token)
if [ -n "$temp_token" ]; then
local response=$(curl -s -X GET \
"$HOMESERVER_URL/_synapse/admin/v2/users?deactivated=false" \
-H "Authorization: Bearer $temp_token" 2>/dev/null || echo "")
if echo "$response" | grep -q '"admin": true'; then
return 0 # Admin exists
fi
fi
return 1 # No admin or couldn't check
}
# Get admin token (this requires an existing admin user)
get_admin_token() {
# This function would need an existing admin to work
# For initial setup, we'll rely on registration shared secret
echo ""
}
# Register admin user using shared secret
register_admin_user() {
@@ -91,25 +70,51 @@ register_admin_user() {
echo "Registering admin user: $ADMIN_USERNAME"
# Generate registration MAC
local nonce=$(date +%s)
local username_lower=$(echo "$ADMIN_USERNAME" | tr '[:upper:]' '[:lower:]')
# Derive localpart (strip leading @ and :domain) and lowercase
local localpart
localpart=$(printf '%s' "$ADMIN_USERNAME" | sed -e 's/^@//' -e 's/:.*$//' | tr '[:upper:]' '[:lower:]')
# Calculate HMAC (simplified - in practice you'd want to use proper HMAC)
local mac=$(echo -n "${nonce}${username_lower}${ADMIN_PASSWORD}admin" | openssl dgst -sha1 -hmac "$SHARED_SECRET" -binary | base64)
# Fetch server-issued nonce
local url nonce
url="${HOMESERVER_URL%/}/_synapse/admin/v1/register"
nonce=$(curl -kfsS "$url" | jq -r '.nonce')
# Register user
local response=$(curl -s -X POST "$HOMESERVER_URL/_synapse/admin/v1/register" \
-H "Content-Type: application/json" \
-d "{
\"nonce\": \"$nonce\",
\"username\": \"$username_lower\",
\"password\": \"$ADMIN_PASSWORD\",
\"admin\": true,
\"mac\": \"$mac\"
}" 2>/dev/null)
if [ -z "$nonce" ] || [ "$nonce" = "null" ]; then
echo "Failed to fetch nonce from $url"
return 1
fi
if echo "$response" | grep -q "access_token"; then
# Admin flag and user_type
local admin_word admin_json user_type user_type_json
user_type="${USER_TYPE:-}"
case "${ADMIN:-true}" in
true|1|yes|y|True|TRUE) admin_word="admin"; admin_json=true ;;
*) admin_word="notadmin"; admin_json=false ;;
esac
if [ -n "$user_type" ]; then
user_type_json=$(printf '"%s"' "$user_type")
else
user_type_json=null
fi
# Compute MAC exactly like Python (no trailing NUL unless user_type present)
local mac
if [ -n "$user_type" ]; then
mac=$(printf '%s\0%s\0%s\0%s\0%s' "$nonce" "$localpart" "$ADMIN_PASSWORD" "$admin_word" "$user_type" \
| openssl dgst -sha1 -hmac "$SHARED_SECRET" -binary | od -An -tx1 | tr -d ' \n')
else
mac=$(printf '%s\0%s\0%s\0%s' "$nonce" "$localpart" "$ADMIN_PASSWORD" "$admin_word" \
| openssl dgst -sha1 -hmac "$SHARED_SECRET" -binary | od -An -tx1 | tr -d ' \n')
fi
# Build payload and register
local payload response
payload=$(printf '{"nonce":"%s","username":"%s","password":"%s","admin":%s,"user_type":%s,"mac":"%s"}' \
"$nonce" "$localpart" "$ADMIN_PASSWORD" "$admin_json" "$user_type_json" "$mac")
response=$(curl -kfsS -X POST "$url" -H 'Content-Type: application/json' -d "$payload" || true)
if echo "$response" | grep -q '"user_id"\|"access_token"'; then
echo "Admin user created successfully!"
return 0
else
@@ -118,28 +123,9 @@ register_admin_user() {
fi
}
# Alternative method using registration endpoint
register_user_simple() {
local SHARED_SECRET=$1
echo "Attempting simple registration for: $ADMIN_USERNAME"
# Try the simpler registration method
local response=$(curl -s -X POST "$HOMESERVER_URL/_matrix/client/r0/admin/register" \
-H "Content-Type: application/json" \
-d "{
\"username\": \"$ADMIN_USERNAME\",
\"password\": \"$ADMIN_PASSWORD\",
\"admin\": true,
\"shared_secret\": \"$SHARED_SECRET\"
}" 2>/dev/null)
echo "Registration response: $response"
}
# Check if admin exists by trying to login
check_admin_by_login() {
local response=$(curl -s -X POST "$HOMESERVER_URL/_matrix/client/r0/login" \
local response=$(curl -sk -X POST "$HOMESERVER_URL/_matrix/client/r0/login" \
-H "Content-Type: application/json" \
-d "{
\"type\": \"m.login.password\",
@@ -147,8 +133,11 @@ check_admin_by_login() {
\"password\": \"$ADMIN_PASSWORD\"
}" 2>/dev/null)
if echo "$response" | grep -q "access_token"; then
if echo "$response" | grep -q access_token; then
echo "Successfully logged in as admin user"
yq eval '.registration_shared_secret = ""' /data/homeserver.yaml > /data/homeserver.yaml.tmp && mv /data/homeserver.yaml.tmp /data/homeserver.yaml
return 0 # User exists and password is correct
fi
return 1 # User doesn't exist or wrong password
}
@@ -182,7 +171,6 @@ main() {
# Try to register admin user
if ! register_admin_user "$SHARED_SECRET"; then
echo "Primary registration method failed, trying alternative..."
register_user_simple "$SHARED_SECRET"
fi
}