#!/bin/bash

#   beas.sh - Bash Email Admin Script
#   Version 0.1
#   (c) 2009 Emmanuel Revah - manu-at-manurevah.com

#   This script is made to go with the tutorial found here
#   http://workaround.org/articles/ispmail-etch/
#   You should inspect it before using it (test it on a test server
#   or test database)

#   This is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.
#
#   DISS is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with DISS.  If not, see <http://www.gnu.org/licenses/>.


## Configuration ##

# User and Password for MYSQL
SQLUSER="mailadmin"
SQLPASS="superpass"
DATABASE="mailserver"

# Min and Max chars for usernames
MINMAIL="1"
MAXMAIL="23"

# Min chars for passwords
MINPW="6"

## End of configuration ## 


doTheMath () {
	COUNTER=1
	unset DB
	for i in ${QUERY}; do
		DB[$COUNTER]=$i
		COUNTER=`expr $COUNTER + 1`
	done
	height=${#DB[@]}
	for i in $(seq 1 $height); do
		if [ -n "${DB[$i]}" ]; then
			echo "$i. ${DB[$i]}"
		fi
        done
}
doTheMath2 () {
	COUNTER=1
	unset DB
	for i in ${QUERY}; do
		DB[$COUNTER]=$i
		COUNTER=`expr $COUNTER + 1`
	done
	COUNTER=1
	for i in ${QUERY2}; do
		DB2[$COUNTER]=$i
		COUNTER=`expr $COUNTER + 1`
	done
	height=${#DB[@]}
	for i in $(seq 1 $height); do
		if [ -n "${DB[$i]}" ]; then
			echo "$i. ${DB[$i]}	=>	${DB2[$i]}"
		fi
        done
}
confirmORdie () {
        COUNTER=0
	while [ $COUNTER != 2 ]; do
		echo -n "Should we continue ? (y/N): "
		read GO
		if [ -n "${GO}" ]; then break; fi
		COUNTER="`expr $COUNTER + 1`"
	done
	if [ "${GO}" = "y" ] || [ "${GO}" = "Y" ]; then
		echo "Continuing..."
	else
		echo "Going back to main menu... (press enter to proceed)"
		read
		pickAdomain
        fi
}
pressEnter () {
	echo ""
	echo "Press enter to continue"
	read
}

getInput () {
	COUNTER=0
	if [ "${2}" = "user" ]; then REGEX="^([0-9a-z]{${MINMAIL},${MAXMAIL}})$"; fi
	if [ "${2}" = "pw" ]; then REGEX="^.{${MINPW},}$"; fi
	if [ "${2}" = "domain" ]; then REGEX="^[a-z0-9\.\-]+$"; fi
	if [ "${2}" = "email" ]; then REGEX="^[a-z@0-9\.\-]+$"; fi
	echo -n "${1} "
	while read ANSWER; do
		if [[ "${ANSWER}" =~ ${REGEX} ]] && [ -n "${ANSWER}" ]; then
		break
		fi
		if [ "${COUNTER}" = "0" ]; then
			echo "Answer contains forbidden characters,"
			echo "you must use:"
			if [ "${2}" = "user" ]; then
				echo ""
				echo "- lower case letters"
				echo "- numbers (0-9)"
				echo "- between ${MINMAIL} and ${MAXMAIL} characters"
			elif [ "${2}" = "pw" ]; then
				echo ""
				echo "- at least ${MINPW} characters"
			elif [ "${2}" = "domain" ]; then
				echo ""
				echo "- lower case letters"
				echo "- numbers"
				echo "- \". -\""
			elif [ "${2}" = "email" ]; then
				echo ""
				echo "- lower case letters"
				echo "- numbers"
				echo "- \".\" and/or \"-\" and/or \"@\""
			fi
			echo ""
			echo -n "${1} "
			COUNTER="`expr $COUNTER + 1`"
		else
			echo " Bad answer please try again"
			echo -n "${1} "
		fi
	done
}

getListInput () {
	while read DBNO; do
		if [ "${DBNO}" = "q" ] || [ "${DBNO}" = "Q" ]; then exit;
		elif [ "${DBNO}" = "a" ] || [ "${DBNO}" = "A" ]; then add${THING}
		elif [ "${DBNO}" = "h" ] || [ "${DBNO}" = "H" ]; then pickAdomain
		fi
		if  [ "${THING}" = "Email" ]; then
			if [ "${DBNO}" = "l" ] || [ "${DBNO}" = "L" ]; then pickAlias;
			elif [ "${DBNO}" = "m" ] || [ "${DBNO}" = "M" ]; then modDomain;
			elif [ "${DBNO}" = "d" ] || [ "${DBNO}" = "D" ]; then delDomain;
			fi
		fi
		if [ -n "${DBNO}" ] && [ "${DBNO}" -eq "${DBNO}" > /dev/null 2>&1 ] && (("${DBNO}" >= "1")) && (("${DBNO}" <= $height)); then
			break
		fi
		echo "Bad input, please try again"
		echo -n " => "
	done
}

genericMenuAddon () {
	echo "H. Main menu"
	echo "Q. Quit"
	echo ""
	echo -n " => "
	getListInput
}

pickAdomain () {
	THING="Domain"
	echo ""
	echo "+---------------------------+"
	echo "| Listing all email domains |"
	echo "+---------------------------+"
	echo ""
	QUERY=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "SELECT name FROM ${DATABASE}.virtual_domains;"|sort`
	doTheMath
	echo " "
	echo "A. Add domain"
	genericMenuAddon
	DOMAIN="${DB[$DBNO]}"
	pickAmail
}

pickAmail () {
	THING="Email"
	echo ""
	echo "+----------------------------------+"
	echo "| Listing all accounts from domain | ${DOMAIN}"
	echo "+----------------------------------+"
	echo ""
	QUERY=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "USE ${DATABASE}; SELECT email FROM view_users WHERE email LIKE CONVERT( _utf8 '%@${DB[$DBNO]}' USING latin1 );"`
	doTheMath
	echo " "
	echo "A. Add Email"
	echo "L. List Aliases from Domain ${DOMAIN}"
	echo "M. Modify Domain ${DOMAIN}"
	echo "D. Delete Domain ${DOMAIN}"
	genericMenuAddon
	EMAIL="${DB[$DBNO]}"
	EMAILID=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "USE ${DATABASE}; SELECT id FROM view_users WHERE email = '${EMAIL}';"`
	showMail
}

pickAlias () {
	THING="Alias"
	echo ""
	echo "+---------------------------------+"
	echo "| Listing all aliases from domain | ${DOMAIN}"
	echo "+---------------------------------+"
	echo ""
	QUERY=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; select email FROM view_aliases WHERE email LIKE '%@${DOMAIN}';"`
	QUERY2=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; select destination FROM view_aliases WHERE email LIKE '%@${DOMAIN}';"`
	echo "   source		=>	destination"
	echo "-------------------------------------------"
	doTheMath2
	echo " "
	echo "A. Add Alias"
	genericMenuAddon
	ALIAS="${DB[$DBNO]}"
	DESTINATION="${DB2[$DBNO]}"
	showAlias
}

addDomain () {
	getInput "Enter domain to add: " domain
	NEWDOMAIN="${ANSWER}"
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; INSERT INTO virtual_domains ( id , name ) VALUES ( NULL , '${NEWDOMAIN}' );"
	echo "" 
	echo "Domain ${NEWDOMAIN} added."
	pressEnter
	pickAdomain
}

addEmail () {
	getInput "Enter email prefix (without \"@${DOMAIN}\"): " user
	NEWMAIL="${ANSWER}"
	getInput "Enter password for ${NEWMAIL}@${DOMAIN} : " pw
	MAILPASS="${ANSWER}"
	echo "creating ${NEWMAIL}@${DOMAIN} pass: ${MAILPASS}"
	DOMAINID=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; SELECT id FROM virtual_domains WHERE name = '${DOMAIN}';"`
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; INSERT INTO virtual_users ( id , domain_id , user , password ) VALUES ( NULL , '${DOMAINID}' , '${NEWMAIL}' , MD5('${MAILPASS}') )";
	echo "Done"
	echo ""
	echo " Acount info:"
	echo " user: ${NEWMAIL}@${DOMAIN}"
	echo " password: ${MAILPASS}"
	pressEnter
	pickAdomain
}

addAlias () {
	getInput "Enter Alias to add (without \"@${DOMAIN}\"): " user
	NEWALIAS="${ANSWER}"
	getInput "Enter destination (full email address): " email
	NEWDESTINATION="${ANSWER}"
	DOMAINID=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; SELECT id FROM virtual_domains WHERE name = '${DOMAIN}';"`
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; INSERT INTO ${DATABASE}.virtual_aliases ( id , domain_id , source , destination ) VALUES (NULL , '${DOMAINID}', '${NEWALIAS}', '${NEWDESTINATION}');"
	echo ""
	echo "New alias ${NEWALIAS}@${DOMAIN} => ${NEWDESTINATION} added"
	pressEnter
	pickAdomain
}

showMail () {
	echo ""
	echo "What do you want to do with ${EMAIL} ?"
	echo ""
	echo "M. Modify address"
	echo "C. Change passowrd"
	echo "D. Delete mailbox"
	echo "Q. Quit"
	echo ""
	echo -n "=> "
	read ANS
        if [ "${ANS}" = "m" ] || [ "${ANS}" = "M" ]; then modEmail;
        elif [ "${ANS}" = "c" ] || [ "${ANS}" = "C" ]; then modPass;
        elif [ "${ANS}" = "d" ] || [ "${ANS}" = "D" ]; then delEmail;
        elif [ "${ANS}" = "q" ] || [ "${ANS}" = "Q" ]; then exit;
	fi
	pickAdomain
}

showAlias () {
	echo ""
	echo "What do you want to do with ${ALIAS} => ${DESTINATION} ?"
	echo ""
	echo "M. Modify Alias"
	echo "D. Delete Alias"
	echo "Q. Quit"
	echo ""
	echo -n "=> "
	read ANS
	DOMAINID=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; SELECT id FROM virtual_domains WHERE name = '${DOMAIN}';"`
	ALIASID=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; SELECT id FROM virtual_aliases WHERE source = '${SHORTALIAS}' AND domain_id = '${DOMAINID}';"`
        if [ "${ANS}" = "m" ] || [ "${ANS}" = "M" ]; then modAlias;
        elif [ "${ANS}" = "d" ] || [ "${ANS}" = "D" ]; then delAlias;
        elif [ "${ANS}" = "q" ] || [ "${ANS}" = "Q" ]; then exit;
	fi
	pickAdomain
}

delDomain () {
	echo ""
	echo "WARNING !!  This will delete:"
	echo ""
	echo " - The domain ${DOMAIN}"
	echo " - All email accounts on ${DOMAIN}"
	echo " - All aliases for ${DOMAIN}"
	echo " - All emails in /home/vmail/${DOMAIN}."
	echo ""
	confirmORdie
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; DELETE FROM virtual_domains WHERE  virtual_domains.name = '${DOMAIN}';"
	if [ -d "/home/vmail/${DOMAIN}" ]; then rm -rf /home/vmail/${DOMAIN}; fi
	echo ""
	echo "Domain ${DOMAIN} deleted"
	echo ""
	pressEnter
	pickAdomain
}

delEmail () {
	USER=`echo ${EMAIL}|cut -d "@" -f 1`
	echo ""
	echo "WARNING !!  This will delete:"
	echo ""
	echo " - The email account ${EMAIL}"
	echo " - ALL emails in /home/vmail/${DOMAIN}/${USER}"
	echo ""
	confirmORdie
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; DELETE FROM virtual_users WHERE virtual_users.id = '${EMAILID}';"
	if [ -d "/home/vmail/${DOMAIN}/${USER}" ]; then rm -rf /home/vmail/${DOMAIN}/${USER}; fi
	echo ""
	echo "Account deleted !"
	pressEnter
	pickAdomain
}

delAlias () {
	echo ""
	echo "Do you really want to delete the alias ${ALIAS} => ${DESTINATION} ?"
	confirmORdie
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "use ${DATABASE}; DELETE FROM virtual_aliases WHERE virtual_aliases.id = '${ALIASID}';"
	echo ""
	echo "Alias deleted !"
	pressEnter
	pickAdomain
}

modDomain () {
	echo ""
	echo "This option changes the domain name and hence will impact all accounts attached to this domain."
	echo "Be aware that aliases will not be updated from this script."
	echo ""
	getInput "Enter replacement name for domain ${DOMAIN} : " domain
	NEWDOMAIN="${ANSWER}"
	DOMAINID=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "SELECT id FROM ${DATABASE}.virtual_domains WHERE name = '${DOMAIN}';"`
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "USE ${DATABASE}; UPDATE virtual_domains SET name = '${NEWDOMAIN}' WHERE virtual_domains.id = '${DOMAINID}';"
	echo ""
	echo "The domain ${DOMAIN} is now ${NEWDOMAIN}."
	pressEnter
	pickAdomain
}

modEmail () {
	echo ""
	echo "Modifying email ${EMAIL}. (you should be aware that aliases will not be updated automatically)"
	getInput "Enter replacement name (the part before the @ sign): " user
	NEWMAIL="${ANSWER}"
	DOMAINID=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "SELECT id FROM ${DATABASE}.view_users WHERE email = '${EMAIL}';"`
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "USE ${DATABASE}; UPDATE virtual_users SET user = '${NEWMAIL}' WHERE virtual_users.id = '${DOMAINID}';"
	echo ""
	echo "The email address ${EMAIL} is now ${NEWMAIL}@${DOMAIN}"
	pressEnter
	pickAdomain
}

modPass () {
	echo ""
	echo "Modifying email ${EMAIL}."
	getInput "Enter new password: " pw
	NEWPASS="${ANSWER}"
	DOMAINID=`mysql -u${SQLUSER} -p${SQLPASS} -ss -e "SELECT id FROM ${DATABASE}.view_users WHERE email = '${EMAIL}';"`
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "USE ${DATABASE}; UPDATE virtual_users SET password = MD5('${NEWPASS}') WHERE virtual_users.id = '${DOMAINID}';"
	echo ""
	echo "Password for account ${EMAIL} modified"
	pressEnter
	pickAdomain
}

modAlias () {
	echo ""
	echo "Modifying Alias ${ALIAS} => ${DESTINATION}."
	echo ""
	SHORTALIAS=`echo ${ALIAS}|cut -d "@" -f 1`
	getInput "Enter new Alias source (without \"@${DOMAIN}\") (was: ${SHORTALIAS}) : " user
	NEWALIAS="${ANSWER}"
	getInput "Enter new Destination (Complete email address where emails should be sent to): " email
	NEWDESTINATION="${ANSWER}"
	mysql -u${SQLUSER} -p${SQLPASS} -ss -e "USE ${DATABASE}; UPDATE virtual_aliases SET source = '${NEWALIAS}', destination = '${NEWDESTINATION}'  WHERE virtual_aliases.id = '${ALIASID}' ;"
	echo ""
	echo " Old Alias: ${ALIAS} => ${DESTINATION}"
	echo "		is now"
	echo " ${NEWALIAS}@${DOMAIN} => ${NEWDESTINATION}"
	pressEnter
	pickAdomain
}

echo "
+---------------------------+
|			    |
|  Bash Email Admin Script  |
|	   v. 0.1	    |
+---------------------------+"
pickAdomain

