bash htaccess file management script

OK, so its not too hard to run htpasswd manually, but if you spend a lot of time in your job doing it, it's nice to have a tool to do it more efficiently. This is a menu driven script, which will make a backup of your file, and suggest a random password, which you can choose to use or not.

As always, don't trust everything you read on the internet, and test before you use in anger.

#!/bin/bash

# Configuration
HTACCESS_FILE_DEFAULT="/etc/nginx/htpasswd-developers

# Function to display a list of users
display_users() {
  echo "--- Existing Users ---"
  # Grep for lines that don't start with # and aren't empty
  # Then use cut to show only the username before the colon, and number the lines
  grep -vE '^(#|$)' "$HTACCESS_FILE" | cut -d':' -f1 | cat -n
  echo "----------------------"
}

# Function to perform a backup
backup_file() {
  if [ -f "$HTACCESS_FILE" ]; then
    cp "$HTACCESS_FILE" "$HTACCESS_FILE.bak"
    echo "Backup created at $HTACCESS_FILE.bak"
  else
    echo "No .htpasswd file to back up."
  fi
}

# Function to generate a random password
generate_password() {
    tr -cd '[:alnum:]' < /dev/urandom | head -c 12
}

# --- Main Script ---

# Select the .htpasswd file. Suggest the default value, but allow user to type another name
read -p "Enter .htpasswd file (default: $HTACCESS_FILE_DEFAULT): " HTACCESS_FILE
HTACCESS_FILE=${HTACCESS_FILE:-$HTACCESS_FILE_DEFAULT}

# Ensure the file exists, exit if not
if [ ! -f "$HTACCESS_FILE" ]; then
  echo "Password file doesn't exist"
  exit 1
fi

# Main menu loop
while true; do
  echo "Do you want to:"
  echo "a) Add a user"
  echo "r) Remove a user"
  echo "u) Update a user's password"
  echo "l) List users"
  echo "q) Quit"
  read -p "Enter your choice: " choice

  case "$choice" in
    a)
      read -p "Enter username to add: " username
      # Check if the username already exists
      if grep -q "^$username:" "$HTACCESS_FILE"; then
        echo "Error: User '$username' already exists. Use the 'u' option to update their password."
      else
        suggested_password=$(generate_password)
        read -p "Enter password for '$username' (or press Enter to use suggested: $suggested_password): " password
        password=${password:-$suggested_password}
        
        backup_file
        htpasswd -b "$HTACCESS_FILE" "$username" "$password"
        echo "User '$username' added."
      fi
      ;;
    r)
      display_users
      read -p "Enter reference number of user to remove: " ref
      # Use grep and sed to find the line number and get the username
      username_to_remove=$(grep -vE '^(#|$)' "$HTACCESS_FILE" | sed -n "${ref}p" | cut -d':' -f1)

      if [ -z "$username_to_remove" ]; then
        echo "Invalid reference number."
      else
        backup_file
        # Create a temp file without the user and then replace the original
        grep -v "^$username_to_remove:" "$HTACCESS_FILE" > "$HTACCESS_FILE.tmp" && mv "$HTACCESS_FILE.tmp" "$HTACCESS_FILE"
        echo "User '$username_to_remove' removed."
      fi
      ;;
    u)
      display_users
      read -p "Enter reference number of user to update: " ref
      username_to_update=$(grep -vE '^(#|$)' "$HTACCESS_FILE" | sed -n "${ref}p" | cut -d':' -f1)

      if [ -z "$username_to_update" ]; then
        echo "Invalid reference number."
      else
        suggested_password=$(generate_password)
        read -p "Enter new password for '$username_to_update' (or press Enter to use suggested: $suggested_password): " password
        password=${password:-$suggested_password}

        backup_file
        htpasswd -b "$HTACCESS_FILE" "$username_to_update" "$password"
        echo "Password for user '$username_to_update' updated."
      fi
      ;;
    l)
      display_users
      ;;
    q)
      echo "Exiting."
      exit 0
      ;;
    *)
      echo "Invalid option. Please try again."
      ;;
  esac

  echo ""
done

Leave a Comment