# PLACE YOUR BASH INTERPRETER HERE.

##########################################################################################
#
# FILE: permission_update
# 
# You can change the PERMS, UID and GID of directories
# mostly used for wordpress and joomla sites.
# You OPEN the directory access so files can be updated (wordpress update, joomla update)
# You LOCK the directory access so files cannot be written to (normal operation)
# You can specify what permissions and
# 
##########################################################################################

# config files, specify a location that is RELATIVE
# to the "-s SITE_DIRECTORY" you specify on the command line
# you can also place them directly into the tree, just make sure you
# protect them in .htaccess.
lock_file="permission_update_lock.txt"
update_file="permission_update_update.txt"

########################################## stop editing here.
# vars used
debug=0
permupdate=0
permlock=0
site=""

# this holds the array for line instruction
declare -a instruction

function read_write
{
    # make it read_write for $3 AND $2
    # echo $"READ WRITE of ${1} for user ${2} AND group ${3}"
    echo $" - chown -R ${2}.${3} $1"
    chown -R ${2}.${3} $1
    echo " - find $1 -type d -exec chmod 6770 {} \;"
    find $1 -type d -exec chmod 6770 {} \;
    echo " - find $1 -type f -exec chmod 0660 {} \;"
    find $1 -type f -exec chmod 0660 {} \;
    echo 
}

function read_only
{
    # make it read_write for $2 AND read_only for $3
    # echo $"READ ONLY of ${1} for group ${3} and READ_WRITE for user ${2}"
    echo $" - chown -R ${2}.${3} $1"
    chown -R ${2}.${3} $1
    echo " - find $1 -type d -exec chmod 0750 {} \;"
    find $1 -type d -exec chmod 0750 {} \;
    echo " - find $1 -type f -exec chmod 0640 {} \;"
    find $1 -type f -exec chmod 0640 {} \;
}

# help
usage()
{
    echo 
    echo $1
    echo 
    echo "Usage ${0} [-d] -[c|u] [-lf LOCK_FILE] [-uf UPDATE_FILE] [-s SITE_DIRECTORY]"
    echo " where "
    echo "   "
    echo "   -d turn debug messages on"
    echo "   -u update mode, meaning reading the instructions from permission_update_update file"
    echo "   -l lock mode, meaning reading the instructions from permission_update_lock file"
    echo "   -s site directory, this needs to be full tree beginning with a /"
    echo "   -lf lock file, specify a different instruction file for locking"
    echo "   -uf update file, specify a different instruction file for updating"
    echo "   -h"
    echo "   -help help, this message"
    echo " HINTS:"
    echo " The configuration files should be protected in the .htacess file of the site like so: "
    echo "   "
    echo "   <Files ~ '^permission_update_'>"
    echo "       Order allow,deny"
    echo "       Deny from all"
    echo "   </Files>"
    echo " If you do not want to do this put the files one directory up outside of the site tree."
    echo " You can specify ' -lf ../permission_update_lock ' on the command line to access the"
    echo " file but it cannot be disclosed by the server, this is for your security."
    echo "   "
}

docont()
{
    echo "${1}"
    echo 
    read -e -n 1 -p "press y to do it ..." key
    if [ "$key" != "y" ]; then
        echo 
        echo "Aborting upon user request"
        echo 
        exit
    fi
}

# parse command line
while [ "$1" != "${1##[-+]}" ]; do
    case $1 in
        '') usage "Incorrect Parameter $1 specified!"
            exit 1
            ;;
        -d)
            debug=1
            shift 1
            ;;
        -u)
            permupdate=1
            permlock=0
            shift 1
            ;;
        -l)
            permupdate=0
            permlock=1
            shift 1
            ;;
        -s) 
            site=$2
            shift 2
            ;;
        -lf) 
            lock_file=$2
            shift 2
            ;;
        -uf) 
            open_file=$2
            shift 2
            ;;
        -h) 
            usage
            exit 1
            ;;
        -help) 
            usage
            exit 1
            ;;
        *)  usage "Incorrect Parameter $1 specified!"
            exit 1
            ;;
    esac
done

# display what we've found so far
if [ $debug == 1 ]; then
    echo 
    echo "DEBUG  $debug"
    echo "UPDATE $permupdate"
    echo "LOCK   $permlock"
    echo "SITE   $site"
    echo 
fi

# root only, period
if [ $UID -ne 0 ]; then
    echo $"You must be root to do this, Aborting!"
    echo $" "
    exit
fi

# specified UPDATE or LOCK?
if [[ $permupdate == 0 && $permlock == 0 ]]; then
    usage "You must specify at least one -c or -u"
    echo $" "
    exit
fi

# specified the SITE DIRECTORY?
if [[ -z $site ]]; then
    usage "You must specify the site directory, you specified |$site|"
    echo $" "
    exit
fi

# IS DIRECTORY A FILE?
if [ ! -d "$site" ]; then
    usage "The site directory must exist, you specified |$site|"
    echo $" "
    exit
fi

if [[ $permlock == 1 || $permupdate == 1 ]]; then

    if [[ $permlock == 1 ]]; then
        docont "We are locking the directory |$site| "
        echo
        # check whether the instruction instfile exists
        instfile=$site.$"/"$lock_file
        echo "Reading "$instfile
        # we need to update the perms on the root.
        echo 
        echo "LOCKING the permission on the root $site!"
        chmod 0750 $site
        echo 
    fi

    if [[ $permupdate == 1 ]]; then
        docont "We are updating the directory |$site| "
        echo
        # check whether the instruction instfile exists
        instfile=$site$"/"$open_file
        echo "Reading "$instfile
        # we need to update the perms on the root.
        echo 
        echo "UPDATING the permission on the root $site, YOU NEED TO REVERSE THIS!!!!!!!!!!!!"
        chmod 0770 $site
        echo 
    fi
    
    # check exists ...
    echo "Checking instfile |$instfile| ... "
    if [ ! -f "$instfile" ]; then
        usage "The update instruction instfile |$instfile| must exist, please fix"
        echo
        exit
    fi
    
    # do it
    while read -r line; 
    do
        echo "found |$line|"
        [[ "$line" = "\#*" ]] && continue
        [[ "$line" == "" ]] && continue
        # split it
        IFS=', ' read -r -a instruction <<< "$line"
        if [ "${instruction[0]}" == "perms" ]; then
            echo " - Working with ${instruction[4]}:"
            curfile=$site${instruction[4]}
            echo -n " - Permission instruction, "
            if [ "${instruction[1]}" == "rw" ]; then
                echo -n "rw $curfile "
                if [ ! -e "$curfile" ]; then
                    echo 
                    echo 
                    echo "File $curfile does not exist, aborting!"
                    echo 
                    exit
                fi
                read_write $curfile
            fi
            if [ "${instruction[1]}" == "ro" ]; then
                echo -n "ro $curfile "
                if [ ! -e "$curfile" ]; then
                    echo 
                    echo 
                    echo "File $curfile does not exist, aborting!"
                    echo 
                    exit
                fi
                read_only $curfile
            fi
        fi
        if [ "${instruction[0]}" == "delete" ]; then
            curfile=$site${instruction[1]}
            echo " - Delete instruction, working with $curfile, "
            rm -f $curfile
        fi
        if [[ $line =~ ^# ]]; then
            # comment
            echo " - Comment ${line}"
        fi
 
        echo 
    done < $instfile
    echo
    echo
    exit
fi
