|  |  | @ -173,363 +173,3 @@ main() { | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | main "$@" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | #!/bin/bash | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # Keycloak Setup Script for CI/CD | 
			
		
	
		
			
				
					|  |  |  | # This script sets up a Keycloak realm with test users and roles for SeaweedFS S3 IAM testing | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | set -e | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | KEYCLOAK_URL="${KEYCLOAK_URL:-http://localhost:8080}" | 
			
		
	
		
			
				
					|  |  |  | # Support both old and new Keycloak environment variable formats | 
			
		
	
		
			
				
					|  |  |  | ADMIN_USER="${KC_BOOTSTRAP_ADMIN_USERNAME:-${KEYCLOAK_ADMIN:-admin}}" | 
			
		
	
		
			
				
					|  |  |  | ADMIN_PASSWORD="${KC_BOOTSTRAP_ADMIN_PASSWORD:-${KEYCLOAK_ADMIN_PASSWORD:-admin}}" | 
			
		
	
		
			
				
					|  |  |  | REALM_NAME="seaweedfs-test" | 
			
		
	
		
			
				
					|  |  |  | CLIENT_ID="seaweedfs-s3" | 
			
		
	
		
			
				
					|  |  |  | CLIENT_SECRET="seaweedfs-s3-secret" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | echo "🔧 Setting up Keycloak realm and users for SeaweedFS S3 IAM testing..." | 
			
		
	
		
			
				
					|  |  |  | echo "Keycloak URL: $KEYCLOAK_URL" | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # Function to get admin access token with retry logic | 
			
		
	
		
			
				
					|  |  |  | get_admin_token() { | 
			
		
	
		
			
				
					|  |  |  |     local max_attempts=5 | 
			
		
	
		
			
				
					|  |  |  |     local attempt=1 | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     while [ $attempt -le $max_attempts ]; do | 
			
		
	
		
			
				
					|  |  |  |         echo "🔑 Getting admin access token (attempt $attempt/$max_attempts)..." | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         local response=$(curl -s -X POST "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" \ | 
			
		
	
		
			
				
					|  |  |  |             -H "Content-Type: application/x-www-form-urlencoded" \ | 
			
		
	
		
			
				
					|  |  |  |             -d "username=$ADMIN_USER" \ | 
			
		
	
		
			
				
					|  |  |  |             -d "password=$ADMIN_PASSWORD" \ | 
			
		
	
		
			
				
					|  |  |  |             -d "grant_type=password" \ | 
			
		
	
		
			
				
					|  |  |  |             -d "client_id=admin-cli" 2>/dev/null || echo '{"error":"curl_failed"}') | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         local token=$(echo "$response" | jq -r '.access_token // empty' 2>/dev/null || echo "") | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         if [ -n "$token" ] && [ "$token" != "null" ] && [ "$token" != "" ]; then | 
			
		
	
		
			
				
					|  |  |  |             echo "✅ Successfully obtained admin token" | 
			
		
	
		
			
				
					|  |  |  |             echo "$token" | 
			
		
	
		
			
				
					|  |  |  |             return 0 | 
			
		
	
		
			
				
					|  |  |  |         fi | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         echo "⚠️  Failed to get token (attempt $attempt). Response: $response" | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         if [ $attempt -eq $max_attempts ]; then | 
			
		
	
		
			
				
					|  |  |  |             echo "❌ Failed to get admin access token after $max_attempts attempts" | 
			
		
	
		
			
				
					|  |  |  |             echo "🔍 Checking Keycloak status..." | 
			
		
	
		
			
				
					|  |  |  |             curl -s "$KEYCLOAK_URL/realms/master" || echo "Keycloak master realm not accessible" | 
			
		
	
		
			
				
					|  |  |  |             return 1 | 
			
		
	
		
			
				
					|  |  |  |         fi | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         echo "⏳ Waiting 5 seconds before retry..." | 
			
		
	
		
			
				
					|  |  |  |         sleep 5 | 
			
		
	
		
			
				
					|  |  |  |         attempt=$((attempt + 1)) | 
			
		
	
		
			
				
					|  |  |  |     done | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # Function to check if realm exists | 
			
		
	
		
			
				
					|  |  |  | realm_exists() { | 
			
		
	
		
			
				
					|  |  |  |     local token=$1 | 
			
		
	
		
			
				
					|  |  |  |     curl -s -H "Authorization: Bearer $token" \ | 
			
		
	
		
			
				
					|  |  |  |         "$KEYCLOAK_URL/admin/realms/$REALM_NAME" \ | 
			
		
	
		
			
				
					|  |  |  |         -o /dev/null -w "%{http_code}" | grep -q "200" | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # Function to create realm | 
			
		
	
		
			
				
					|  |  |  | create_realm() { | 
			
		
	
		
			
				
					|  |  |  |     local token=$1 | 
			
		
	
		
			
				
					|  |  |  |     echo "📝 Creating realm: $REALM_NAME" | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local payload=$(jq -n \ | 
			
		
	
		
			
				
					|  |  |  |         --arg realm "$REALM_NAME" \ | 
			
		
	
		
			
				
					|  |  |  |         '{ | 
			
		
	
		
			
				
					|  |  |  |             "realm": $realm, | 
			
		
	
		
			
				
					|  |  |  |             "enabled": true, | 
			
		
	
		
			
				
					|  |  |  |             "displayName": "SeaweedFS Test Realm", | 
			
		
	
		
			
				
					|  |  |  |             "accessTokenLifespan": 3600, | 
			
		
	
		
			
				
					|  |  |  |             "sslRequired": "none" | 
			
		
	
		
			
				
					|  |  |  |         }') | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local http_code=$(curl -s -w "%{http_code}" -X POST "$KEYCLOAK_URL/admin/realms" \ | 
			
		
	
		
			
				
					|  |  |  |         -H "Authorization: Bearer $token" \ | 
			
		
	
		
			
				
					|  |  |  |         -H "Content-Type: application/json" \ | 
			
		
	
		
			
				
					|  |  |  |         -d "$payload" \ | 
			
		
	
		
			
				
					|  |  |  |         -o /tmp/realm_response.json) | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local response=$(cat /tmp/realm_response.json 2>/dev/null || echo "") | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     if [[ "$http_code" == "201" ]]; then | 
			
		
	
		
			
				
					|  |  |  |         echo "✅ Realm created successfully" | 
			
		
	
		
			
				
					|  |  |  |         return 0 | 
			
		
	
		
			
				
					|  |  |  |     else | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Realm creation failed with HTTP $http_code" | 
			
		
	
		
			
				
					|  |  |  |         echo "📋 Response: $response" | 
			
		
	
		
			
				
					|  |  |  |         return 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # Function to create client | 
			
		
	
		
			
				
					|  |  |  | create_client() { | 
			
		
	
		
			
				
					|  |  |  |     local token=$1 | 
			
		
	
		
			
				
					|  |  |  |     echo "📝 Creating client: $CLIENT_ID" | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local payload=$(jq -n \ | 
			
		
	
		
			
				
					|  |  |  |         --arg clientId "$CLIENT_ID" \ | 
			
		
	
		
			
				
					|  |  |  |         --arg secret "$CLIENT_SECRET" \ | 
			
		
	
		
			
				
					|  |  |  |         '{ | 
			
		
	
		
			
				
					|  |  |  |             "clientId": $clientId, | 
			
		
	
		
			
				
					|  |  |  |             "enabled": true, | 
			
		
	
		
			
				
					|  |  |  |             "publicClient": false, | 
			
		
	
		
			
				
					|  |  |  |             "secret": $secret, | 
			
		
	
		
			
				
					|  |  |  |             "directAccessGrantsEnabled": true, | 
			
		
	
		
			
				
					|  |  |  |             "serviceAccountsEnabled": true, | 
			
		
	
		
			
				
					|  |  |  |             "standardFlowEnabled": true, | 
			
		
	
		
			
				
					|  |  |  |             "implicitFlowEnabled": false, | 
			
		
	
		
			
				
					|  |  |  |             "redirectUris": ["*"], | 
			
		
	
		
			
				
					|  |  |  |             "webOrigins": ["*"] | 
			
		
	
		
			
				
					|  |  |  |         }') | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local http_code=$(curl -s -w "%{http_code}" -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/clients" \ | 
			
		
	
		
			
				
					|  |  |  |         -H "Authorization: Bearer $token" \ | 
			
		
	
		
			
				
					|  |  |  |         -H "Content-Type: application/json" \ | 
			
		
	
		
			
				
					|  |  |  |         -d "$payload" \ | 
			
		
	
		
			
				
					|  |  |  |         -o /tmp/client_response.json) | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local response=$(cat /tmp/client_response.json 2>/dev/null || echo "") | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     if [[ "$http_code" == "201" ]]; then | 
			
		
	
		
			
				
					|  |  |  |         echo "✅ Client created successfully" | 
			
		
	
		
			
				
					|  |  |  |         return 0 | 
			
		
	
		
			
				
					|  |  |  |     else | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Client creation failed with HTTP $http_code" | 
			
		
	
		
			
				
					|  |  |  |         echo "📋 Response: $response" | 
			
		
	
		
			
				
					|  |  |  |         return 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # Function to create role | 
			
		
	
		
			
				
					|  |  |  | create_role() { | 
			
		
	
		
			
				
					|  |  |  |     local token=$1 | 
			
		
	
		
			
				
					|  |  |  |     local role_name=$2 | 
			
		
	
		
			
				
					|  |  |  |     local role_description=$3 | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     echo "📝 Creating role: $role_name" | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local payload=$(jq -n \ | 
			
		
	
		
			
				
					|  |  |  |         --arg name "$role_name" \ | 
			
		
	
		
			
				
					|  |  |  |         --arg description "$role_description" \ | 
			
		
	
		
			
				
					|  |  |  |         '{ | 
			
		
	
		
			
				
					|  |  |  |             "name": $name, | 
			
		
	
		
			
				
					|  |  |  |             "description": $description | 
			
		
	
		
			
				
					|  |  |  |         }') | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local http_code=$(curl -s -w "%{http_code}" -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \ | 
			
		
	
		
			
				
					|  |  |  |         -H "Authorization: Bearer $token" \ | 
			
		
	
		
			
				
					|  |  |  |         -H "Content-Type: application/json" \ | 
			
		
	
		
			
				
					|  |  |  |         -d "$payload" \ | 
			
		
	
		
			
				
					|  |  |  |         -o /tmp/role_response_$role_name.json) | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local response=$(cat /tmp/role_response_$role_name.json 2>/dev/null || echo "") | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     if [[ "$http_code" == "201" ]]; then | 
			
		
	
		
			
				
					|  |  |  |         echo "✅ Role '$role_name' created successfully" | 
			
		
	
		
			
				
					|  |  |  |         return 0 | 
			
		
	
		
			
				
					|  |  |  |     else | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Role '$role_name' creation failed with HTTP $http_code" | 
			
		
	
		
			
				
					|  |  |  |         echo "📋 Response: $response" | 
			
		
	
		
			
				
					|  |  |  |         return 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # Function to create user | 
			
		
	
		
			
				
					|  |  |  | create_user() { | 
			
		
	
		
			
				
					|  |  |  |     local token=$1 | 
			
		
	
		
			
				
					|  |  |  |     local username=$2 | 
			
		
	
		
			
				
					|  |  |  |     local password=$3 | 
			
		
	
		
			
				
					|  |  |  |     local email=$4 | 
			
		
	
		
			
				
					|  |  |  |     local first_name=$5 | 
			
		
	
		
			
				
					|  |  |  |     local last_name=$6 | 
			
		
	
		
			
				
					|  |  |  |     local roles=$7 | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     echo "📝 Creating user: $username" | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Create user | 
			
		
	
		
			
				
					|  |  |  |     local user_payload=$(jq -n \ | 
			
		
	
		
			
				
					|  |  |  |         --arg username "$username" \ | 
			
		
	
		
			
				
					|  |  |  |         --arg email "$email" \ | 
			
		
	
		
			
				
					|  |  |  |         --arg firstName "$first_name" \ | 
			
		
	
		
			
				
					|  |  |  |         --arg lastName "$last_name" \ | 
			
		
	
		
			
				
					|  |  |  |         --arg password "$password" \ | 
			
		
	
		
			
				
					|  |  |  |         '{ | 
			
		
	
		
			
				
					|  |  |  |             "username": $username, | 
			
		
	
		
			
				
					|  |  |  |             "email": $email, | 
			
		
	
		
			
				
					|  |  |  |             "firstName": $firstName, | 
			
		
	
		
			
				
					|  |  |  |             "lastName": $lastName, | 
			
		
	
		
			
				
					|  |  |  |             "enabled": true, | 
			
		
	
		
			
				
					|  |  |  |             "emailVerified": true, | 
			
		
	
		
			
				
					|  |  |  |             "credentials": [{ | 
			
		
	
		
			
				
					|  |  |  |                 "type": "password", | 
			
		
	
		
			
				
					|  |  |  |                 "value": $password, | 
			
		
	
		
			
				
					|  |  |  |                 "temporary": false | 
			
		
	
		
			
				
					|  |  |  |             }] | 
			
		
	
		
			
				
					|  |  |  |         }') | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local http_code=$(curl -s -w "%{http_code}" -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users" \ | 
			
		
	
		
			
				
					|  |  |  |         -H "Authorization: Bearer $token" \ | 
			
		
	
		
			
				
					|  |  |  |         -H "Content-Type: application/json" \ | 
			
		
	
		
			
				
					|  |  |  |         -d "$user_payload" \ | 
			
		
	
		
			
				
					|  |  |  |         -o /tmp/user_response_$username.json) | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     local user_response=$(cat /tmp/user_response_$username.json 2>/dev/null || echo "") | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     if [[ "$http_code" == "201" ]]; then | 
			
		
	
		
			
				
					|  |  |  |         echo "✅ User '$username' created successfully" | 
			
		
	
		
			
				
					|  |  |  |     else | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ User '$username' creation failed with HTTP $http_code" | 
			
		
	
		
			
				
					|  |  |  |         echo "📋 Response: $user_response" | 
			
		
	
		
			
				
					|  |  |  |         return 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Get user ID | 
			
		
	
		
			
				
					|  |  |  |     local user_id=$(curl -s -H "Authorization: Bearer $token" \ | 
			
		
	
		
			
				
					|  |  |  |         "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users?username=$username" | \ | 
			
		
	
		
			
				
					|  |  |  |         jq -r '.[0].id') | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Assign roles | 
			
		
	
		
			
				
					|  |  |  |     if [ -n "$roles" ]; then | 
			
		
	
		
			
				
					|  |  |  |         echo "📝 Assigning roles to $username: $roles" | 
			
		
	
		
			
				
					|  |  |  |         IFS=',' read -ra ROLE_ARRAY <<< "$roles" | 
			
		
	
		
			
				
					|  |  |  |         for role in "${ROLE_ARRAY[@]}"; do | 
			
		
	
		
			
				
					|  |  |  |             # Get role representation | 
			
		
	
		
			
				
					|  |  |  |             local role_rep=$(curl -s -H "Authorization: Bearer $token" \ | 
			
		
	
		
			
				
					|  |  |  |                 "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles/$role") | 
			
		
	
		
			
				
					|  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |             # Assign role to user | 
			
		
	
		
			
				
					|  |  |  |             curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$user_id/role-mappings/realm" \ | 
			
		
	
		
			
				
					|  |  |  |                 -H "Authorization: Bearer $token" \ | 
			
		
	
		
			
				
					|  |  |  |                 -H "Content-Type: application/json" \ | 
			
		
	
		
			
				
					|  |  |  |                 -d "[$role_rep]" | 
			
		
	
		
			
				
					|  |  |  |         done | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # Main setup process | 
			
		
	
		
			
				
					|  |  |  | main() { | 
			
		
	
		
			
				
					|  |  |  |     echo "🚀 Starting Keycloak setup..." | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Wait for Keycloak to be ready with better health checking | 
			
		
	
		
			
				
					|  |  |  |     echo "⏳ Waiting for Keycloak to be ready..." | 
			
		
	
		
			
				
					|  |  |  |     timeout 300 bash -c ' | 
			
		
	
		
			
				
					|  |  |  |         while true; do | 
			
		
	
		
			
				
					|  |  |  |             # Try health endpoint first (if available) | 
			
		
	
		
			
				
					|  |  |  |             if curl -s http://localhost:8080/health/ready > /dev/null 2>&1; then | 
			
		
	
		
			
				
					|  |  |  |                 echo "✅ Keycloak health check passed" | 
			
		
	
		
			
				
					|  |  |  |                 break | 
			
		
	
		
			
				
					|  |  |  |             fi | 
			
		
	
		
			
				
					|  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |             # Fallback to master realm check | 
			
		
	
		
			
				
					|  |  |  |             if curl -s $KEYCLOAK_URL/realms/master > /dev/null 2>&1; then | 
			
		
	
		
			
				
					|  |  |  |                 echo "✅ Keycloak master realm accessible" | 
			
		
	
		
			
				
					|  |  |  |                 break | 
			
		
	
		
			
				
					|  |  |  |             fi | 
			
		
	
		
			
				
					|  |  |  |              | 
			
		
	
		
			
				
					|  |  |  |             echo "Still waiting for Keycloak..." | 
			
		
	
		
			
				
					|  |  |  |             sleep 5 | 
			
		
	
		
			
				
					|  |  |  |         done | 
			
		
	
		
			
				
					|  |  |  |     ' || { | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Keycloak is not ready after 300 seconds" | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Additional wait for admin user to be fully set up | 
			
		
	
		
			
				
					|  |  |  |     echo "⏳ Waiting for admin user to be fully initialized..." | 
			
		
	
		
			
				
					|  |  |  |     sleep 10 | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Get admin token | 
			
		
	
		
			
				
					|  |  |  |     ADMIN_TOKEN=$(get_admin_token) | 
			
		
	
		
			
				
					|  |  |  |     if [ -z "$ADMIN_TOKEN" ] || [ "$ADMIN_TOKEN" = "null" ]; then | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Failed to get admin access token" | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Create realm if it doesn't exist | 
			
		
	
		
			
				
					|  |  |  |     if ! realm_exists "$ADMIN_TOKEN"; then | 
			
		
	
		
			
				
					|  |  |  |         if ! create_realm "$ADMIN_TOKEN"; then | 
			
		
	
		
			
				
					|  |  |  |             echo "❌ Failed to create realm $REALM_NAME" | 
			
		
	
		
			
				
					|  |  |  |             exit 1 | 
			
		
	
		
			
				
					|  |  |  |         fi | 
			
		
	
		
			
				
					|  |  |  |         sleep 2 | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         # Wait for realm to be fully available | 
			
		
	
		
			
				
					|  |  |  |         echo "⏳ Waiting for realm to be fully initialized..." | 
			
		
	
		
			
				
					|  |  |  |         timeout 60 bash -c " | 
			
		
	
		
			
				
					|  |  |  |             while ! curl -fs $KEYCLOAK_URL/realms/$REALM_NAME/.well-known/openid-configuration >/dev/null 2>&1; do | 
			
		
	
		
			
				
					|  |  |  |                 echo '   ... waiting for realm endpoint' | 
			
		
	
		
			
				
					|  |  |  |                 sleep 3 | 
			
		
	
		
			
				
					|  |  |  |             done | 
			
		
	
		
			
				
					|  |  |  |         " || { | 
			
		
	
		
			
				
					|  |  |  |             echo "❌ Realm $REALM_NAME not accessible after creation" | 
			
		
	
		
			
				
					|  |  |  |             exit 1 | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         echo "✅ Realm is now accessible" | 
			
		
	
		
			
				
					|  |  |  |     else | 
			
		
	
		
			
				
					|  |  |  |         echo "✅ Realm $REALM_NAME already exists" | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Create client | 
			
		
	
		
			
				
					|  |  |  |     if ! create_client "$ADMIN_TOKEN"; then | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Failed to create client $CLIENT_ID" | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |     sleep 1 | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Create roles | 
			
		
	
		
			
				
					|  |  |  |     if ! create_role "$ADMIN_TOKEN" "s3-admin" "SeaweedFS S3 Administrator"; then | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Failed to create s3-admin role" | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |     if ! create_role "$ADMIN_TOKEN" "s3-read-only" "SeaweedFS S3 Read-Only User"; then | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Failed to create s3-read-only role" | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |     if ! create_role "$ADMIN_TOKEN" "s3-write-only" "SeaweedFS S3 Write-Only User"; then | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Failed to create s3-write-only role" | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |     if ! create_role "$ADMIN_TOKEN" "s3-read-write" "SeaweedFS S3 Read-Write User"; then | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Failed to create s3-read-write role" | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |     sleep 1 | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Create test users | 
			
		
	
		
			
				
					|  |  |  |     if ! create_user "$ADMIN_TOKEN" "admin-user" "admin123" "admin@seaweedfs.test" "Admin" "User" "s3-admin"; then | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Failed to create admin-user" | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |     if ! create_user "$ADMIN_TOKEN" "read-user" "read123" "read@seaweedfs.test" "Read" "User" "s3-read-only"; then | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Failed to create read-user"  | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |     if ! create_user "$ADMIN_TOKEN" "write-user" "write123" "write@seaweedfs.test" "Write" "User" "s3-write-only"; then | 
			
		
	
		
			
				
					|  |  |  |         echo "❌ Failed to create write-user" | 
			
		
	
		
			
				
					|  |  |  |         exit 1 | 
			
		
	
		
			
				
					|  |  |  |     fi | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     echo "✅ Keycloak setup completed successfully!" | 
			
		
	
		
			
				
					|  |  |  |     echo "🔗 Realm: $KEYCLOAK_URL/realms/$REALM_NAME" | 
			
		
	
		
			
				
					|  |  |  |     echo "👥 Test users created:" | 
			
		
	
		
			
				
					|  |  |  |     echo "   - admin-user (password: admin123) - s3-admin role" | 
			
		
	
		
			
				
					|  |  |  |     echo "   - read-user (password: read123) - s3-read-only role" | 
			
		
	
		
			
				
					|  |  |  |     echo "   - write-user (password: write123) - s3-write-only role" | 
			
		
	
		
			
				
					|  |  |  |     echo "🔑 Client: $CLIENT_ID (secret: $CLIENT_SECRET)" | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     # Cleanup temporary files | 
			
		
	
		
			
				
					|  |  |  |     rm -f /tmp/realm_response.json /tmp/client_response.json /tmp/role_response_*.json /tmp/user_response_*.json | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | # Run main function | 
			
		
	
		
			
				
					|  |  |  | main "$@" |