Last active
December 17, 2025 04:53
-
-
Save NetPenguins/277babc21a74fcccc083e00174569fb6 to your computer and use it in GitHub Desktop.
Admin script for easily switching between impersonated users in Ludus
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| ######################################################################### | |
| # ludus-impersonator.sh | |
| # | |
| # A lightweight Bash tool for safely impersonating Ludus users. | |
| # Designed to be sourced into your shell to temporarily override the | |
| # `ludus` command for testing, troubleshooting, or administrative tasks. | |
| # | |
| # Features: | |
| # - Interactive menu to select and impersonate any Ludus user | |
| # - Automatic detection of user IDs and admin status | |
| # - Safe reset function to restore original Ludus behavior | |
| # - Status display to show current impersonation | |
| # | |
| # Usage: | |
| # source ludus-impersonator.sh | |
| # | |
| # Commands (aliases): | |
| # limpersonate - Launch the interactive user impersonation menu | |
| # lreset - Reset `ludus` command and clear impersonation | |
| # lstatus - Show current impersonation status | |
| # lhelp - Show commands | |
| # | |
| # Notes: | |
| # - Must be sourced, not executed directly | |
| # - Works in Bash and Zsh | |
| # | |
| # Author: NetPenguin | |
| # Version: 1.0 | |
| ######################################################################### | |
| # Colors | |
| R='\033[0;31m' G='\033[0;32m' Y='\033[1;33m' B='\033[0;34m' C='\033[0;36m' N='\033[0m' | |
| # Simple sourcing check that works everywhere | |
| case $0 in | |
| *ludus-impersonator.sh) | |
| echo -e "${R}Must be sourced: source ludus-impersonator.sh${N}" | |
| return 1 2>/dev/null || exit 1 | |
| ;; | |
| esac | |
| if [[ $- == *i* ]]; then | |
| # interactive shell: maybe hint the user | |
| echo -e "${Y}Ludus Impersonator loaded. Type lhelp for commands.${N}" | |
| fi | |
| # Reset function | |
| reset_ludus() { | |
| if declare -f ludus >/dev/null 2>&1; then | |
| unset -f ludus | |
| fi | |
| unset LUDUS_USER ORIGINAL_LUDUS 2>/dev/null | |
| echo -e "${G}✓ Reset ludus command${N}" | |
| } | |
| banner() { | |
| echo -e "\033[91m" | |
| cat << 'EOF' | |
| ⠀⢀⣴⣶⠿⠟⠻⠿⢷⣦⣄⠀ | |
| ⠀⠀⠀⠀⣾⠏⠀⠀⣠⣤⣤⣤⣬⣿⣷⣄ | |
| ⠀⢀⣀⣸⡿⠀⠀⣼⡟⠁⠀⠀⠀⠀⠀⠙⣷ | |
| ⢸⡟⠉⣽⡇⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⢀⣿ | |
| ⣾⠇⠀⣿⡇⠀⠀⠘⠿⢶⣶⣤⣤⣶⡶⣿⠋ | |
| ⣿⠂⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿ | |
| ⠘⠻⠷⢿⡇⠀⠀⠀⣴⣶⣶⠀ ⢸⡟⠀ | |
| ⠀ ⠀⠀⢸⣇⠀⠀⠀⣿⡇⣿⡄⠀⢀⣿⠇⠀ | |
| ⠀ ⠀⠀⠘⣿⣤⣤⣴⡿⠃⠙⠛⠛⠛⠋⠀⠀ | |
| EOF | |
| echo -e "\033[0m" | |
| echo -e " Ludus Impersonator" | |
| echo | |
| echo -e "\033[2;37m ⁿᵉᵗᵖᵉⁿᵍᵘᶦⁿ\033[0m" | |
| echo | |
| } | |
| # Status | |
| show_status() { | |
| if [[ -n "$LUDUS_USER" ]]; then | |
| echo -e "${C}🎭 Impersonating: $LUDUS_USER${N}" | |
| else | |
| echo -e "${B}ℹ No impersonation active${N}" | |
| fi | |
| } | |
| # Main | |
| impersonate_user() { | |
| # Check if jq is installed, offer user install run | |
| if ! command -v jq >/dev/null 2>&1; then | |
| echo "${R}[!] jq is not installed.${N}" | |
| print -n "Would you like to run 'sudo apt install -y jq' now? (y/n): " | |
| read choice | |
| case "$choice" in | |
| [Yy]* ) sudo apt install -y jq ;; | |
| * ) echo "${Y}Skipping installation. jq is required for this script.${N}"; return 1 ;; | |
| esac | |
| fi | |
| banner | |
| # Ensure we're not in debug mode | |
| set +x 2>/dev/null | |
| # Check ludus exists | |
| if ! command -v ludus >/dev/null 2>&1; then | |
| echo -e "${R}✗ ludus command not found${N}" | |
| return 1 | |
| fi | |
| # Get users (use original command if set) | |
| local cmd="${ORIGINAL_LUDUS:-ludus}" | |
| local json | |
| json=$($cmd user list all --json 2>/dev/null) | |
| if [[ $? -ne 0 ]]; then | |
| echo -e "${R}✗ Failed to get user list${N}" | |
| return 1 | |
| fi | |
| # Create temp file | |
| local temp_file="/tmp/ludus_users_$$_$(date +%s)" | |
| # Extract user data to temp file | |
| echo "$json" | jq -r '.[] | "\(.name)|\(.userID)|\(.isAdmin)"' > "$temp_file" 2>/dev/null | |
| if [[ $? -ne 0 ]]; then | |
| echo -e "${R}✗ Failed to parse user data${N}" | |
| rm -f "$temp_file" 2>/dev/null | |
| return 1 | |
| fi | |
| # Count valid entries | |
| local user_count=0 | |
| while IFS= read -r line || [[ -n "$line" ]]; do | |
| if [[ -n "$line" ]]; then | |
| user_count=$((user_count + 1)) | |
| fi | |
| done < "$temp_file" | |
| if [[ $user_count -eq 0 ]]; then | |
| rm -f "$temp_file" 2>/dev/null | |
| echo -e "${R}✗ No users found${N}" | |
| return 1 | |
| fi | |
| # Display menu | |
| echo -e "${C}Available Users:${N}" | |
| echo "┌─────┬──────────────────────┬──────────────────────┬───────┐" | |
| echo "│ # │ Name │ User ID │ Admin │" | |
| echo "├─────┼──────────────────────┼──────────────────────┼───────┤" | |
| local display_num=1 | |
| while IFS= read -r line || [[ -n "$line" ]]; do | |
| if [[ -n "$line" ]]; then | |
| IFS='|' read -r name userid admin <<< "$line" | |
| if [[ "$admin" == "true" ]]; then | |
| admin_icon="✅" | |
| else | |
| admin_icon="❌" | |
| fi | |
| printf "│ %-3d │ %-20s │ %-20s │ %s │\n" $display_num "$name" "$userid" "$admin_icon" | |
| display_num=$((display_num + 1)) | |
| fi | |
| done < "$temp_file" | |
| echo "└─────┴──────────────────────┴──────────────────────┴───────┘" | |
| # Get selection | |
| while true; do | |
| echo -n -e "${Y}Select user (1-$user_count) or 'q' to quit: ${N}" | |
| read -r choice | |
| if [[ "$choice" == "q" ]]; then | |
| rm -f "$temp_file" 2>/dev/null | |
| echo -e "${B}Cancelled${N}" | |
| return 0 | |
| fi | |
| if [[ "$choice" =~ ^[0-9]+$ ]] && [[ "$choice" -ge 1 ]] && [[ "$choice" -le $user_count ]]; then | |
| break | |
| fi | |
| echo -e "${R}✗ Invalid selection${N}" | |
| done | |
| # Find the selected user | |
| local count=0 | |
| local selected_user="" | |
| while IFS= read -r line || [[ -n "$line" ]]; do | |
| if [[ -n "$line" ]]; then | |
| count=$((count + 1)) | |
| if [[ $count -eq $choice ]]; then | |
| selected_user="$line" | |
| break | |
| fi | |
| fi | |
| done < "$temp_file" | |
| rm -f "$temp_file" 2>/dev/null | |
| # Setup impersonation | |
| IFS='|' read -r name userid admin <<< "$selected_user" | |
| if [[ -z "$ORIGINAL_LUDUS" ]]; then | |
| ORIGINAL_LUDUS=$(command -v ludus) | |
| fi | |
| export LUDUS_USER="$name ($userid)" | |
| export ORIGINAL_LUDUS | |
| # Override ludus command with function | |
| eval "ludus() { \"$ORIGINAL_LUDUS\" --user \"$userid\" \"\$@\"; }" | |
| echo "" | |
| echo -e "${G}🎭 Now impersonating: ${N}$name ($userid)" | |
| if [[ "$admin" == "true" ]]; then | |
| echo -e "${G}Admin: Yes${N}" | |
| else | |
| echo -e "${Y}Admin: No${N}" | |
| fi | |
| echo -e "${Y}Use 'lreset' to reset${N}" | |
| echo "" | |
| } | |
| # Set up aliases safely | |
| if command -v alias >/dev/null 2>&1; then | |
| alias limpersonate=impersonate_user 2>/dev/null | |
| alias lreset=reset_ludus 2>/dev/null | |
| alias lstatus=show_status 2>/dev/null | |
| fi | |
| lhelp() { | |
| echo "" | |
| echo -e "${G}╔═══════════════════════════════════════════════════════════════╗${N}" | |
| echo -e "${G}║ ${C}🎭 Ludus Impersonator ඞ${G} ║${N}" | |
| echo -e "${G}╚═══════════════════════════════════════════════════════════════╝${N}" | |
| echo -e "${Y}Commands:${N}" | |
| echo -e " ${C}limpersonate${N} - Start user impersonation menu" | |
| echo -e " ${C}lreset${N} - Reset to original ludus command" | |
| echo -e " ${C}lstatus${N} - Show current impersonation status" | |
| echo -e " ${C}lhelp${N} - Show this dialog" | |
| echo "" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment