Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔧 feat(casaos-update-database-password): Add script to update database password #21

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions casaos-update-database-password/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Why?

This script helps you update the root/admin password for running database containers (PostgreSQL, MySQL, or MariaDB).

## Features

- Automatically detects running database containers
- Supports PostgreSQL, MySQL, and MariaDB
- Interactive container selection
- Secure password input

## How to use?

```bash
bash -c "$(wget -qLO - https://raw.githubusercontent.com/bigbeartechworld/big-bear-scripts/master/casaos-update-database-password/run.sh)"
```
155 changes: 155 additions & 0 deletions casaos-update-database-password/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#!/usr/bin/env bash


# Set text colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}Please run as root (use sudo)${NC}"
exit 1
fi

# Function to print header
print_header() {
echo "================================================"
echo "$1"
echo "================================================"
echo
}

# Function to display menu
show_intro() {
clear
print_header "BigBearCasaOS Database Password Update Tool V0.0.1"

echo "Here are some links:"
echo "https://community.bigbeartechworld.com"
echo "https://github.com/BigBearTechWorld"
echo ""
echo "If you would like to support me, please consider buying me a tea:"
echo "https://ko-fi.com/bigbeartechworld"
echo ""
echo "===================="
}

# Show the intro
show_intro

# Set error handling
set -e

# Function to show password change instructions
show_instructions() {
local container_type=$1
echo -e "\nInstructions for updating password in docker-compose.yml:"
echo "1. Look for the service configuration of your database container"
if [[ $container_type == *"postgres"* ]]; then
echo "2. Find the POSTGRES_PASSWORD environment variable"
echo " Example:"
echo " environment:"
echo " - POSTGRES_PASSWORD=your_new_password"
elif [[ $container_type == *"mysql"* ]] || [[ $container_type == *"mariadb"* ]]; then
echo "2. Find the MYSQL_ROOT_PASSWORD environment variable"
echo " Example:"
echo " environment:"
echo " - MYSQL_ROOT_PASSWORD=your_new_password"
fi
echo "3. Replace the old password with: $NEW_PASSWORD"
echo "4. Save the file and exit the editor"
echo -e "\nPress Enter to continue to editor..."
read
}

# edit the docker compose
edit_docker_compose() {
local service_name=$1
local editor_choice=$2
local docker_compose_path="${APPS_DIR}/${service_name}/docker-compose.yml"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix undefined variable APPS_DIR

The APPS_DIR variable is used but never defined. This could cause the script to fail.

Add this at the beginning of the script:

+# Configuration
+APPS_DIR="/var/lib/casaos/apps"  # Adjust this path according to your CasaOS installation

Committable suggestion skipped: line range outside the PR's diff.


if [[ ! -f "$docker_compose_path" ]]; then
echo "Error: The docker-compose.yml file does not exist for the service: $service_name"
exit 1
fi

# Check if the chosen editor is installed
if ! command -v "$editor_choice" &> /dev/null; then
echo "Error: $editor_choice is not installed. Please install it or choose another editor."
exit 1
fi

# Show instructions before editing
show_instructions "$container_name"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix undefined variable container_name

The container_name variable is referenced but not assigned. This should be container based on the selection logic.

-  show_instructions "$container_name"
+  show_instructions "$container"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
show_instructions "$container_name"
show_instructions "$container"
🧰 Tools
🪛 Shellcheck

[warning] 85-85: container_name is referenced but not assigned.

(SC2154)


# Open the editor
"$editor_choice" "$docker_compose_path"

# Apply the changes using casaos-cli
if casaos-cli app-management apply "$service_name" --file="$docker_compose_path"; then
echo "Changes applied successfully."
else
echo "Error: Failed to apply changes. Please check the docker-compose file for errors."
exit 1
fi
}
Comment on lines +68 to +97
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add safety measures for docker-compose editing

Consider adding these safety features:

  1. Backup the docker-compose file before editing
  2. Validate the docker-compose file after editing
 edit_docker_compose() {
   local service_name=$1
   local editor_choice=$2
   local docker_compose_path="${APPS_DIR}/${service_name}/docker-compose.yml"

+  # Create backup
+  cp "$docker_compose_path" "${docker_compose_path}.bak"
+  echo "Created backup at ${docker_compose_path}.bak"
+
   if [[ ! -f "$docker_compose_path" ]]; then
     echo "Error: The docker-compose.yml file does not exist for the service: $service_name"
     exit 1
   fi

   # Check if the chosen editor is installed
   if ! command -v "$editor_choice" &> /dev/null; then
     echo "Error: $editor_choice is not installed. Please install it or choose another editor."
     exit 1
   fi

   # Show instructions before editing
   show_instructions "$container"

   # Open the editor
   "$editor_choice" "$docker_compose_path"

+  # Validate docker-compose file
+  if ! docker-compose -f "$docker_compose_path" config > /dev/null 2>&1; then
+    echo "Error: Invalid docker-compose file. Restoring backup..."
+    cp "${docker_compose_path}.bak" "$docker_compose_path"
+    exit 1
+  fi
+
   # Apply the changes using casaos-cli
   if casaos-cli app-management apply "$service_name" --file="$docker_compose_path"; then
     echo "Changes applied successfully."
+    rm "${docker_compose_path}.bak"
   else
     echo "Error: Failed to apply changes. Please check the docker-compose file for errors."
+    echo "Restoring backup..."
+    cp "${docker_compose_path}.bak" "$docker_compose_path"
     exit 1
   fi
 }

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Shellcheck

[warning] 85-85: container_name is referenced but not assigned.

(SC2154)


# Get list of running containers
containers=$(docker ps --format '{{.Names}}' | grep -E 'postgres|mysql|mariadb')

if [ -z "$containers" ]; then
echo "No database containers found"
exit 1
fi

# Display containers
echo -e "\nAvailable database containers:"
select container in $containers; do
if [ -n "$container" ]; then
break
fi
echo "Invalid selection"
done

# Get new password
read -sp "Enter new password: " NEW_PASSWORD
echo
Comment on lines +117 to +118
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add password validation

The script should validate password complexity to ensure security. Consider adding checks for minimum length, special characters, etc.

+# Password validation function
+validate_password() {
+    local pass="$1"
+    if [[ ${#pass} -lt 8 ]]; then
+        echo "Password must be at least 8 characters long"
+        return 1
+    fi
+    if ! [[ "$pass" =~ [0-9] ]]; then
+        echo "Password must contain at least one number"
+        return 1
+    fi
+    if ! [[ "$pass" =~ [A-Z] ]]; then
+        echo "Password must contain at least one uppercase letter"
+        return 1
+    fi
+    return 0
+}

 # Get new password
-read -sp "Enter new password: " NEW_PASSWORD
+while true; do
+    read -sp "Enter new password: " NEW_PASSWORD
+    echo
+    if validate_password "$NEW_PASSWORD"; then
+        break
+    fi
+done
-echo

Committable suggestion skipped: line range outside the PR's diff.


# Update password based on container type
if [[ $container == *"postgres"* ]]; then
echo "Updating PostgreSQL password..."
docker exec -it $container psql -U postgres -c "ALTER USER postgres WITH PASSWORD '$NEW_PASSWORD';"
elif [[ $container == *"mysql"* ]] || [[ $container == *"mariadb"* ]]; then
echo "Updating MySQL/MariaDB password..."
docker exec -it $container mysql -u root -pDB_PASSWORD_CHANGEME -e "ALTER USER 'root'@'%' IDENTIFIED BY '$NEW_PASSWORD';"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove hardcoded default password and add error handling

The script uses a hardcoded default password 'DB_PASSWORD_CHANGEME' which is insecure. Also, add error handling for the password update operation.

-    docker exec -it $container mysql -u root -pDB_PASSWORD_CHANGEME -e "ALTER USER 'root'@'%' IDENTIFIED BY '$NEW_PASSWORD';"
+    # First try with empty password (common default)
+    if ! docker exec -it $container mysql -u root -e "ALTER USER 'root'@'%' IDENTIFIED BY '$NEW_PASSWORD';" 2>/dev/null; then
+        # If that fails, prompt for current password
+        read -sp "Enter current MySQL root password: " CURRENT_PASSWORD
+        echo
+        if ! docker exec -it $container mysql -u root -p"$CURRENT_PASSWORD" -e "ALTER USER 'root'@'%' IDENTIFIED BY '$NEW_PASSWORD';"; then
+            echo "Failed to update MySQL password. Please verify your current password."
+            exit 1
+        fi
+    fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
docker exec -it $container mysql -u root -pDB_PASSWORD_CHANGEME -e "ALTER USER 'root'@'%' IDENTIFIED BY '$NEW_PASSWORD';"
# First try with empty password (common default)
if ! docker exec -it $container mysql -u root -e "ALTER USER 'root'@'%' IDENTIFIED BY '$NEW_PASSWORD';" 2>/dev/null; then
# If that fails, prompt for current password
read -sp "Enter current MySQL root password: " CURRENT_PASSWORD
echo
if ! docker exec -it $container mysql -u root -p"$CURRENT_PASSWORD" -e "ALTER USER 'root'@'%' IDENTIFIED BY '$NEW_PASSWORD';"; then
echo "Failed to update MySQL password. Please verify your current password."
exit 1
fi
fi

fi

# Ask if user wants to edit docker-compose file
echo -e "\nWould you like to edit the docker-compose file? (y/n)"
read -r edit_choice

if [[ "$edit_choice" =~ ^[Yy]$ ]]; then
# Ask the user to choose an editor
PS3="Select an editor (enter the number): "
options=("nano" "vim" "quit")
select EDITOR_CHOICE in "${options[@]}"
do
case $EDITOR_CHOICE in
"nano"|"vim")
edit_docker_compose "$container" "$EDITOR_CHOICE"
break
;;
"quit")
echo "Skipping docker-compose edit"
break
;;
*)
echo "Invalid option. Please try again."
;;
esac
done
fi

echo -e "\nPassword updated successfully for $container"