#!/bin/bash # # Script to revoke ALTER permission from application database user # # Colors GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[0;33m' RED='\033[0;31m' NC='\033[0m' echo -e "${BLUE}===========================================================${NC}" echo -e "${BLUE} Revoke ALTER Permission from Database User${NC}" echo -e "${BLUE}===========================================================${NC}" echo "" # Get database configuration echo -e "${BLUE}Reading database configuration from Laravel...${NC}" DB_USER=$(php artisan tinker --execute="echo config('database.connections.mysql.username');" 2>/dev/null | grep -v ">>>" | grep -v "Psy" | tr -d '\n' | xargs) DB_NAME=$(php artisan tinker --execute="echo config('database.connections.mysql.database');" 2>/dev/null | grep -v ">>>" | grep -v "Psy" | tr -d '\n' | xargs) if [ -z "$DB_USER" ] || [ -z "$DB_NAME" ]; then echo -e "${RED}Error: Could not determine database user or name from Laravel config${NC}" exit 1 fi echo -e "${GREEN}Database: $DB_NAME${NC}" echo -e "${GREEN}User: $DB_USER${NC}" echo "" # Prompt for MySQL credentials with GRANT privileges echo -e "${YELLOW}MySQL user with GRANT privileges needed to revoke ALTER permission${NC}" echo -e "${YELLOW}This can be root or a dedicated deployment user${NC}" read -p "MySQL username [root]: " MYSQL_DEPLOY_USER MYSQL_DEPLOY_USER="${MYSQL_DEPLOY_USER:-root}" read -sp "MySQL password: " MYSQL_DEPLOY_PASS echo "" echo "" # Test MySQL connection first echo -e "${BLUE}Testing MySQL connection...${NC}" if ! mysql -u "$MYSQL_DEPLOY_USER" -p"$MYSQL_DEPLOY_PASS" -e "SELECT 1;" 2>/dev/null >/dev/null; then echo -e "${RED}✗ Failed to connect to MySQL. Check your credentials.${NC}" exit 1 fi echo -e "${GREEN}✓ MySQL connection successful${NC}" echo "" # Show current grants echo -e "${BLUE}Current grants for $DB_USER:${NC}" mysql -u "$MYSQL_DEPLOY_USER" -p"$MYSQL_DEPLOY_PASS" -e "SHOW GRANTS FOR '$DB_USER'@'localhost';" 2>/dev/null echo "" # Confirm revocation echo -e "${YELLOW}This will revoke the ALTER permission from $DB_USER on $DB_NAME${NC}" read -p "Continue? (y/n): " confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then echo "Operation cancelled." exit 0 fi echo "" # Revoke ALTER permission echo -e "${BLUE}Revoking ALTER permission...${NC}" if mysql -u "$MYSQL_DEPLOY_USER" -p"$MYSQL_DEPLOY_PASS" -e "REVOKE ALTER ON \`$DB_NAME\`.* FROM '$DB_USER'@'localhost'; FLUSH PRIVILEGES;" 2>/dev/null; then echo -e "${GREEN}✓ ALTER permission revoked successfully${NC}" else echo -e "${RED}✗ Failed to revoke ALTER permission${NC}" exit 1 fi echo "" # Show updated grants echo -e "${BLUE}Updated grants for $DB_USER:${NC}" mysql -u "$MYSQL_DEPLOY_USER" -p"$MYSQL_DEPLOY_PASS" -e "SHOW GRANTS FOR '$DB_USER'@'localhost';" 2>/dev/null echo "" # Verify by attempting ALTER echo -e "${BLUE}Verifying restriction by attempting ALTER command...${NC}" if php artisan tinker --execute=" try { DB::statement('ALTER TABLE sessions ADD COLUMN test_column VARCHAR(10)'); echo 'FAIL: ALTER command succeeded (should have been denied)'; DB::statement('ALTER TABLE sessions DROP COLUMN test_column'); } catch (\Exception \$e) { if (strpos(\$e->getMessage(), 'ALTER command denied') !== false) { echo 'SUCCESS: ALTER command denied as expected'; } else { echo 'ERROR: ' . \$e->getMessage(); } } exit; " 2>/dev/null | grep -E "SUCCESS|FAIL|ERROR"; then echo "" else echo -e "${YELLOW}Warning: Could not verify restriction${NC}" fi echo "" echo -e "${GREEN}===========================================================${NC}" echo -e "${GREEN} Permission revocation complete!${NC}" echo -e "${GREEN}===========================================================${NC}" echo "" echo -e "${YELLOW}Note: Future deployments will temporarily grant ALTER permission${NC}" echo -e "${YELLOW} during migrations, then automatically revoke it again.${NC}"