Enables Uberspace users to administrate some functions via a very simple web panel
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

action.sh 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. #!/bin/bash
  2. ########################################################################
  3. # Copyright (C) 2016 Max Mehl <mail [at] mehl [dot] mx>
  4. ########################################################################
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU Affero General Public License as
  8. # published by the Free Software Foundation, either version 3 of the
  9. # License, or (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU Affero General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Affero General Public
  17. # License along with this program. If not, see
  18. # <http://www.gnu.org/licenses/>.
  19. #
  20. ########################################################################
  21. #
  22. # This script handles calls from submit.php.
  23. # It checks the validity of usernames, executes basic command
  24. # When password entries are required, it starts the respective python
  25. # scripts
  26. #
  27. ########################################################################
  28. # Test if config.cfg exists and set needed variables
  29. if [ ! -e config.cfg ]; then echo "Missing config.cfg file. Edit and rename config.cfg.sample"; exit 1; fi
  30. source config.cfg
  31. ACTION=$1 # adduser, changepw, listusers, userdetail, deluser, sizeall, sizeuser, viewdata
  32. USER=$2
  33. PASSFILE=$3 # $3 is a file containing the password
  34. PASS=$(cat $PASSFILE)
  35. PATH=$PATH:$HOME/bin
  36. ## FUNCTIONS
  37. function checkaction {
  38. REGEX="^adduser$|^changepw$|^listusers$|^userdetail$|^deluser$|^sizeall$|^sizeuser$|^viewdata$|^addalias$|^quota$|^installwp$|^uninstallwp$"
  39. if [[ $1 =~ $REGEX ]]; then
  40. echo "true"
  41. else
  42. echo "false"
  43. fi
  44. }
  45. function checkuser {
  46. REGEX="^[A-Za-z0-9._+-]+$" # Allowed symbols
  47. if [[ $1 =~ $REGEX ]]; then
  48. echo "true"
  49. else
  50. echo "false"
  51. fi
  52. }
  53. function checkpass {
  54. REGEX="[ '\\]" # Not allowed symbols
  55. if [[ $(grep -E "$REGEX" $1 ; echo $?) == 1 ]]; then
  56. echo "true"
  57. else
  58. echo "false"
  59. fi
  60. }
  61. function userexists {
  62. STATUS=$(listvdomain | cut -d" " -f 1 | sed '1d' | grep -q "^$1$" ; echo $?)
  63. if [ $STATUS == 0 ]; then
  64. echo "true"
  65. else
  66. echo "false"
  67. fi
  68. }
  69. function mailsend {
  70. TOEMAIL="$TOEMAIL";
  71. FREMAIL="$FREMAIL";
  72. SUBJECT="[$DOMAIN] $1";
  73. MSGBODY1="$2"
  74. MSGBODY2="$3"
  75. printf '%s\n' "From: $FREMAIL
  76. To: $TOEMAIL
  77. Reply-To: $FREMAIL
  78. Subject: $SUBJECT
  79. $MSGBODY1
  80. $MSGBODY2
  81. " > $MAILTMP
  82. cat $MAILTMP | "$SENDMAILPATH" -t;
  83. rm $MAILTMP;
  84. }
  85. function mailsendenc {
  86. if [ ! -e $SSLKEY ]; then
  87. #echo "Encryption key \"$SSLKEY\" is not available. Aborting."
  88. #exit 1
  89. openssl genrsa -out $SSLKEY 2048
  90. fi
  91. TOEMAIL="$TOEMAIL";
  92. FREMAIL="$FREMAIL";
  93. SUBJECT="[$DOMAIN] $1";
  94. MSGBODY1="$2"
  95. BOUNDARY="ZZafgwejwepfgkl.9453x1q"
  96. ATTACHMENT=$(echo $3 | openssl rsautl -inkey $SSLKEY -encrypt | base64)
  97. printf '%s\n' "From: $FREMAIL
  98. To: $TOEMAIL
  99. Reply-To: $FREMAIL
  100. Subject: $SUBJECT
  101. Mime-Version: 1.0
  102. Content-Type: multipart/mixed; boundary=\"$BOUNDARY\"
  103. --${BOUNDARY}
  104. Content-Type: text/plain; charset=\"us-ascii\"
  105. Content-Transfer-Encoding: 7bit
  106. Content-Disposition: inline
  107. $MSGBODY1
  108. Upload the attached encrypted file to your Account Administration Panel
  109. in order to see sensitive details. Please visit the section \"Decrypt
  110. system email\" for more details.
  111. --${BOUNDARY}
  112. Content-Type: text/plain
  113. Content-Transfer-Encoding: 7bit
  114. Content-Disposition: attachment; filename=\"message.txt.crypt\"
  115. $ATTACHMENT
  116. --${BOUNDARY}
  117. " > $MAILTMP
  118. cat $MAILTMP | "$SENDMAILPATH" -t;
  119. rm $MAILTMP;
  120. }
  121. function notesdelete {
  122. USER="$1"
  123. # Extract Mail part | exclude LEAD and TAIL | delete user
  124. sed -n "/$LEAD/,/$TAIL/ p" $NOTES | grep -v "$LEAD\|$TAIL" | sed "/User:[ \t]*$USER$/,+2d" > $NOTESTMP
  125. # Put edited part in between $LEAD and $TAIL again
  126. sed -i "/$LEAD/,/$TAIL/{ /$LEAD/{p; r $NOTESTMP
  127. }; /$TAIL/p; d }" $NOTES
  128. rm $NOTESTMP
  129. }
  130. function notesinsert {
  131. # Update datasheet (add new entry in Email section)
  132. USER=$1
  133. PASSFILE=$2
  134. # Create temporary file from $PASSFILE
  135. sed -E "s/(.*)/User: $USER\nPass: \1\n\n/" $PASSFILE > .$PASSFILE.tmp
  136. # Insert this edited file into the datasheet
  137. sed -i "/$TAIL/ {
  138. h
  139. r .$PASSFILE.tmp
  140. g
  141. N
  142. }" $NOTES
  143. rm .$PASSFILE.tmp
  144. }
  145. ## FIRST CHECKS
  146. if ! $(checkaction "$ACTION"); then
  147. echo "No valid action chosen"
  148. exit 1
  149. fi
  150. # # # # #
  151. # ADDING USER
  152. # # # # #
  153. if [ "$ACTION" == "adduser" ]; then
  154. echo "Adding new Email user..."
  155. echo
  156. if ! $(checkuser "$USER"); then
  157. echo "Username \"$USER\" invalid"
  158. exit 1
  159. fi
  160. if $(userexists "$USER"); then
  161. echo "User \"$USER\" does already exist!"
  162. exit 1
  163. fi
  164. if ! $(checkpass "$PASSFILE"); then
  165. echo "Password \""$(cat $PASSFILE)"\" invalid"
  166. exit 1
  167. fi
  168. python adduser.py "$USER" "$PASSFILE"
  169. if [ $? == 0 ]; then
  170. # Send infomail
  171. $MAILTYPE "New Email account created" \
  172. "A new Email account has been created." \
  173. "User: $USER"
  174. LEAD='## > EMAIL'
  175. TAIL='## < EMAIL'
  176. notesinsert "$USER" "$PASSFILE"
  177. fi
  178. fi # /adduser
  179. # # # # #
  180. # ADD ALIAS
  181. # # # # #
  182. if [ "$ACTION" == "addalias" ]; then
  183. echo "Extracting details of Email account..."
  184. echo
  185. DEST=$PASS
  186. if ! $(checkuser "$USER"); then
  187. echo "Username \"$USER\" invalid"
  188. exit 1
  189. fi
  190. if $(userexists "$USER"); then
  191. echo "User \"$USER\" does already exist!"
  192. exit 1
  193. fi
  194. if ! $(userexists "$DEST"); then
  195. echo "Destination account \"$DEST\" does not exist!"
  196. exit 1
  197. fi
  198. vaddalias $USER $DEST
  199. fi # /addalias
  200. # # # # #
  201. # CHANGE PASSWORD
  202. # # # # #
  203. if [ "$ACTION" == "changepw" ]; then
  204. echo "Changing password of Email account..."
  205. echo
  206. if ! $(userexists "$USER"); then
  207. echo "User \"$USER\" does not exist!"
  208. exit 1
  209. fi
  210. if ! $(checkpass "$PASSFILE"); then
  211. echo "Password \""$(cat $PASSFILE)"\" invalid"
  212. exit 1
  213. fi
  214. python changepw.py "$USER" "$PASSFILE"
  215. if [ $? == 0 ]; then
  216. # Send infomail
  217. $MAILTYPE "Email password changed" \
  218. "An Email account password has been changed." \
  219. "User: $USER"
  220. # Update datasheet (delete entry in Email section and add a new one with the new password)
  221. # In fact a combination of deluser and adduser
  222. LEAD='## > EMAIL'
  223. TAIL='## < EMAIL'
  224. notesdelete "$USER"
  225. notesinsert "$USER" "$PASSFILE"
  226. fi
  227. fi # /changepw
  228. # # # # #
  229. # LIST USERS
  230. # # # # #
  231. if [ "$ACTION" == "listusers" ]; then
  232. echo "Listing all Email accounts..."
  233. echo
  234. listvdomain | column -s $' ' -t
  235. fi # /listusers
  236. # # # # #
  237. # SIZE ALL USERS
  238. # # # # #
  239. if [ "$ACTION" == "sizeall" ]; then
  240. echo "Calculate total size of all Email accounts..."
  241. echo
  242. du -sBM ~/users/* | sed -e "s:/home/$SYSUSER/users/::g"
  243. fi # /sizeall
  244. # # # # #
  245. # VIEW DATASHEET
  246. # # # # #
  247. if [ "$ACTION" == "viewdata" ]; then
  248. echo "Extracting data sheet..."
  249. echo
  250. cat $NOTES
  251. fi # /viewdata
  252. # # # # #
  253. # SIZE USER
  254. # # # # #
  255. if [ "$ACTION" == "sizeuser" ]; then
  256. echo "Calculate size of all folders of an Email account..."
  257. echo
  258. # Show size in MB, strip long paths, strip tmp and new folders, rename .INBOX cur-folder
  259. du -BM ~/users/"$USER" | sed -e "s:/home/$SYSUSER/users/$USER/::g" | grep -v "/cur$\|new$\|tmp$" | sed "s:cur$:.INBOX:" | grep -v "/home/$SYSUSER/users/$USER" | sort -nr
  260. fi # /sizeuser
  261. # # # # #
  262. # USER DETAIL
  263. # # # # #
  264. if [ "$ACTION" == "userdetail" ]; then
  265. echo "Extracting details of Email account..."
  266. echo
  267. if ! $(userexists "$USER"); then
  268. echo "User \"$USER\" does not exist!"
  269. exit 1
  270. fi
  271. dumpvuser "$USER" | column -s $' ' -t
  272. fi # /userdetail
  273. # # # # #
  274. # QUOTA
  275. # # # # #
  276. if [ "$ACTION" == "quota" ]; then
  277. echo "Calculating account disk usage..."
  278. echo
  279. USAGE=$(quota -gsl | tail -n 1 | awk -F" " '{ print $2 }')
  280. QUOTA=$(quota -gsl | tail -n 1 | awk -F" " '{ print $3 }' | sed 's/[A-Za-z]//g')
  281. # If smaller than 1M, set usage to 1M to avoid miscalcuations
  282. if [ $(echo $USAGE | grep -q "[A-Za-z]$" ; echo $?) != 0 ]; then
  283. USAGE="1"
  284. else
  285. USAGE=$(echo $USAGE | sed 's/[A-Za-z]//g')
  286. fi
  287. PERC=$(echo "scale=2; $USAGE/$QUOTA" | bc)
  288. PERC=$(echo "scale=2; $PERC*100" | bc)
  289. echo "$USAGE MB of $QUOTA MB are used ($PERC %)."
  290. PERC=$(echo "scale=2; 100 - $PERC" | bc)
  291. echo "You have "$[$QUOTA - $USAGE]" MB free ($PERC %)."
  292. fi # /quota
  293. # # # # #
  294. # DELETE USER
  295. # # # # #
  296. if [ "$ACTION" == "deluser" ]; then
  297. echo "Extracting details of Email account..."
  298. echo
  299. if ! $(userexists "$USER"); then
  300. echo "User \"$USER\" does not exist!"
  301. exit 1
  302. fi
  303. vdeluser "$USER"
  304. if [ $? == 0 ]; then
  305. # Send infomail
  306. $MAILTYPE "Email account deleted" \
  307. "An Email account has been deleted." \
  308. "User: $USER"
  309. # Update datasheet (delete entry in Email section)
  310. LEAD='## > EMAIL'
  311. TAIL='## < EMAIL'
  312. notesdelete "$USER"
  313. fi
  314. fi # /deluser
  315. # # # # #
  316. # INSTALL WORDPRESS
  317. # # # # #
  318. if [ "$ACTION" == "installwp" ]; then
  319. echo "Installing WordPress..."
  320. echo
  321. # $USER: Username for Wordpress
  322. # $PASS: Email address for Wordpress user
  323. if ! $(checkuser "$USER"); then
  324. echo "Username \"$USER\" invalid"
  325. exit 1
  326. fi
  327. WEBDIR=$HOME/html
  328. WPUSER=$USER
  329. WPPASS=$(apg -n 1 -M NCL -m 14)
  330. WPMAIL=$PASS
  331. WPDOMAIN=http://$DOMAIN
  332. # Get MySQL password
  333. LEAD='## > MYSQL'
  334. TAIL='## < MYSQL'
  335. MYSQLUSER=$SYSUSER
  336. MYSQLDB=${MYSQLUSER}_wp
  337. MYSQLPASS=$(sed -n "/$LEAD/,/$TAIL/ p" $NOTES | grep "^Pass:" | awk -F" " '{ print $2 }')
  338. # Check if ready for install: WEBDIR empty, Database available
  339. if [ $(ls -a $WEBDIR | wc -l) -gt 2 ]; then
  340. echo "The website directory \"$WEBDIR\" doesn't seem to be empty."
  341. exit 1
  342. fi
  343. if [ $(mysql -e "SHOW DATABASES;" | tr -d "| " | grep -v Database | grep "^$$WPDB$" ; echo $?) = 0 ]; then
  344. echo "The default database \"${USER}_wp\" already exists."
  345. exit 1
  346. fi
  347. # Downloading wordpress
  348. wget $WPDL
  349. unzip $(basename $WPDL)
  350. mv wordpress/* $WEBDIR
  351. rm -r wordpress $(basename $WPDL)
  352. # Downloading wp-cli
  353. curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
  354. chmod +x wp-cli.phar
  355. mv wp-cli.phar $HOME/bin/wp-cli
  356. # Create database
  357. mysql -e "CREATE DATABASE $MYSQLDB;"
  358. # Use wp-cli to create config.php and install WP
  359. wp-cli core config --dbname=${MYSQLDB} --dbpass=${MYSQLPASS} --dbuser=${MYSQLUSER} --path=${WEBDIR}
  360. wp-cli core install --url="$WPDOMAIN" --title="CHANGE THIS TITLE" --admin_user=${WPUSER} --admin_password=${WPPASS} --admin_email=${WPMAIL} --path=${WEBDIR}
  361. # Update datasheet
  362. TAIL='## < WORDPRESS'
  363. sed -i "/$TAIL/i User: $WPUSER\nPass: $WPPASS\n" $NOTES
  364. echo
  365. echo "Wordpress successfully installed to $WPDOMAIN"
  366. echo "You can login on $WPDOMAIN/wp-login.php"
  367. echo "Please take a look into your data sheet for the login data."
  368. fi # /installwp
  369. # # # # #
  370. # REMOVE WORDPRESS
  371. # # # # #
  372. if [ "$ACTION" == "uninstallwp" ]; then
  373. echo "Uninstalling WordPress..."
  374. echo
  375. # $USER: Username for Wordpress
  376. # $PASS: Email address for Wordpress user
  377. WEBDIR=$HOME/html
  378. MYSQLUSER=$SYSUSER
  379. MYSQLDB=${MYSQLUSER}_wp
  380. # Delete database and content of ~/htmp
  381. mysql -e "DROP DATABASE ${MYSQLDB};"
  382. rm -rf $WEBDIR/*
  383. rm -rf $WEBDIR/.*
  384. # Update datasheet
  385. LEAD='## > WORDPRESS'
  386. TAIL='## < WORDPRESS'
  387. notesdelete ".*"
  388. echo
  389. echo "Wordpress successfully uninstalled."
  390. fi # /uninstallwp