tests
This commit is contained in:
342
scripts/setup.sh
Executable file
342
scripts/setup.sh
Executable file
@@ -0,0 +1,342 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Ginxsom Interactive Setup Wizard
|
||||
# Creates signed configuration events for first-run server setup
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
CONFIG_PATH="${1:-}"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||||
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies() {
|
||||
log_info "Checking dependencies..."
|
||||
local missing_deps=()
|
||||
|
||||
for cmd in nak jq; do
|
||||
if ! command -v $cmd &> /dev/null; then
|
||||
missing_deps+=("$cmd")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#missing_deps[@]} -ne 0 ]; then
|
||||
log_error "Missing dependencies: ${missing_deps[*]}"
|
||||
echo ""
|
||||
echo "Please install the missing dependencies:"
|
||||
echo "- nak: https://github.com/fiatjaf/nak"
|
||||
echo "- jq: sudo apt install jq (or equivalent for your system)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "All dependencies found"
|
||||
}
|
||||
|
||||
# Validate private key format
|
||||
validate_private_key() {
|
||||
local key="$1"
|
||||
if [[ ! "$key" =~ ^[a-fA-F0-9]{64}$ ]]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Setup key pairs with user choice
|
||||
setup_keys() {
|
||||
log_info "Setting up cryptographic key pairs..."
|
||||
echo ""
|
||||
echo "=== Admin Key Setup ==="
|
||||
echo "Choose an option for your admin private key:"
|
||||
echo "1. Generate a new random admin key"
|
||||
echo "2. Use an existing admin private key"
|
||||
echo ""
|
||||
|
||||
while true; do
|
||||
echo -n "Choice (1/2): "
|
||||
read -r ADMIN_KEY_CHOICE
|
||||
case "$ADMIN_KEY_CHOICE" in
|
||||
1)
|
||||
log_info "Generating new admin key pair..."
|
||||
ADMIN_PRIVKEY=$(nak key generate)
|
||||
ADMIN_PUBKEY=$(echo "$ADMIN_PRIVKEY" | nak key public)
|
||||
log_success "New admin key pair generated"
|
||||
break
|
||||
;;
|
||||
2)
|
||||
echo -n "Enter your admin private key (64 hex characters): "
|
||||
read -r ADMIN_PRIVKEY
|
||||
if validate_private_key "$ADMIN_PRIVKEY"; then
|
||||
ADMIN_PUBKEY=$(echo "$ADMIN_PRIVKEY" | nak key public)
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Admin private key validated"
|
||||
break
|
||||
else
|
||||
log_error "Invalid private key format or nak error"
|
||||
fi
|
||||
else
|
||||
log_error "Invalid private key format (must be 64 hex characters)"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log_error "Please choose 1 or 2"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== Server Key Setup ==="
|
||||
echo "Choose an option for your Ginxsom server private key:"
|
||||
echo "1. Generate a new random server key"
|
||||
echo "2. Use an existing server private key"
|
||||
echo ""
|
||||
|
||||
while true; do
|
||||
echo -n "Choice (1/2): "
|
||||
read -r SERVER_KEY_CHOICE
|
||||
case "$SERVER_KEY_CHOICE" in
|
||||
1)
|
||||
log_info "Generating new server key pair..."
|
||||
SERVER_PRIVKEY=$(nak key generate)
|
||||
SERVER_PUBKEY=$(echo "$SERVER_PRIVKEY" | nak key public)
|
||||
log_success "New server key pair generated"
|
||||
break
|
||||
;;
|
||||
2)
|
||||
echo -n "Enter your server private key (64 hex characters): "
|
||||
read -r SERVER_PRIVKEY
|
||||
if validate_private_key "$SERVER_PRIVKEY"; then
|
||||
SERVER_PUBKEY=$(echo "$SERVER_PRIVKEY" | nak key public)
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Server private key validated"
|
||||
break
|
||||
else
|
||||
log_error "Invalid private key format or nak error"
|
||||
fi
|
||||
else
|
||||
log_error "Invalid private key format (must be 64 hex characters)"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log_error "Please choose 1 or 2"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
log_success "Key pairs configured:"
|
||||
echo " Admin Public Key: $ADMIN_PUBKEY"
|
||||
echo " Server Public Key: $SERVER_PUBKEY"
|
||||
|
||||
# Save keys securely
|
||||
echo "ADMIN_PRIVKEY='$ADMIN_PRIVKEY'" > "$PROJECT_ROOT/.admin_keys"
|
||||
echo "ADMIN_PUBKEY='$ADMIN_PUBKEY'" >> "$PROJECT_ROOT/.admin_keys"
|
||||
echo "SERVER_PRIVKEY='$SERVER_PRIVKEY'" >> "$PROJECT_ROOT/.admin_keys"
|
||||
echo "SERVER_PUBKEY='$SERVER_PUBKEY'" >> "$PROJECT_ROOT/.admin_keys"
|
||||
chmod 600 "$PROJECT_ROOT/.admin_keys"
|
||||
|
||||
log_warning "Keys saved to $PROJECT_ROOT/.admin_keys (keep this file secure!)"
|
||||
}
|
||||
|
||||
# Collect server configuration
|
||||
collect_configuration() {
|
||||
log_info "Collecting server configuration..."
|
||||
|
||||
echo ""
|
||||
echo "=== Server Configuration Setup ==="
|
||||
|
||||
# CDN Origin
|
||||
echo -n "CDN Origin URL (default: http://localhost:9001): "
|
||||
read -r CDN_ORIGIN
|
||||
CDN_ORIGIN="${CDN_ORIGIN:-http://localhost:9001}"
|
||||
|
||||
# Max file size
|
||||
echo -n "Maximum file size in MB (default: 100): "
|
||||
read -r MAX_SIZE_MB
|
||||
MAX_SIZE_MB="${MAX_SIZE_MB:-100}"
|
||||
MAX_FILE_SIZE=$((MAX_SIZE_MB * 1024 * 1024))
|
||||
|
||||
# NIP-94 support
|
||||
echo -n "Enable NIP-94 metadata (y/n, default: y): "
|
||||
read -r ENABLE_NIP94
|
||||
case "$ENABLE_NIP94" in
|
||||
[Nn]*) NIP94_ENABLED="false" ;;
|
||||
*) NIP94_ENABLED="true" ;;
|
||||
esac
|
||||
|
||||
# Authentication rules
|
||||
echo -n "Enable authentication rules system (y/n, default: n): "
|
||||
read -r ENABLE_AUTH_RULES
|
||||
case "$ENABLE_AUTH_RULES" in
|
||||
[Yy]*) AUTH_RULES_ENABLED="true" ;;
|
||||
*) AUTH_RULES_ENABLED="false" ;;
|
||||
esac
|
||||
|
||||
# Cache TTL
|
||||
echo -n "Authentication cache TTL in seconds (default: 300): "
|
||||
read -r CACHE_TTL
|
||||
CACHE_TTL="${CACHE_TTL:-300}"
|
||||
|
||||
echo ""
|
||||
log_success "Configuration collected:"
|
||||
echo " CDN Origin: $CDN_ORIGIN"
|
||||
echo " Max File Size: ${MAX_SIZE_MB}MB"
|
||||
echo " NIP-94 Enabled: $NIP94_ENABLED"
|
||||
echo " Auth Rules Enabled: $AUTH_RULES_ENABLED"
|
||||
echo " Cache TTL: ${CACHE_TTL}s"
|
||||
}
|
||||
|
||||
# Create configuration event
|
||||
create_config_event() {
|
||||
log_info "Creating signed configuration event..."
|
||||
|
||||
local expiration=$(($(date +%s) + 31536000)) # 1 year from now
|
||||
|
||||
# Create configuration event with all settings
|
||||
CONFIG_EVENT=$(nak event -k 33333 -c "Ginxsom server configuration" \
|
||||
--tag server_privkey="$SERVER_PRIVKEY" \
|
||||
--tag cdn_origin="$CDN_ORIGIN" \
|
||||
--tag max_file_size="$MAX_FILE_SIZE" \
|
||||
--tag nip94_enabled="$NIP94_ENABLED" \
|
||||
--tag auth_rules_enabled="$AUTH_RULES_ENABLED" \
|
||||
--tag auth_cache_ttl="$CACHE_TTL" \
|
||||
--tag expiration="$expiration" \
|
||||
--sec "$ADMIN_PRIVKEY")
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
log_error "Failed to create configuration event"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "Configuration event created and signed"
|
||||
}
|
||||
|
||||
# Save configuration file
|
||||
save_config_file() {
|
||||
local config_file="$1"
|
||||
|
||||
log_info "Saving configuration to $config_file"
|
||||
|
||||
# Create directory if it doesn't exist
|
||||
local config_dir=$(dirname "$config_file")
|
||||
mkdir -p "$config_dir"
|
||||
|
||||
# Save configuration event to file
|
||||
echo "$CONFIG_EVENT" | jq . > "$config_file"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
log_error "Failed to save configuration file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
chmod 600 "$config_file"
|
||||
log_success "Configuration saved to $config_file"
|
||||
}
|
||||
|
||||
# Setup database
|
||||
setup_database() {
|
||||
log_info "Setting up database configuration..."
|
||||
|
||||
local db_path="$PROJECT_ROOT/db/ginxsom.db"
|
||||
|
||||
if [ ! -f "$db_path" ]; then
|
||||
log_warning "Database not found at $db_path"
|
||||
log_warning "Please ensure the database is initialized before starting the server"
|
||||
return
|
||||
fi
|
||||
|
||||
# Insert admin configuration into database
|
||||
sqlite3 "$db_path" << EOF
|
||||
INSERT OR REPLACE INTO server_config (key, value, description) VALUES
|
||||
('admin_pubkey', '$ADMIN_PUBKEY', 'Admin public key from setup wizard'),
|
||||
('admin_enabled', 'true', 'Enable admin interface');
|
||||
EOF
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Database configuration updated"
|
||||
else
|
||||
log_warning "Failed to update database (this is OK if database doesn't exist yet)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Display setup summary
|
||||
show_setup_summary() {
|
||||
echo ""
|
||||
echo "================================================================="
|
||||
echo " GINXSOM SETUP COMPLETE"
|
||||
echo "================================================================="
|
||||
echo ""
|
||||
log_success "Configuration file created: $CONFIG_PATH"
|
||||
log_success "Admin keys saved: $PROJECT_ROOT/.admin_keys"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo "1. Start the Ginxsom server:"
|
||||
echo " cd $PROJECT_ROOT"
|
||||
echo " make run"
|
||||
echo ""
|
||||
echo "2. Test admin API access:"
|
||||
echo " source .admin_keys"
|
||||
echo " ./scripts/test_admin.sh"
|
||||
echo ""
|
||||
echo "3. Access web admin (when implemented):"
|
||||
echo " http://localhost:9001/admin"
|
||||
echo ""
|
||||
log_warning "Keep the .admin_keys file secure - it contains your admin private key!"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main setup workflow
|
||||
main() {
|
||||
echo "=== Ginxsom Interactive Setup Wizard ==="
|
||||
echo ""
|
||||
|
||||
# Validate config path
|
||||
if [ -z "$CONFIG_PATH" ]; then
|
||||
# Determine default config path
|
||||
if [ -n "$XDG_CONFIG_HOME" ]; then
|
||||
CONFIG_PATH="$XDG_CONFIG_HOME/ginxsom/ginxsom_config_event.json"
|
||||
else
|
||||
CONFIG_PATH="$HOME/.config/ginxsom/ginxsom_config_event.json"
|
||||
fi
|
||||
fi
|
||||
|
||||
log_info "Configuration will be saved to: $CONFIG_PATH"
|
||||
|
||||
# Check if config already exists
|
||||
if [ -f "$CONFIG_PATH" ]; then
|
||||
log_warning "Configuration file already exists at $CONFIG_PATH"
|
||||
echo -n "Overwrite existing configuration? (y/n): "
|
||||
read -r OVERWRITE
|
||||
case "$OVERWRITE" in
|
||||
[Yy]*) ;;
|
||||
*) log_info "Setup cancelled"; exit 0 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Run setup steps
|
||||
check_dependencies
|
||||
setup_keys
|
||||
collect_configuration
|
||||
create_config_event
|
||||
save_config_file "$CONFIG_PATH"
|
||||
setup_database
|
||||
show_setup_summary
|
||||
}
|
||||
|
||||
# Allow sourcing for testing individual functions
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
main "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user