Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
86cd632416 | |||
|
19f73fb5ab | ||
|
72cb30e706 | ||
|
1134fd915c |
@@ -1,6 +1,6 @@
|
|||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
|
|
||||||
RUN apk add --no-cache yq
|
RUN apk add --no-cache yq curl openssl jq
|
||||||
|
|
||||||
COPY start.sh /start.sh
|
COPY start.sh /start.sh
|
||||||
|
|
||||||
|
125
start.sh
125
start.sh
@@ -8,10 +8,9 @@ POSTGRES_HOST=matrixpostgres-db
|
|||||||
DB_PORT="5432"
|
DB_PORT="5432"
|
||||||
|
|
||||||
SYNAPSE_HOST="${SYNAPSE_SERVER_NAME:-localhost}"
|
SYNAPSE_HOST="${SYNAPSE_SERVER_NAME:-localhost}"
|
||||||
SYNAPSE_PORT="${SYNAPSE_PORT:-8008}"
|
|
||||||
ADMIN_USERNAME="${ADMIN_USERNAME:-admin}"
|
ADMIN_USERNAME="${ADMIN_USERNAME:-admin}"
|
||||||
ADMIN_PASSWORD="${ADMIN_PASSWORD:-changeme}"
|
ADMIN_PASSWORD="${ADMIN_PASSWORD:-changeme}"
|
||||||
HOMESERVER_URL="${HOMESERVER_URL:-http://$SYNAPSE_HOST:$SYNAPSE_PORT}"
|
HOMESERVER_URL="${HOMESERVER_URL:-https://$SYNAPSE_HOST}"
|
||||||
|
|
||||||
prepare_postgres () {
|
prepare_postgres () {
|
||||||
if [ -f /data/homeserver.yaml ]; then
|
if [ -f /data/homeserver.yaml ]; then
|
||||||
@@ -37,6 +36,10 @@ prepare_postgres () {
|
|||||||
get_registration_secret() {
|
get_registration_secret() {
|
||||||
if [ -f "/data/homeserver.yaml" ]; then
|
if [ -f "/data/homeserver.yaml" ]; then
|
||||||
SHARED_SECRET=$(yq '.registration_shared_secret' /data/homeserver.yaml 2>/dev/null)
|
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
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +50,7 @@ wait_for_synapse() {
|
|||||||
local attempt=1
|
local attempt=1
|
||||||
|
|
||||||
while [ $attempt -le $max_attempts ]; do
|
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!"
|
echo "Synapse is ready!"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -60,30 +63,6 @@ wait_for_synapse() {
|
|||||||
return 1
|
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 using shared secret
|
||||||
register_admin_user() {
|
register_admin_user() {
|
||||||
@@ -91,26 +70,60 @@ register_admin_user() {
|
|||||||
|
|
||||||
echo "Registering admin user: $ADMIN_USERNAME"
|
echo "Registering admin user: $ADMIN_USERNAME"
|
||||||
|
|
||||||
# Generate registration MAC
|
# Derive localpart (strip leading @ and :domain) and lowercase
|
||||||
local nonce=$(date +%s)
|
local localpart
|
||||||
local username_lower=$(echo "$ADMIN_USERNAME" | tr '[:upper:]' '[:lower:]')
|
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)
|
# Fetch server-issued nonce
|
||||||
local mac=$(echo -n "${nonce}${username_lower}${ADMIN_PASSWORD}admin" | openssl dgst -sha1 -hmac "$SHARED_SECRET" -binary | base64)
|
local url nonce
|
||||||
|
url="${HOMESERVER_URL%/}/_synapse/admin/v1/register"
|
||||||
|
nonce=$(curl -kfsS "$url" | jq -r '.nonce')
|
||||||
|
|
||||||
# Register user
|
if [ -z "$nonce" ] || [ "$nonce" = "null" ]; then
|
||||||
local response=$(curl -s -X POST "$HOMESERVER_URL/_synapse/admin/v1/register" \
|
echo "Failed to fetch nonce from $url"
|
||||||
-H "Content-Type: application/json" \
|
return 1
|
||||||
-d "{
|
fi
|
||||||
\"nonce\": \"$nonce\",
|
|
||||||
\"username\": \"$username_lower\",
|
|
||||||
\"password\": \"$ADMIN_PASSWORD\",
|
|
||||||
\"admin\": true,
|
|
||||||
\"mac\": \"$mac\"
|
|
||||||
}" 2>/dev/null)
|
|
||||||
|
|
||||||
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!"
|
echo "Admin user created successfully!"
|
||||||
|
|
||||||
|
# renmove registration_shared_secret from homeserver.yaml for security
|
||||||
|
yq eval '.registration_shared_secret = ""' /data/homeserver.yaml > /tmp/homeserver.yaml.tmp && mv /tmp/homeserver.yaml.tmp /data/homeserver.yaml
|
||||||
|
|
||||||
|
# trigger a restart of synapse to reload config
|
||||||
|
echo '{"NAME":"service-matrix.containers.matrixserver-app"}' | jq -r > /var/tmp/shared/input/upgrade-matrix.json
|
||||||
|
echo "Matrix server app restart requested"
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
echo "Failed to create admin user. Response: $response"
|
echo "Failed to create admin user. Response: $response"
|
||||||
@@ -118,28 +131,9 @@ register_admin_user() {
|
|||||||
fi
|
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 if admin exists by trying to login
|
||||||
check_admin_by_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" \
|
-H "Content-Type: application/json" \
|
||||||
-d "{
|
-d "{
|
||||||
\"type\": \"m.login.password\",
|
\"type\": \"m.login.password\",
|
||||||
@@ -147,8 +141,10 @@ check_admin_by_login() {
|
|||||||
\"password\": \"$ADMIN_PASSWORD\"
|
\"password\": \"$ADMIN_PASSWORD\"
|
||||||
}" 2>/dev/null)
|
}" 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"
|
||||||
return 0 # User exists and password is correct
|
return 0 # User exists and password is correct
|
||||||
|
|
||||||
fi
|
fi
|
||||||
return 1 # User doesn't exist or wrong password
|
return 1 # User doesn't exist or wrong password
|
||||||
}
|
}
|
||||||
@@ -182,7 +178,6 @@ main() {
|
|||||||
# Try to register admin user
|
# Try to register admin user
|
||||||
if ! register_admin_user "$SHARED_SECRET"; then
|
if ! register_admin_user "$SHARED_SECRET"; then
|
||||||
echo "Primary registration method failed, trying alternative..."
|
echo "Primary registration method failed, trying alternative..."
|
||||||
register_user_simple "$SHARED_SECRET"
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user