test.bats 69 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291
  1. #!/usr/bin/env bats
  2. if [ "${PATH#*/usr/local/hestia/bin*}" = "$PATH" ]; then
  3. . /etc/profile.d/hestia.sh
  4. fi
  5. load 'test_helper/bats-support/load'
  6. load 'test_helper/bats-assert/load'
  7. load 'test_helper/bats-file/load'
  8. function random() {
  9. head /dev/urandom | tr -dc 0-9 | head -c$1
  10. }
  11. function setup() {
  12. # echo "# Setup_file" > &3
  13. if [ $BATS_TEST_NUMBER = 1 ]; then
  14. echo 'user=test-5285' > /tmp/hestia-test-env.sh
  15. echo 'user2=test-5286' >> /tmp/hestia-test-env.sh
  16. echo 'userbk=testbk-5285' >> /tmp/hestia-test-env.sh
  17. echo 'userpass1=test-5285' >> /tmp/hestia-test-env.sh
  18. echo 'userpass2=t3st-p4ssw0rd' >> /tmp/hestia-test-env.sh
  19. echo 'HESTIA=/usr/local/hestia' >> /tmp/hestia-test-env.sh
  20. echo 'domain=test-5285.hestiacp.com' >> /tmp/hestia-test-env.sh
  21. echo 'domainuk=test-5285.hestiacp.com.uk' >> /tmp/hestia-test-env.sh
  22. echo 'rootdomain=testhestiacp.com' >> /tmp/hestia-test-env.sh
  23. echo 'subdomain=cdn.testhestiacp.com' >> /tmp/hestia-test-env.sh
  24. echo 'database=test-5285_database' >> /tmp/hestia-test-env.sh
  25. echo 'dbuser=test-5285_dbuser' >> /tmp/hestia-test-env.sh
  26. echo 'pguser=test5290' >> /tmp/hestia-test-env.sh
  27. echo 'pgdatabase=test5290_database' >> /tmp/hestia-test-env.sh
  28. echo 'pgdbuser=test5290_dbuser' >> /tmp/hestia-test-env.sh
  29. fi
  30. source /tmp/hestia-test-env.sh
  31. source $HESTIA/func/main.sh
  32. source $HESTIA/conf/hestia.conf
  33. source $HESTIA/func/ip.sh
  34. }
  35. function validate_web_domain() {
  36. local user=$1
  37. local domain=$2
  38. local webproof=$3
  39. local webpath=${4}
  40. refute [ -z "$user" ]
  41. refute [ -z "$domain" ]
  42. refute [ -z "$webproof" ]
  43. source $HESTIA/func/ip.sh
  44. run v-list-web-domain $user $domain
  45. assert_success
  46. USER_DATA=$HESTIA/data/users/$user
  47. local domain_ip=$(get_object_value 'web' 'DOMAIN' "$domain" '$IP')
  48. SSL=$(get_object_value 'web' 'DOMAIN' "$domain" '$SSL')
  49. domain_ip=$(get_real_ip "$domain_ip")
  50. if [ ! -z $webpath ]; then
  51. domain_docroot=$(get_object_value 'web' 'DOMAIN' "$domain" '$CUSTOM_DOCROOT')
  52. if [ -n "$domain_docroot" ] && [ -d "$domain_docroot" ]; then
  53. assert_file_exist "${domain_docroot}/${webpath}"
  54. else
  55. assert_file_exist "${HOMEDIR}/${user}/web/${domain}/public_html/${webpath}"
  56. fi
  57. fi
  58. # Test HTTP
  59. # Curl hates UTF domains so convert them to ascci.
  60. domain_idn=$(idn2 $domain)
  61. run curl --location --silent --show-error --insecure --resolve "${domain_idn}:80:${domain_ip}" "http://${domain_idn}/${webpath}"
  62. assert_success
  63. assert_output --partial "$webproof"
  64. # Test HTTPS
  65. if [ "$SSL" = "yes" ]; then
  66. run v-list-web-domain-ssl $user $domain
  67. assert_success
  68. run curl --location --silent --show-error --insecure --resolve "${domain_idn}:443:${domain_ip}" "https://${domain_idn}/${webpath}"
  69. assert_success
  70. assert_output --partial "$webproof"
  71. fi
  72. }
  73. function validate_headers_domain() {
  74. local user=$1
  75. local domain=$2
  76. local webproof=$3
  77. refute [ -z "$user" ]
  78. refute [ -z "$domain" ]
  79. refute [ -z "$webproof" ]
  80. source $HESTIA/func/ip.sh
  81. run v-list-web-domain $user $domain
  82. assert_success
  83. USER_DATA=$HESTIA/data/users/$user
  84. local domain_ip=$(get_object_value 'web' 'DOMAIN' "$domain" '$IP')
  85. SSL=$(get_object_value 'web' 'DOMAIN' "$domain" '$SSL')
  86. domain_ip=$(get_real_ip "$domain_ip")
  87. # Test HTTP with code redirect for some reasons due to 301 redirect it fails
  88. curl -i --resolve "${domain}:80:${domain_ip}" "http://${domain}"
  89. assert_success
  90. assert_output --partial "$webproof"
  91. }
  92. function validate_mail_domain() {
  93. local user=$1
  94. local domain=$2
  95. refute [ -z "$user" ]
  96. refute [ -z "$domain" ]
  97. run v-list-mail-domain $user $domain
  98. assert_success
  99. assert_dir_exist $HOMEDIR/$user/mail/$domain
  100. assert_dir_exist $HOMEDIR/$user/conf/mail/$domain
  101. assert_file_exist $HOMEDIR/$user/conf/mail/$domain/aliases
  102. if [ -n "$ANTISPAM_SYSTEM" ]; then
  103. assert_file_exist $HOMEDIR/$user/conf/mail/$domain/antispam
  104. fi
  105. if [ -n "$ANTIVIRUS_SYSTEM" ]; then
  106. assert_file_exist $HOMEDIR/$user/conf/mail/$domain/antivirus
  107. fi
  108. assert_file_exist $HOMEDIR/$user/conf/mail/$domain/fwd_only
  109. assert_file_exist $HOMEDIR/$user/conf/mail/$domain/ip
  110. assert_file_exist $HOMEDIR/$user/conf/mail/$domain/passwd
  111. }
  112. function validate_webmail_domain() {
  113. local user=$1
  114. local domain=$2
  115. local webproof=$3
  116. local webpath=${4}
  117. refute [ -z "$user" ]
  118. refute [ -z "$domain" ]
  119. refute [ -z "$webproof" ]
  120. source $HESTIA/func/ip.sh
  121. USER_DATA=$HESTIA/data/users/$user
  122. local domain_ip=$(get_object_value 'web' 'DOMAIN' "$domain" '$IP')
  123. SSL=$(get_object_value 'mail' 'DOMAIN' "$domain" '$SSL')
  124. domain_ip=$(get_real_ip "$domain_ip")
  125. if [ ! -z "$webpath" ]; then
  126. assert_file_exist /var/lib/roundcube/$webpath
  127. fi
  128. if [ "$SSL" = "no" ]; then
  129. # Test HTTP
  130. run curl --location --silent --show-error --insecure --resolve "webmail.${domain}:80:${domain_ip}" "http://webmail.${domain}/${webpath}"
  131. assert_success
  132. assert_output --partial "$webproof"
  133. # Test HTTP
  134. run curl --location --silent --show-error --insecure --resolve "mail.${domain}:80:${domain_ip}" "http://mail.${domain}/${webpath}"
  135. assert_success
  136. assert_output --partial "$webproof"
  137. fi
  138. # Test HTTPS
  139. if [ "$SSL" = "yes" ]; then
  140. # Test HTTP with 301 redirect for some reasons due to 301 redirect it fails
  141. run curl --silent --show-error --insecure --resolve "webmail.${domain}:80:${domain_ip}" "http://webmail.${domain}/${webpath}"
  142. assert_success
  143. assert_output --partial "301 Moved Permanently"
  144. # Test HTTP with 301 redirect for some reasons due to 301 redirect it fails
  145. run curl --silent --show-error --insecure --resolve "mail.${domain}:80:${domain_ip}" "http://mail.${domain}/${webpath}"
  146. assert_success
  147. assert_output --partial "301 Moved Permanently"
  148. run v-list-mail-domain-ssl $user $domain
  149. assert_success
  150. run curl --location --silent --show-error --insecure --resolve "webmail.${domain}:443:${domain_ip}" "https://webmail.${domain}/${webpath}"
  151. assert_success
  152. assert_output --partial "$webproof"
  153. run curl --location --silent --show-error --insecure --resolve "mail.${domain}:443:${domain_ip}" "https://mail.${domain}/${webpath}"
  154. assert_success
  155. assert_output --partial "$webproof"
  156. fi
  157. }
  158. function validate_database(){
  159. local type=$1
  160. local database=$2
  161. local dbuser=$3
  162. local password=$4
  163. host_str=$(grep "HOST='localhost'" $HESTIA/conf/$type.conf)
  164. parse_object_kv_list "$host_str"
  165. if [ -z $PORT ]; then PORT=3306; fi
  166. refute [ -z "$HOST" ]
  167. refute [ -z "$PORT" ]
  168. refute [ -z "$database" ]
  169. refute [ -z "$dbuser" ]
  170. refute [ -z "$password" ]
  171. if [ "$type" = "mysql" ]; then
  172. # Create an connection to verify correct username / password has been set correctly
  173. tmpfile=$(mktemp /tmp/mysql.XXXXXX)
  174. echo "[client]">$tmpfile
  175. echo "host='$HOST'" >> $tmpfile
  176. echo "user='$dbuser'" >> $tmpfile
  177. echo "password='$password'" >> $tmpfile
  178. echo "port='$PORT'" >> $tmpfile
  179. chmod 600 $tmpfile
  180. sql_tmp=$(mktemp /tmp/query.XXXXXX)
  181. echo "show databases;" > $sql_tmp
  182. run mysql --defaults-file=$tmpfile < "$sql_tmp"
  183. assert_success
  184. assert_output --partial "$database"
  185. rm -f "$sql_tmp"
  186. rm -f "$tmpfile"
  187. else
  188. echo "*:*:*:$dbuser:$password" > /root/.pgpass
  189. chmod 600 /root/.pgpass
  190. run export PGPASSWORD="$password" | psql -h $HOST -U "$dbuser" -p $PORT -d "$database" --no-password -c "\l"
  191. assert_success
  192. rm /root/.pgpass
  193. fi
  194. }
  195. function check_ip_banned(){
  196. local ip=$1
  197. local chain=$2
  198. run grep "IP='$ip' CHAIN='$chain'" $HESTIA/data/firewall/banlist.conf
  199. assert_success
  200. assert_output --partial "$ip"
  201. }
  202. function check_ip_not_banned(){
  203. local ip=$1
  204. local chain=$2
  205. run grep "IP='$ip' CHAIN='$chain'" $HESTIA/data/firewall/banlist.conf
  206. assert_failure E_ARGS
  207. refute_output
  208. }
  209. #----------------------------------------------------------#
  210. # IP #
  211. #----------------------------------------------------------#
  212. @test "RDNS: Check reverse Dns validation" {
  213. # 1. PTR record for a IP should return a hostname(reverse) which in turn must resolve to the same IP addr(forward). (Full circle)
  214. # `-> not implemented in `is_ip_rdns_valid` yet and also not tested here
  215. # 2. Reject rPTR records that match generic dynamic IP pool patterns
  216. local ip="54.200.1.22"
  217. local rdns="ec2-54-200-1-22.us-west-2.compute.amazonaws.com"
  218. run is_ip_rdns_valid "$ip"
  219. assert_failure
  220. refute_output
  221. local rdns="ec2.54.200.1.22.us-west-2.compute.amazonaws.com"
  222. run is_ip_rdns_valid "$ip"
  223. assert_failure
  224. refute_output
  225. local rdns="ec2-22-1-200-54.us-west-2.compute.amazonaws.com"
  226. run is_ip_rdns_valid "$ip"
  227. assert_failure
  228. refute_output
  229. local rdns="ec2.22.1.200.54.us-west-2.compute.amazonaws.com"
  230. run is_ip_rdns_valid "$ip"
  231. assert_failure
  232. refute_output
  233. local rdns="ec2-200-54-1-22.us-west-2.compute.amazonaws.com"
  234. run is_ip_rdns_valid "$ip"
  235. assert_failure
  236. refute_output
  237. local rdns="panel-22.mydomain.tld"
  238. run is_ip_rdns_valid "$ip"
  239. assert_success
  240. assert_output "$rdns"
  241. local rdns="mail.mydomain.tld"
  242. run is_ip_rdns_valid "$ip"
  243. assert_success
  244. assert_output "$rdns"
  245. local rdns="mydomain.tld"
  246. run is_ip_rdns_valid "$ip"
  247. assert_success
  248. assert_output "$rdns"
  249. }
  250. #----------------------------------------------------------#
  251. # User #
  252. #----------------------------------------------------------#
  253. @test "User: Add new user" {
  254. run v-add-user $user $user $user@hestiacp.com default "Super Test"
  255. assert_success
  256. refute_output
  257. }
  258. @test "User: Add new user Failed 1" {
  259. run v-add-user 'jäap' $user $user@hestiacp2.com default "Super Test"
  260. assert_failure $E_INVALID
  261. assert_output --partial 'Error: invalid user format'
  262. }
  263. @test "User: Add new user Failed 2" {
  264. run v-add-user 'ëaap' $user $user@hestiacp2.com default "Super Test"
  265. assert_failure $E_INVALID
  266. assert_output --partial 'Error: invalid user format'
  267. }
  268. @test "User: Add new user Failed 3" {
  269. run v-add-user 'jaaẞ' $user $user@hestiacp2.com default "Super Test"
  270. assert_failure $E_INVALID
  271. assert_output --partial 'Error: invalid user format'
  272. }
  273. @test "User: Add new user Failed 4" {
  274. run v-add-user '1234' $user $user@hestiacp2.com default "Super Test"
  275. assert_failure $E_INVALID
  276. assert_output --partial 'Error: invalid user format'
  277. }
  278. @test "User: Add new user Failed 5" {
  279. run v-add-user '1aap' $user $user@hestiacp2.com default "Super Test"
  280. assert_failure $E_INVALID
  281. assert_output --partial 'Error: invalid user format'
  282. }
  283. @test "User: Add new user Failed 6" {
  284. run v-add-user 'ib_Buffer' $user $user@hestiacp2.com default "Super Test"
  285. assert_failure $E_INVALID
  286. assert_output --partial 'Error: The user name'
  287. }
  288. @test "User: Add new user Failed 7" {
  289. run v-add-user 'hello.com' $user $user@hestiacp2.com default "Super Test"
  290. assert_failure $E_INVALID
  291. assert_output --partial 'Error: invalid user format'
  292. }
  293. @test "User: Add new user Success 1" {
  294. run v-add-user 'jaap01' $user $user@hestiacp2.com default "Super Test"
  295. assert_success
  296. refute_output
  297. }
  298. @test "User: Add new user Success 1 Delete" {
  299. run v-delete-user jaap01
  300. assert_success
  301. refute_output
  302. }
  303. @test "User: Add new user Success 2" {
  304. run v-add-user 'buffer' $user $user@hestiacp2.com default "Super Test"
  305. assert_success
  306. refute_output
  307. }
  308. @test "User: Add new user Success 2 Delete" {
  309. run v-delete-user buffer
  310. assert_success
  311. refute_output
  312. }
  313. @test "User: Change user password" {
  314. run v-change-user-password "$user" "$userpass2"
  315. assert_success
  316. refute_output
  317. }
  318. @test "User: Change user email" {
  319. run v-change-user-contact "$user" tester@hestiacp.com
  320. assert_success
  321. refute_output
  322. }
  323. @test "User: Change user contact invalid email " {
  324. run v-change-user-contact "$user" testerhestiacp.com
  325. assert_failure $E_INVALID
  326. assert_output --partial 'Error: invalid email format'
  327. }
  328. @test "User: Change user name" {
  329. run v-change-user-name "$user" "New name"
  330. assert_success
  331. refute_output
  332. }
  333. @test "User: Change user shell" {
  334. run v-change-user-shell $user bash no
  335. assert_success
  336. refute_output
  337. run stat -c '%U' /home/$user
  338. assert_output --partial "$user"
  339. mount_file=$(systemd-escape -p --suffix=mount "/srv/jail/$user/home")
  340. assert_file_not_exist /etc/systemd/system/$mount_file
  341. }
  342. @test "User: Change user invalid shell" {
  343. run v-change-user-shell $user bashinvalid no
  344. assert_failure $E_INVALID
  345. assert_output --partial 'shell bashinvalid is not valid'
  346. }
  347. @test "User: Change user nologin" {
  348. run v-change-user-shell $user nologin no
  349. assert_success
  350. refute_output
  351. run stat -c '%U' /home/$user
  352. assert_output --partial 'root'
  353. mount_file=$(systemd-escape -p --suffix=mount "/srv/jail/$user/home/$user")
  354. assert_file_exist /etc/systemd/system/$mount_file
  355. }
  356. @test "User: Change user bash with jail" {
  357. run v-change-user-shell $user bash yes
  358. assert_success
  359. refute_output
  360. run stat -c '%U' /home/$user
  361. assert_output --partial 'root'
  362. mount_file=$(systemd-escape -p --suffix=mount "/srv/jail/$user/home/$user")
  363. assert_file_exist /etc/systemd/system/$mount_file
  364. }
  365. @test "User: Change user default ns" {
  366. run v-change-user-ns $user ns0.com ns1.com ns2.com ns3.com
  367. assert_success
  368. refute_output
  369. run v-list-user-ns "$user" plain
  370. assert_success
  371. assert_output --partial 'ns0.com'
  372. }
  373. @test "User: Change user language" {
  374. run v-change-user-language $user "nl"
  375. assert_success
  376. refute_output
  377. }
  378. @test "User: Change user language (Does not exists)" {
  379. run v-change-user-language $user "aa"
  380. assert_failure $E_NOTEXIST
  381. }
  382. @test "User: Change user sort order" {
  383. run v-change-user-sort-order $user "name"
  384. assert_success
  385. refute_output
  386. }
  387. @test "User: Change user theme" {
  388. run v-change-user-theme $user "flat"
  389. assert_success
  390. refute_output
  391. }
  392. @test "User: Change user theme (Does not exists)" {
  393. run v-change-user-theme $user "aa"
  394. assert_failure $E_NOTEXIST
  395. }
  396. @test "User: Change user login ip" {
  397. run v-change-user-config-value $user "LOGIN_USE_IPLIST" "1.2.3.4,1.2.3.5"
  398. assert_success
  399. refute_output
  400. }
  401. @test "User: Change user login ip (Failed)" {
  402. run v-change-user-config-value $user "LOGIN_USE_IPLIST" "'; echo 'jaap'; echo '"
  403. assert_failure $E_INVALID
  404. }
  405. @test "User: Add user notification" {
  406. run v-add-user-notification $user "Test message" "Message"
  407. assert_success
  408. refute_output
  409. }
  410. @test "User: Acknowledge user notification" {
  411. run v-acknowledge-user-notification $user 1
  412. assert_success
  413. refute_output
  414. }
  415. @test "User: List user notification" {
  416. run v-list-user-notifications $user csv
  417. assert_success
  418. assert_output --partial "1,\"Test message\",\"Message\",yes"
  419. }
  420. @test "User: Delete user notification" {
  421. run v-delete-user-notification admin 1
  422. assert_success
  423. refute_output
  424. }
  425. @test "User: Get User salt ipv4" {
  426. run v-get-user-salt $user 192.168.2.10
  427. assert_success
  428. }
  429. @test "User: Get User salt ipv4 invalid" {
  430. run v-get-user-salt $user 192.168.992.10
  431. assert_failure $E_INVALID
  432. }
  433. @test "User: Get User salt ipv6" {
  434. run v-get-user-salt $user "21DA:D3:0:2F3B:2AA:FF:FE28:9C5A"
  435. assert_success
  436. }
  437. @test "User: Get User salt ipv6 not exists" {
  438. run v-get-user-salt "notexists" "21DA:D3:0:2F3B:2AA:FF:FE28:9C5B"
  439. assert_failure $E_PASSWORD
  440. }
  441. @test "User: Get User salt ipv6 invalid" {
  442. run v-get-user-salt "$user" "21DA:D3:0:2F3B:ZZZ:FF:FE28:9C5B"
  443. assert_failure $E_INVALID
  444. }
  445. @test "User: Check user password" {
  446. run v-check-user-password $user "$userpass2" 192.168.2.10 'no'
  447. assert_success
  448. }
  449. @test "User: Check user password Incorrect password" {
  450. run v-check-user-password $user "$userpass1" 192.168.2.10 'no'
  451. assert_failure $E_PASSWORD
  452. }
  453. @test "User: Check user hash ipv4" {
  454. hash=$(v-check-user-password $user "$userpass2" 192.168.2.10 'yes');
  455. run v-check-user-hash $user $hash 192.168.2.10
  456. assert_success
  457. }
  458. @test "User: Check user hash ipv6" {
  459. hash=$(v-check-user-password $user "$userpass2" 21DA:D3:0:2F3B:2AA:FF:FE28:9C5A 'yes');
  460. run v-check-user-hash $user $hash 21DA:D3:0:2F3B:2AA:FF:FE28:9C5A
  461. assert_success
  462. }
  463. @test "User: Check user hash ipv6 incorrect" {
  464. run v-check-user-hash $user 'jafawefaweijawe' 21DA:D3:0:2F3B:2AA:FF:FE28:9C5A
  465. assert_failure $E_PASSWORD
  466. }
  467. #----------------------------------------------------------#
  468. # Cron #
  469. #----------------------------------------------------------#
  470. @test "Cron: Add cron job" {
  471. run v-add-cron-job $user 1 1 1 1 1 echo
  472. assert_success
  473. refute_output
  474. }
  475. @test "Cron: Suspend cron job" {
  476. run v-suspend-cron-job $user 1
  477. assert_success
  478. refute_output
  479. }
  480. @test "Cron: Unsuspend cron job" {
  481. run v-unsuspend-cron-job $user 1
  482. assert_success
  483. refute_output
  484. }
  485. @test "Cron: Delete cron job" {
  486. run v-delete-cron-job $user 1
  487. assert_success
  488. refute_output
  489. }
  490. @test "Cron: Add cron job (duplicate)" {
  491. run v-add-cron-job $user 1 1 1 1 1 echo 1
  492. assert_success
  493. refute_output
  494. run v-add-cron-job $user 1 1 1 1 1 echo 1
  495. assert_failure $E_EXISTS
  496. assert_output --partial 'JOB=1 already exists'
  497. }
  498. @test "Cron: Second cron job" {
  499. run v-add-cron-job $user 2 2 2 2 2 echo 2
  500. assert_success
  501. refute_output
  502. }
  503. @test "Cron: Two cron jobs must be listed" {
  504. run v-list-cron-jobs $user csv
  505. assert_success
  506. assert_line --partial '1,1,1,1,1,"echo",no'
  507. assert_line --partial '2,2,2,2,2,"echo",no'
  508. }
  509. @test "Cron: rebuild" {
  510. run v-rebuild-cron-jobs $user
  511. assert_success
  512. refute_output
  513. }
  514. #----------------------------------------------------------#
  515. # IP #
  516. #----------------------------------------------------------#
  517. @test "Ip: Add new ip on first interface" {
  518. interface=$(v-list-sys-interfaces plain | head -n 1)
  519. run ip link show dev $interface
  520. assert_success
  521. local a2_rpaf="/etc/$WEB_SYSTEM/mods-enabled/rpaf.conf"
  522. local a2_remoteip="/etc/$WEB_SYSTEM/mods-enabled/remoteip.conf"
  523. # Save initial state
  524. echo "interface=${interface}" >> /tmp/hestia-test-env.sh
  525. [ -f "$a2_rpaf" ] && file_hash1=$(cat $a2_rpaf |md5sum |cut -d" " -f1) && echo "a2_rpaf_hash='${file_hash1}'" >> /tmp/hestia-test-env.sh
  526. [ -f "$a2_remoteip" ] && file_hash2=$(cat $a2_remoteip |md5sum |cut -d" " -f1) && echo "a2_remoteip_hash='${file_hash2}'" >> /tmp/hestia-test-env.sh
  527. local ip="198.18.0.12"
  528. run v-add-sys-ip $ip 255.255.255.255 $interface $user
  529. assert_success
  530. refute_output
  531. assert_file_exist /etc/$WEB_SYSTEM/conf.d/$ip.conf
  532. assert_file_exist $HESTIA/data/ips/$ip
  533. assert_file_contains $HESTIA/data/ips/$ip "OWNER='$user'"
  534. assert_file_contains $HESTIA/data/ips/$ip "INTERFACE='$interface'"
  535. if [ -n "$PROXY_SYSTEM" ]; then
  536. assert_file_exist /etc/$PROXY_SYSTEM/conf.d/$ip.conf
  537. [ -f "$a2_rpaf" ] && assert_file_contains "$a2_rpaf" "RPAFproxy_ips.*$ip\b"
  538. [ -f "$a2_remoteip" ] && assert_file_contains "$a2_remoteip" "RemoteIPInternalProxy $ip\$"
  539. fi
  540. }
  541. @test "Ip: [Ubuntu] Netplan file updated" {
  542. # Skip if Debian
  543. if [ $(lsb_release -s -i) != "Ubuntu" ]; then
  544. skip
  545. fi
  546. # Test will fail if systemd (For example Proxmox) is used for setting ip addresses. How ever there is no "decent" way to check if Netplan is used except via the method used in v-add-sys-ip and there for breaking the reason to test this. How ever if the test used in v-add-sys-ip fails it still should check if it exists!
  547. assert_file_exist /etc/netplan/60-hestia.yaml
  548. # also check if file contains the newly added ip
  549. assert_file_contains /etc/netplan/60-hestia.yaml "$ip"
  550. }
  551. @test "Ip: [Debian] Netplan file updated" {
  552. # Skip with netplan
  553. if [ $(lsb_release -s -i) = "Ubuntu" ]; then
  554. skip
  555. fi
  556. assert_file_exist /etc/network/interfaces
  557. assert_file_contains /etc/network/interfaces "$ip"
  558. }
  559. @test "Ip: Add ip (duplicate)" {
  560. run v-add-sys-ip 198.18.0.12 255.255.255.255 $interface $user
  561. assert_failure $E_EXISTS
  562. }
  563. @test "Ip: Add extra ip" {
  564. local ip="198.18.0.121"
  565. run v-add-sys-ip $ip 255.255.255.255 $interface $user
  566. assert_success
  567. refute_output
  568. assert_file_exist /etc/$WEB_SYSTEM/conf.d/$ip.conf
  569. assert_file_exist $HESTIA/data/ips/$ip
  570. assert_file_contains $HESTIA/data/ips/$ip "OWNER='$user'"
  571. assert_file_contains $HESTIA/data/ips/$ip "INTERFACE='$interface'"
  572. if [ -n "$PROXY_SYSTEM" ]; then
  573. assert_file_exist /etc/$PROXY_SYSTEM/conf.d/$ip.conf
  574. local a2_rpaf="/etc/$WEB_SYSTEM/mods-enabled/rpaf.conf"
  575. [ -f "$a2_rpaf" ] && assert_file_contains "$a2_rpaf" "RPAFproxy_ips.*$ip\b"
  576. local a2_remoteip="/etc/$WEB_SYSTEM/mods-enabled/remoteip.conf"
  577. [ -f "$a2_remoteip" ] && assert_file_contains "$a2_remoteip" "RemoteIPInternalProxy $ip\$"
  578. fi
  579. }
  580. @test "Ip: Delete ip 198.18.0.12" {
  581. local ip="198.18.0.12"
  582. run v-delete-sys-ip $ip
  583. assert_success
  584. refute_output
  585. assert_file_not_exist /etc/$WEB_SYSTEM/conf.d/$ip.conf
  586. assert_file_not_exist $HESTIA/data/ips/$ip
  587. }
  588. @test "Ip: [Ubuntu] Netplan file changed" {
  589. # Skip if Debian
  590. if [ $(lsb_release -s -i) != "Ubuntu" ]; then
  591. skip
  592. fi
  593. ip="198.18.0.121"
  594. assert_file_exist /etc/netplan/60-hestia.yaml
  595. assert_file_contains /etc/netplan/60-hestia.yaml "$ip"
  596. }
  597. @test "Ip: Delete ip 198.18.0.121" {
  598. ip="198.18.0.121"
  599. run v-delete-sys-ip $ip
  600. assert_success
  601. refute_output
  602. assert_file_not_exist /etc/$WEB_SYSTEM/conf.d/$ip.conf
  603. assert_file_not_exist $HESTIA/data/ips/$ip
  604. if [ -n "$PROXY_SYSTEM" ]; then
  605. assert_file_not_exist /etc/$PROXY_SYSTEM/conf.d/$ip.conf
  606. fi
  607. # remoteip and rpaf config hashes must match the initial one
  608. if [ ! -z "$a2_rpaf_hash" ]; then
  609. local a2_rpaf="/etc/$WEB_SYSTEM/mods-enabled/rpaf.conf"
  610. file_hash=$(cat $a2_rpaf |md5sum |cut -d" " -f1)
  611. assert_equal "$file_hash" "$a2_rpaf_hash"
  612. fi
  613. if [ ! -z "$a2_remoteip_hash" ]; then
  614. local a2_remoteip="/etc/$WEB_SYSTEM/mods-enabled/remoteip.conf"
  615. file_hash=$(cat $a2_remoteip |md5sum |cut -d" " -f1)
  616. assert_equal "$file_hash" "$a2_remoteip_hash"
  617. fi
  618. }
  619. @test "Ip: Add IP for rest of the test" {
  620. local ip="198.18.0.125"
  621. run v-add-sys-ip $ip 255.255.255.255 $interface $user
  622. assert_success
  623. refute_output
  624. assert_file_exist /etc/$WEB_SYSTEM/conf.d/$ip.conf
  625. assert_file_exist $HESTIA/data/ips/$ip
  626. assert_file_contains $HESTIA/data/ips/$ip "OWNER='$user'"
  627. assert_file_contains $HESTIA/data/ips/$ip "INTERFACE='$interface'"
  628. if [ -n "$PROXY_SYSTEM" ]; then
  629. assert_file_exist /etc/$PROXY_SYSTEM/conf.d/$ip.conf
  630. local a2_rpaf="/etc/$WEB_SYSTEM/mods-enabled/rpaf.conf"
  631. [ -f "$a2_rpaf" ] && assert_file_contains "$a2_rpaf" "RPAFproxy_ips.*$ip\b"
  632. local a2_remoteip="/etc/$WEB_SYSTEM/mods-enabled/remoteip.conf"
  633. [ -f "$a2_remoteip" ] && assert_file_contains "$a2_remoteip" "RemoteIPInternalProxy $ip\$"
  634. fi
  635. }
  636. #----------------------------------------------------------#
  637. # WEB #
  638. #----------------------------------------------------------#
  639. @test "WEB: Add web domain" {
  640. run v-add-web-domain $user $domain 198.18.0.125
  641. assert_success
  642. refute_output
  643. echo -e "<?php\necho 'Hestia Test:'.(4*3);" > $HOMEDIR/$user/web/$domain/public_html/php-test.php
  644. validate_web_domain $user $domain 'Hestia Test:12' 'php-test.php'
  645. rm $HOMEDIR/$user/web/$domain/public_html/php-test.php
  646. }
  647. @test "WEB: Add web domain (duplicate)" {
  648. run v-add-web-domain $user $domain 198.18.0.125
  649. assert_failure $E_EXISTS
  650. }
  651. @test "WEB: Add web domain alias" {
  652. run v-add-web-domain-alias $user $domain v3.$domain
  653. assert_success
  654. refute_output
  655. }
  656. @test "WEB: Add web domain alias (duplicate)" {
  657. run v-add-web-domain-alias $user $domain v3.$domain
  658. assert_failure $E_EXISTS
  659. }
  660. @test "WEB: Add web domain wildcard alias" {
  661. run v-add-web-domain-alias $user $domain "*.$domain"
  662. assert_success
  663. refute_output
  664. }
  665. @test "WEB: Delete web domain wildcard alias" {
  666. run v-delete-web-domain-alias $user $domain "*.$domain"
  667. assert_success
  668. refute_output
  669. }
  670. @test "WEB: Add web domain stats" {
  671. run v-add-web-domain-stats $user $domain awstats
  672. assert_success
  673. refute_output
  674. }
  675. @test "WEB: Add web domain stats user" {
  676. skip
  677. run v-add-web-domain-stats-user $user $domain test m3g4p4ssw0rd
  678. assert_success
  679. refute_output
  680. }
  681. @test "WEB: Suspend web domain" {
  682. run v-suspend-web-domain $user $domain
  683. assert_success
  684. refute_output
  685. echo -e "<?php\necho 'Hestia Test:'.(4*3);" > $HOMEDIR/$user/web/$domain/public_html/php-test.php
  686. validate_web_domain $user $domain 'This site is currently suspended'
  687. validate_web_domain $user $domain 'This site is currently suspended' 'php-test.php'
  688. rm $HOMEDIR/$user/web/$domain/public_html/php-test.php
  689. }
  690. @test "WEB: Unsuspend web domain" {
  691. run v-unsuspend-web-domain $user $domain
  692. assert_success
  693. refute_output
  694. echo -e "<?php\necho 'Hestia Test:'.(4*3);" > $HOMEDIR/$user/web/$domain/public_html/php-test.php
  695. validate_web_domain $user $domain 'Hestia Test:12' 'php-test.php'
  696. rm $HOMEDIR/$user/web/$domain/public_html/php-test.php
  697. }
  698. @test "WEB: Add redirect to www.domain.com" {
  699. run v-add-web-domain-redirect $user $domain www.$domain 301
  700. assert_success
  701. refute_output
  702. run validate_headers_domain $user $domain "301"
  703. }
  704. @test "WEB: Delete redirect to www.domain.com" {
  705. run v-delete-web-domain-redirect $user $domain
  706. assert_success
  707. refute_output
  708. }
  709. @test "WEB: Enable Fast CGI Cache" {
  710. if [ "$WEB_SYSTEM" != "nginx" ]; then
  711. skip "FastCGI cache is not supported"
  712. fi
  713. run v-add-fastcgi-cache $user $domain '1m' yes
  714. assert_success
  715. refute_output
  716. echo -e "<?php\necho 'Hestia Test:'.(4*3);" > $HOMEDIR/$user/web/$domain/public_html/php-test.php
  717. run validate_headers_domain $user $domain "Miss"
  718. run validate_headers_domain $user $domain "Hit"
  719. rm $HOMEDIR/$user/web/$domain/public_html/php-test.php
  720. }
  721. @test "WEB: Disable Fast CGI Cache" {
  722. if [ "$WEB_SYSTEM" != "nginx" ]; then
  723. skip "FastCGI cache is not supported"
  724. fi
  725. run v-delete-fastcgi-cache $user $domain yes
  726. assert_success
  727. refute_output
  728. }
  729. @test "WEB: Generate Self signed certificate" {
  730. ssl=$(v-generate-ssl-cert "$domain" "info@$domain" US CA "Orange County" HestiaCP IT "mail.$domain" | tail -n1 | awk '{print $2}')
  731. echo $ssl;
  732. mv $ssl/$domain.crt /tmp/$domain.crt
  733. mv $ssl/$domain.key /tmp/$domain.key
  734. }
  735. @test "WEB: Add ssl" {
  736. # Use self signed certificates during last test
  737. run v-add-web-domain-ssl $user $domain /tmp
  738. assert_success
  739. refute_output
  740. }
  741. @test "WEB: Rebuild web domain" {
  742. run v-rebuild-web-domains $user
  743. assert_success
  744. refute_output
  745. }
  746. #----------------------------------------------------------#
  747. # IDN #
  748. #----------------------------------------------------------#
  749. @test "WEB: Add IDN domain UTF idn-tést.eu" {
  750. run v-add-web-domain $user idn-tést.eu 198.18.0.125
  751. assert_success
  752. refute_output
  753. assert_file_exist /home/$user/web/idn-tést.eu/public_html/index.html
  754. }
  755. @test "WEB: Add IDN domain ASCII idn-tést.eu" {
  756. # Expected to fail due to utf exists
  757. run v-add-web-domain $user "xn--idn-tst-fya.eu" 198.18.0.125
  758. assert_failure $E_EXISTS
  759. }
  760. @test "WEB: Generate Self signed certificate ASCII idn-tést.eu" {
  761. run v-generate-ssl-cert "xn--idn-tst-fya.eu" "info@xn--idn-tst-fya.eu" US CA "Orange County" HestiaCP IT "mail.xn--idn-tst-fya.eu"
  762. assert_success
  763. }
  764. @test "WEB: Delete IDN domain idn-tést.eu" {
  765. run v-delete-web-domain $user idn-tést.eu
  766. assert_success
  767. refute_output
  768. }
  769. @test "WEB: Add IDN domain UTF bløst.рф" {
  770. run v-add-web-domain $user bløst.рф 198.18.0.125
  771. assert_success
  772. refute_output
  773. }
  774. @test "WEB: Generate Self signed certificate ASCII bløst.рф" {
  775. run v-generate-ssl-cert "xn--blst-hra.xn--p1ai" "info@xn--blst-hra.xn--p1ai" US CA "Orange County" HestiaCP IT "mail.xn--blst-hra.xn--p1ai"
  776. assert_success
  777. }
  778. @test "WEB: Delete IDN domain bløst.рф" {
  779. run v-delete-web-domain $user bløst.рф
  780. assert_success
  781. refute_output
  782. }
  783. #----------------------------------------------------------#
  784. # MULTIPHP #
  785. #----------------------------------------------------------#
  786. @test "Multiphp: Default php Backend version" {
  787. def_phpver=$(multiphp_default_version)
  788. multi_domain="multiphp.${domain}"
  789. run v-add-web-domain $user $multi_domain 198.18.0.125
  790. assert_success
  791. refute_output
  792. echo -e "<?php\necho PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  793. validate_web_domain $user $multi_domain "$def_phpver" 'php-test.php'
  794. rm "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  795. }
  796. @test "Multiphp: Change backend version - PHP v5.6" {
  797. test_phpver='5.6'
  798. multi_domain="multiphp.${domain}"
  799. if [ ! -d "/etc/php/${test_phpver}/fpm/pool.d/" ]; then
  800. skip "PHP ${test_phpver} not installed"
  801. fi
  802. run v-change-web-domain-backend-tpl $user $multi_domain 'PHP-5_6' 'yes'
  803. assert_success
  804. refute_output
  805. # Changing web backend will create a php-fpm pool config in the corresponding php folder
  806. assert_file_exist "/etc/php/${test_phpver}/fpm/pool.d/${multi_domain}.conf"
  807. # A single php-fpm pool config file must be present
  808. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  809. assert_equal "$num_fpm_config_files" '1'
  810. echo -e "<?php\necho 'hestia-multiphptest:'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  811. validate_web_domain $user $multi_domain "hestia-multiphptest:$test_phpver" 'php-test.php'
  812. rm "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  813. }
  814. @test "Multiphp: Change backend version - PHP v7.0" {
  815. test_phpver='7.0'
  816. multi_domain="multiphp.${domain}"
  817. if [ ! -d "/etc/php/${test_phpver}/fpm/pool.d/" ]; then
  818. skip "PHP ${test_phpver} not installed"
  819. fi
  820. run v-change-web-domain-backend-tpl $user $multi_domain 'PHP-7_0' 'yes'
  821. assert_success
  822. refute_output
  823. # Changing web backend will create a php-fpm pool config in the corresponding php folder
  824. assert_file_exist "/etc/php/${test_phpver}/fpm/pool.d/${multi_domain}.conf"
  825. # A single php-fpm pool config file must be present
  826. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  827. assert_equal "$num_fpm_config_files" '1'
  828. echo -e "<?php\necho 'hestia-multiphptest:'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  829. validate_web_domain $user $multi_domain "hestia-multiphptest:$test_phpver" 'php-test.php'
  830. rm "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  831. }
  832. @test "Multiphp: Change backend version - PHP v7.1" {
  833. test_phpver='7.1'
  834. multi_domain="multiphp.${domain}"
  835. if [ ! -d "/etc/php/${test_phpver}/fpm/pool.d/" ]; then
  836. skip "PHP ${test_phpver} not installed"
  837. fi
  838. run v-change-web-domain-backend-tpl $user $multi_domain 'PHP-7_1' 'yes'
  839. assert_success
  840. refute_output
  841. # Changing web backend will create a php-fpm pool config in the corresponding php folder
  842. assert_file_exist "/etc/php/${test_phpver}/fpm/pool.d/${multi_domain}.conf"
  843. # A single php-fpm pool config file must be present
  844. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  845. assert_equal "$num_fpm_config_files" '1'
  846. echo -e "<?php\necho 'hestia-multiphptest:'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  847. validate_web_domain $user $multi_domain "hestia-multiphptest:$test_phpver" 'php-test.php'
  848. rm "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  849. }
  850. @test "Multiphp: Change backend version - PHP v7.2" {
  851. test_phpver='7.2'
  852. multi_domain="multiphp.${domain}"
  853. if [ ! -d "/etc/php/${test_phpver}/fpm/pool.d/" ]; then
  854. skip "PHP ${test_phpver} not installed"
  855. fi
  856. run v-change-web-domain-backend-tpl $user $multi_domain 'PHP-7_2' 'yes'
  857. assert_success
  858. refute_output
  859. # Changing web backend will create a php-fpm pool config in the corresponding php folder
  860. assert_file_exist "/etc/php/${test_phpver}/fpm/pool.d/${multi_domain}.conf"
  861. # A single php-fpm pool config file must be present
  862. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  863. assert_equal "$num_fpm_config_files" '1'
  864. echo -e "<?php\necho 'hestia-multiphptest:'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  865. validate_web_domain $user $multi_domain "hestia-multiphptest:$test_phpver" 'php-test.php'
  866. rm "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  867. }
  868. @test "Multiphp: Change backend version - PHP v7.3" {
  869. test_phpver='7.3'
  870. multi_domain="multiphp.${domain}"
  871. if [ ! -d "/etc/php/${test_phpver}/fpm/pool.d/" ]; then
  872. skip "PHP ${test_phpver} not installed"
  873. fi
  874. run v-change-web-domain-backend-tpl $user $multi_domain 'PHP-7_3' 'yes'
  875. assert_success
  876. refute_output
  877. # Changing web backend will create a php-fpm pool config in the corresponding php folder
  878. assert_file_exist "/etc/php/${test_phpver}/fpm/pool.d/${multi_domain}.conf"
  879. # A single php-fpm pool config file must be present
  880. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  881. assert_equal "$num_fpm_config_files" '1'
  882. echo -e "<?php\necho 'hestia-multiphptest:'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  883. validate_web_domain $user $multi_domain "hestia-multiphptest:$test_phpver" 'php-test.php'
  884. rm "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  885. }
  886. @test "Multiphp: Change backend version - PHP v7.4" {
  887. test_phpver='7.4'
  888. multi_domain="multiphp.${domain}"
  889. if [ ! -d "/etc/php/${test_phpver}/fpm/pool.d/" ]; then
  890. skip "PHP ${test_phpver} not installed"
  891. fi
  892. run v-change-web-domain-backend-tpl $user $multi_domain 'PHP-7_4' 'yes'
  893. assert_success
  894. refute_output
  895. # Changing web backend will create a php-fpm pool config in the corresponding php folder
  896. assert_file_exist "/etc/php/${test_phpver}/fpm/pool.d/${multi_domain}.conf"
  897. # A single php-fpm pool config file must be present
  898. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  899. assert_equal "$num_fpm_config_files" '1'
  900. echo -e "<?php\necho 'hestia-multiphptest:'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  901. validate_web_domain $user $multi_domain "hestia-multiphptest:$test_phpver" 'php-test.php'
  902. rm "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  903. }
  904. @test "Multiphp: Change backend version - PHP v8.0" {
  905. test_phpver='8.0'
  906. multi_domain="multiphp.${domain}"
  907. if [ ! -d "/etc/php/${test_phpver}/fpm/pool.d/" ]; then
  908. skip "PHP ${test_phpver} not installed"
  909. fi
  910. run v-change-web-domain-backend-tpl $user $multi_domain 'PHP-8_0' 'yes'
  911. assert_success
  912. refute_output
  913. # Changing web backend will create a php-fpm pool config in the corresponding php folder
  914. assert_file_exist "/etc/php/${test_phpver}/fpm/pool.d/${multi_domain}.conf"
  915. # A single php-fpm pool config file must be present
  916. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  917. assert_equal "$num_fpm_config_files" '1'
  918. echo -e "<?php\necho 'hestia-multiphptest:'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  919. validate_web_domain $user $multi_domain "hestia-multiphptest:$test_phpver" 'php-test.php'
  920. rm $HOMEDIR/$user/web/$multi_domain/public_html/php-test.php
  921. }
  922. @test "Multiphp: Change backend version - PHP v8.1" {
  923. test_phpver='8.1'
  924. multi_domain="multiphp.${domain}"
  925. if [ ! -d "/etc/php/${test_phpver}/fpm/pool.d/" ]; then
  926. skip "PHP ${test_phpver} not installed"
  927. fi
  928. run v-change-web-domain-backend-tpl $user $multi_domain 'PHP-8_1' 'yes'
  929. assert_success
  930. refute_output
  931. # Changing web backend will create a php-fpm pool config in the corresponding php folder
  932. assert_file_exist "/etc/php/${test_phpver}/fpm/pool.d/${multi_domain}.conf"
  933. # A single php-fpm pool config file must be present
  934. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  935. assert_equal "$num_fpm_config_files" '1'
  936. echo -e "<?php\necho 'hestia-multiphptest:'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  937. validate_web_domain $user $multi_domain "hestia-multiphptest:$test_phpver" 'php-test.php'
  938. rm $HOMEDIR/$user/web/$multi_domain/public_html/php-test.php
  939. }
  940. @test "Multiphp: Change backend version - PHP v8.2" {
  941. test_phpver='8.2'
  942. multi_domain="multiphp.${domain}"
  943. if [ ! -d "/etc/php/${test_phpver}/fpm/pool.d/" ]; then
  944. skip "PHP ${test_phpver} not installed"
  945. fi
  946. run v-change-web-domain-backend-tpl $user $multi_domain 'PHP-8_2' 'yes'
  947. assert_success
  948. refute_output
  949. # Changing web backend will create a php-fpm pool config in the corresponding php folder
  950. assert_file_exist "/etc/php/${test_phpver}/fpm/pool.d/${multi_domain}.conf"
  951. # A single php-fpm pool config file must be present
  952. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  953. assert_equal "$num_fpm_config_files" '1'
  954. echo -e "<?php\necho 'hestia-multiphptest:'.PHP_MAJOR_VERSION.'.'.PHP_MINOR_VERSION;" > "$HOMEDIR/$user/web/$multi_domain/public_html/php-test.php"
  955. validate_web_domain $user $multi_domain "hestia-multiphptest:$test_phpver" 'php-test.php'
  956. rm $HOMEDIR/$user/web/$multi_domain/public_html/php-test.php
  957. }
  958. @test "Multiphp: Cleanup" {
  959. multi_domain="multiphp.${domain}"
  960. run v-delete-web-domain $user $multi_domain 'yes'
  961. assert_success
  962. refute_output
  963. # No php-fpm pool config file must be present
  964. num_fpm_config_files="$(find -L /etc/php/ -name "${multi_domain}.conf" | wc -l)"
  965. assert_equal "$num_fpm_config_files" '0'
  966. }
  967. #----------------------------------------------------------#
  968. # CUSTOM DOCROOT #
  969. #----------------------------------------------------------#
  970. @test "Docroot: Self Subfolder" {
  971. docroot1_domain="docroot1.${domain}"
  972. run v-add-web-domain $user $docroot1_domain 198.18.0.125
  973. assert_success
  974. refute_output
  975. run v-add-fs-directory $user "$HOMEDIR/$user/web/$docroot1_domain/public_html/public/"
  976. assert_success
  977. refute_output
  978. run v-change-web-domain-docroot $user "$docroot1_domain" "$docroot1_domain" "/public"
  979. assert_success
  980. refute_output
  981. echo -e '<?php\necho "self-sub-".$_SERVER["HTTP_HOST"];' > "$HOMEDIR/$user/web/$docroot1_domain/public_html/public/php-test.php"
  982. validate_web_domain $user $docroot1_domain "self-sub-${docroot1_domain}" 'php-test.php'
  983. rm "$HOMEDIR/$user/web/$docroot1_domain/public_html/public/php-test.php"
  984. }
  985. @test "Docroot: Other domain subfolder" {
  986. docroot1_domain="docroot1.${domain}"
  987. docroot2_domain="docroot2.${domain}"
  988. run v-add-web-domain $user $docroot2_domain 198.18.0.125
  989. assert_success
  990. refute_output
  991. run v-add-fs-directory $user "$HOMEDIR/$user/web/$docroot2_domain/public_html/public/"
  992. assert_success
  993. refute_output
  994. run v-change-web-domain-docroot $user "$docroot1_domain" "$docroot2_domain" "/public"
  995. assert_success
  996. refute_output
  997. echo -e '<?php\necho "doc2-sub-".$_SERVER["HTTP_HOST"];' > "$HOMEDIR/$user/web/$docroot2_domain/public_html/public/php-test.php"
  998. validate_web_domain $user $docroot1_domain "doc2-sub-${docroot1_domain}" 'php-test.php'
  999. rm "$HOMEDIR/$user/web/$docroot2_domain/public_html/public/php-test.php"
  1000. }
  1001. @test "Docroot: Other domain root folder" {
  1002. docroot1_domain="docroot1.${domain}"
  1003. docroot2_domain="docroot2.${domain}"
  1004. run v-change-web-domain-docroot $user "$docroot1_domain" "$docroot2_domain"
  1005. assert_success
  1006. refute_output
  1007. echo -e '<?php\necho "doc2-root-".$_SERVER["HTTP_HOST"];' > "$HOMEDIR/$user/web/$docroot2_domain/public_html/php-test.php"
  1008. validate_web_domain $user $docroot1_domain "doc2-root-${docroot1_domain}" 'php-test.php'
  1009. rm "$HOMEDIR/$user/web/$docroot2_domain/public_html/php-test.php"
  1010. }
  1011. @test "Docroot: Reset" {
  1012. docroot1_domain="docroot1.${domain}"
  1013. run v-change-web-domain-docroot $user "$docroot1_domain" "default"
  1014. assert_success
  1015. refute_output
  1016. echo -e '<?php\necho "doc1-root-".$_SERVER["HTTP_HOST"];' > "$HOMEDIR/$user/web/$docroot1_domain/public_html/php-test.php"
  1017. validate_web_domain $user $docroot1_domain "doc1-root-${docroot1_domain}" 'php-test.php'
  1018. rm "$HOMEDIR/$user/web/$docroot1_domain/public_html/php-test.php"
  1019. }
  1020. @test "Docroot: Cleanup" {
  1021. docroot1_domain="docroot1.${domain}"
  1022. docroot2_domain="docroot2.${domain}"
  1023. run v-delete-web-domain $user $docroot1_domain
  1024. assert_success
  1025. refute_output
  1026. run v-delete-web-domain $user $docroot2_domain
  1027. assert_success
  1028. refute_output
  1029. }
  1030. #----------------------------------------------------------#
  1031. # DNS #
  1032. #----------------------------------------------------------#
  1033. @test "DNS: Add domain" {
  1034. run v-add-dns-domain $user $domain 198.18.0.125
  1035. assert_success
  1036. refute_output
  1037. }
  1038. @test "DNS: Add domain (duplicate)" {
  1039. run v-add-dns-domain $user $domain 198.18.0.125
  1040. assert_failure $E_EXISTS
  1041. }
  1042. @test "DNS: Add domain record" {
  1043. run v-add-dns-record $user $domain test A 198.18.0.125 '' 30
  1044. assert_success
  1045. refute_output
  1046. }
  1047. @test "DNS: Add domain record *.domain.com" {
  1048. run v-add-dns-record $user $domain '*' A 198.18.0.125 '' 40
  1049. assert_success
  1050. refute_output
  1051. }
  1052. @test "DNS: Add domain record *.domain.com with ID 0" {
  1053. run v-add-dns-record $user $domain '*' A 198.18.0.125 '' 0
  1054. assert_failure $E_INVALID
  1055. }
  1056. @test "DNS: Change DNS record" {
  1057. run v-change-dns-record $user $domain 30 test A 198.18.0.125 "" "" 1500
  1058. assert_success
  1059. refute_output
  1060. }
  1061. @test "DNS: Change DNS record (no update)" {
  1062. run v-change-dns-record $user $domain 30 test A 198.18.0.125 "" "" 1500
  1063. assert_failure $E_EXSIST
  1064. }
  1065. @test "DNS: Change DNS record id" {
  1066. run v-change-dns-record-id $user $domain 30 31
  1067. assert_success
  1068. refute_output
  1069. # Change back
  1070. run v-change-dns-record-id $user $domain 31 30
  1071. }
  1072. @test "DNS: Change DNS record id (no update)" {
  1073. run v-change-dns-record-id $user $domain 30 30
  1074. assert_failure $E_EXSIST
  1075. }
  1076. @test "DNS: Delete domain record" {
  1077. run v-delete-dns-record $user $domain 30
  1078. assert_success
  1079. refute_output
  1080. }
  1081. @test "DNS: Delete missing domain record" {
  1082. run v-delete-dns-record $user $domain 30
  1083. assert_failure $E_NOTEXIST
  1084. }
  1085. @test "DNS: Change domain expire date" {
  1086. run v-change-dns-domain-exp $user $domain 2020-01-01
  1087. assert_success
  1088. refute_output
  1089. }
  1090. @test "DNS: Add domain record MX" {
  1091. run v-add-dns-record $user $domain '@' MX mx.hestiacp.com '' 50
  1092. assert_success
  1093. refute_output
  1094. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "mx.hestiacp.com."
  1095. run v-change-dns-record $user $domain 50 '@' MX mx.hestia.com
  1096. assert_success
  1097. refute_output
  1098. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "mx.hestia.com."
  1099. run v-delete-dns-record $user $domain 50
  1100. assert_success
  1101. refute_output
  1102. }
  1103. @test "DNS: Add domain record NS" {
  1104. run v-delete-dns-record $user $domain 50
  1105. run v-add-dns-record $user $domain '@' NS mx.hestiacp.com '' 50
  1106. assert_success
  1107. refute_output
  1108. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "mx.hestiacp.com."
  1109. run v-change-dns-record $user $domain 50 '@' NS mx.hestia.com
  1110. assert_success
  1111. refute_output
  1112. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "mx.hestia.com."
  1113. run v-delete-dns-record $user $domain 50
  1114. assert_success
  1115. refute_output
  1116. }
  1117. @test "DNS: Add domain record SRV" {
  1118. run v-delete-dns-record $user $domain 50
  1119. run v-add-dns-record $user $domain '_test_domain' SRV mx.hestiacp.com '' 50
  1120. assert_success
  1121. refute_output
  1122. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "mx.hestiacp.com."
  1123. run v-change-dns-record $user $domain 50 '_test.domain' SRV mx.hestia.com
  1124. assert_success
  1125. refute_output
  1126. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "mx.hestia.com."
  1127. run v-delete-dns-record $user $domain 50
  1128. assert_success
  1129. refute_output
  1130. }
  1131. @test "DNS: Add domain record CNAME" {
  1132. run v-delete-dns-record $user $domain 50
  1133. run v-add-dns-record $user $domain 'mail' CNAME mx.hestiacp.com '' 50
  1134. assert_success
  1135. refute_output
  1136. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "mx.hestiacp.com."
  1137. run v-change-dns-record $user $domain 50 'mail' CNAME mx.hestia.com
  1138. assert_success
  1139. refute_output
  1140. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "mx.hestia.com."
  1141. run v-delete-dns-record $user $domain 50
  1142. assert_success
  1143. refute_output
  1144. }
  1145. @test "DNS: Check txt dns records type1" {
  1146. [ -z "$DNS_SYSTEM" ] && skip
  1147. run v-delete-dns-record $user $domain 50
  1148. record1_in='v=DMARC1; p=quarantine; pct=100'
  1149. record2_in='v=DMARC1; p=quarantine; pct=90'
  1150. record1_out='"v=DMARC1; p=quarantine; pct=100"'
  1151. record2_in='"v=DMARC1; p=quarantine; pct=90"'
  1152. # Test Create
  1153. run v-add-dns-record $user $domain 'test-long-txt' 'TXT' "$record1_in" '' 50
  1154. assert_success
  1155. refute_output
  1156. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "$record1_out"
  1157. # Test Edit
  1158. run v-change-dns-record $user $domain 50 'test-long-txt' 'TXT' "$record2_in"
  1159. assert_success
  1160. refute_output
  1161. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "$record2_out"
  1162. # Test Cleanup
  1163. run v-delete-dns-record $user $domain 50
  1164. assert_success
  1165. refute_output
  1166. }
  1167. @test "DNS: Check txt dns records type2" {
  1168. [ -z "$DNS_SYSTEM" ] && skip
  1169. run v-delete-dns-record $user $domain 50
  1170. record3_in='k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4+VEVsoTbl6tYLJlhozqAGju3IgpSVdBAS5LMyzpHP8/L0/PlyVRJnm2xECjVk3DRqCmelyIvmraw1VtFz2aH6DRlDhHsZghj1DmGhwN+7NkwIb4hEvmytMVAz1WyiLH6Rm6Iemm/ZCt1RhrAMUYLxHA9mJgky76YCcf8/cX35xC+1vd4a5U6YofAZeVP9DBvVgQ8ung4gVrOrQrXkU8QfVNAoXz5pfJo74GB7woIBFhZXsU6SKho7KnzT5inVCIOtWp7L5hyEnbySWQPHT2vAMCCAe2AY/Vv0N3HW14o8P3b4A6OU920wFB2kA7pkQNzO5OwH+HSttwG0PaIiQxYQIDAQAB'
  1171. record3_out='"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4+VEVsoTbl6tYLJlhozqAGju3IgpSVdBAS5LMyzpHP8/L0/PlyVRJnm2xECjVk3DRqCmelyIvmraw1VtFz2aH6DRlDhHsZghj1DmGhwN+7NkwIb4hEvmytMVAz1WyiLH6Rm6Iemm/ZCt1RhrAMUYLxHA9mJgky76YCcf8/cX35xC+1vd4a5U6YofAZeVP9DBvVgQ8ung4g""VrOrQrXkU8QfVNAoXz5pfJo74GB7woIBFhZXsU6SKho7KnzT5inVCIOtWp7L5hyEnbySWQPHT2vAMCCAe2AY/Vv0N3HW14o8P3b4A6OU920wFB2kA7pkQNzO5OwH+HSttwG0PaIiQxYQIDAQAB"'
  1172. record4_in='k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4+VEVsoTbl6tYLJlhozqAGju3IgpSVdBAS5LMyzpHP8/L0/PlyVRJnm2xECjVk3DRqCmelyIvmraw1VtFz2aH6DRlDhHsZghj1DmGhwN+7NkwIb4hEvmytMVAz1WyiLH6Rm6Iemm/ZCt1RhrAMUYLxHA9mJgky76YCcf8/cX35xC+1vd4a5U6YofAZeVP9DBvVgQ8ung4gVrOrQrXkU8QfVNAoXz5pfJo74GB7woIBFhZXsU6SKho7KnzT5inVCIOtWp7L5hyEnbySWQPHT2vAMCCAe2AY/Vv0N3HW14o8P3b4A6OU920wFB2kA7pkQNzO5OwH+HSttwG0PaIiQxYQIDAQA4'
  1173. record4_out='"k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4+VEVsoTbl6tYLJlhozqAGju3IgpSVdBAS5LMyzpHP8/L0/PlyVRJnm2xECjVk3DRqCmelyIvmraw1VtFz2aH6DRlDhHsZghj1DmGhwN+7NkwIb4hEvmytMVAz1WyiLH6Rm6Iemm/ZCt1RhrAMUYLxHA9mJgky76YCcf8/cX35xC+1vd4a5U6YofAZeVP9DBvVgQ8ung4g""VrOrQrXkU8QfVNAoXz5pfJo74GB7woIBFhZXsU6SKho7KnzT5inVCIOtWp7L5hyEnbySWQPHT2vAMCCAe2AY/Vv0N3HW14o8P3b4A6OU920wFB2kA7pkQNzO5OwH+HSttwG0PaIiQxYQIDAQA4"'
  1174. # Test Create
  1175. run v-add-dns-record $user $domain 'test-long-txt' 'TXT' "$record3_in" '' 50
  1176. assert_success
  1177. refute_output
  1178. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "$record3_out"
  1179. # Test Edit
  1180. run v-change-dns-record $user $domain 50 'test-long-txt' 'TXT' "$record4_in"
  1181. assert_success
  1182. refute_output
  1183. assert_file_contains "$HOMEDIR/$user/conf/dns/${domain}.db" "$record4_out"
  1184. # Test Cleanup
  1185. run v-delete-dns-record $user $domain 50
  1186. assert_success
  1187. refute_output
  1188. }
  1189. @test "DNS: Change domain ip" {
  1190. run v-change-dns-domain-ip $user $domain 127.0.0.1
  1191. assert_success
  1192. refute_output
  1193. }
  1194. @test "DNS: Suspend domain" {
  1195. run v-suspend-dns-domain $user $domain
  1196. assert_success
  1197. refute_output
  1198. }
  1199. @test "DNS: Unsuspend domain" {
  1200. run v-unsuspend-dns-domain $user $domain
  1201. assert_success
  1202. refute_output
  1203. }
  1204. @test "DNS: Rebuild" {
  1205. run v-rebuild-dns-domains $user
  1206. assert_success
  1207. refute_output
  1208. }
  1209. #----------------------------------------------------------#
  1210. # MAIL #
  1211. #----------------------------------------------------------#
  1212. @test "MAIL: Add domain" {
  1213. run v-add-mail-domain $user $domain
  1214. assert_success
  1215. refute_output
  1216. validate_mail_domain $user $domain
  1217. }
  1218. @test "MAIL: Add mail domain webmail client (Roundcube)" {
  1219. run v-add-mail-domain-webmail $user $domain "roundcube" "yes"
  1220. assert_success
  1221. refute_output
  1222. # echo -e "<?php\necho 'Server: ' . \$_SERVER['SERVER_SOFTWARE'];" > /var/lib/roundcube/check_server.php
  1223. validate_webmail_domain $user $domain 'Welcome to Roundcube Webmail'
  1224. # rm /var/lib/roundcube/check_server.php
  1225. }
  1226. @test "Mail: Add SSL to mail domain" {
  1227. # Use generated certificates during WEB Generate Self signed certificate
  1228. run v-add-mail-domain-ssl $user $domain /tmp
  1229. assert_success
  1230. refute_output
  1231. validate_webmail_domain $user $domain 'Welcome to Roundcube Webmail'
  1232. }
  1233. @test "MAIL: Add mail domain webmail client (SnappyMail)" {
  1234. if [ -z "$(echo $WEBMAIL_SYSTEM | grep -w "snappymail")" ]; then
  1235. skip "Webmail client SnappyMail not installed"
  1236. fi
  1237. run v-add-mail-domain-webmail $user $domain "snappymail" "yes"
  1238. assert_success
  1239. refute_output
  1240. validate_mail_domain $user $domain
  1241. validate_webmail_domain $user $domain 'SnappyMail Webmail'
  1242. }
  1243. @test "MAIL: Disable webmail client" {
  1244. run v-add-mail-domain-webmail $user $domain "disabled" "yes"
  1245. assert_success
  1246. refute_output
  1247. validate_mail_domain $user $domain
  1248. validate_webmail_domain $user $domain 'Success!'
  1249. run v-add-mail-domain-webmail $user $domain "roundcube" "yes"
  1250. assert_success
  1251. refute_output
  1252. }
  1253. @test "MAIL: Add domain (duplicate)" {
  1254. run v-add-mail-domain $user $domain
  1255. assert_failure $E_EXISTS
  1256. }
  1257. @test "MAIL: Add account" {
  1258. run v-add-mail-account $user $domain test "$userpass2"
  1259. assert_success
  1260. assert_file_contains /etc/exim4/domains/$domain/limits "test@$domain"
  1261. refute_output
  1262. }
  1263. @test "MAIL: Add account (duplicate)" {
  1264. run v-add-mail-account $user $domain test "$userpass2"
  1265. assert_failure $E_EXISTS
  1266. }
  1267. @test "MAIL: Add account 2" {
  1268. run v-add-mail-account $user $domain random "$userpass2"
  1269. assert_success
  1270. assert_file_contains /etc/exim4/domains/$domain/limits "random@$domain"
  1271. refute_output
  1272. }
  1273. @test "MAIL: Add account alias" {
  1274. run v-add-mail-account-alias $user $domain test hestiacprocks
  1275. assert_success
  1276. assert_file_contains /etc/exim4/domains/$domain/aliases "hestiacprocks@$domain"
  1277. refute_output
  1278. }
  1279. @test "MAIL: Add account alias 2" {
  1280. run v-add-mail-account-alias $user $domain test hestiacprocks2
  1281. assert_success
  1282. assert_file_contains /etc/exim4/domains/$domain/aliases "hestiacprocks2@$domain"
  1283. refute_output
  1284. }
  1285. @test "MAIL: Add account alias 3" {
  1286. run v-add-mail-account-alias $user $domain test hestiacp
  1287. assert_success
  1288. assert_file_contains /etc/exim4/domains/$domain/aliases "hestiacp@$domain"
  1289. refute_output
  1290. }
  1291. @test "MAIL: Add account 3" {
  1292. run v-add-mail-account $user $domain hestia "$userpass2"
  1293. assert_success
  1294. assert_file_contains /etc/exim4/domains/$domain/limits "hestia@$domain"
  1295. refute_output
  1296. }
  1297. @test "MAIL: Add account 4" {
  1298. run v-add-mail-account $user $domain hestiarocks3 "$userpass2"
  1299. assert_success
  1300. assert_file_contains /etc/exim4/domains/$domain/limits "hestiarocks3@$domain"
  1301. refute_output
  1302. }
  1303. @test "MAIL: Add account 5" {
  1304. run v-add-mail-account $user $domain 01 "$userpass2"
  1305. assert_success
  1306. assert_file_contains /etc/exim4/domains/$domain/limits "01@$domain"
  1307. refute_output
  1308. }
  1309. @test "MAIL: Add account 6" {
  1310. run v-add-mail-account $user $domain "0aa" "$userpass2"
  1311. assert_success
  1312. assert_file_contains /etc/exim4/domains/$domain/limits "0aa@$domain"
  1313. refute_output
  1314. }
  1315. @test "MAIL: Add account alias Invalid length" {
  1316. run v-add-mail-account-alias $user $domain test 'hestiacp-really-rocks-but-i-want-to-have-feature-xyz-and-i-want-it-now'
  1317. assert_failure $E_INVALID
  1318. }
  1319. @test "MAIL: Add account alias Invalid" {
  1320. run v-add-mail-account-alias $user $domain test 'test+123'
  1321. assert_failure $E_INVALID
  1322. }
  1323. @test "MAIL: Add account alias starting with -" {
  1324. run v-add-mail-account-alias $user $domain test '-test'
  1325. assert_success
  1326. }
  1327. @test "MAIL: Add account alias ending with -" {
  1328. run v-add-mail-account-alias $user $domain test 'test-'
  1329. assert_success
  1330. }
  1331. @test "MAIL: Add account alias Invalid 2" {
  1332. run v-add-mail-account-alias $user $domain test 'hestia@test'
  1333. assert_failure $E_INVALID
  1334. }
  1335. @test "MAIL: Add account alias (duplicate)" {
  1336. run v-add-mail-account-alias $user $domain test hestiacprocks
  1337. assert_failure $E_EXISTS
  1338. }
  1339. @test "MAIL: change mail account password" {
  1340. run curl -k -X POST -d "email=test@$domain&password=$userpass2&new=123456" https://localhost:8083/reset/mail/
  1341. assert_success
  1342. assert_output --partial "==ok=="
  1343. }
  1344. @test "MAIL: change mail account password (Incorrect PW)" {
  1345. run curl -k -X POST -d "email=test@$domain&password=$userpass2&new=123456" https://localhost:8083/reset/mail/
  1346. assert_success
  1347. assert_output --partial "error"
  1348. }
  1349. @test "MAIL: Change rate limit" {
  1350. run v-change-mail-account-rate-limit $user $domain test 10
  1351. assert_file_contains /etc/exim4/domains/$domain/limits "test@$domain:10"
  1352. }
  1353. @test "MAIL: Delete account" {
  1354. run v-delete-mail-account $user $domain test
  1355. assert_success
  1356. refute_output
  1357. }
  1358. @test "MAIL: Delete missing account" {
  1359. run v-delete-mail-account $user $domain test
  1360. assert_failure $E_NOTEXIST
  1361. }
  1362. @test "MAIL: Rebuild mail domain" {
  1363. run v-rebuild-mail-domains $user
  1364. assert_success
  1365. refute_output
  1366. }
  1367. @test "MAIL: Delete DKIM" {
  1368. run v-delete-mail-domain-dkim $user $domain
  1369. assert_success
  1370. refute_output
  1371. run grep "RECORD='_domainkey'" "${HESTIA}/data/users/${user}/dns/${domain}.conf"
  1372. assert_failure
  1373. refute_output
  1374. run grep "RECORD='mail._domainkey'" "${HESTIA}/data/users/${user}/dns/${domain}.conf"
  1375. assert_failure
  1376. refute_output
  1377. }
  1378. @test "MAIL: Add DKIM" {
  1379. run v-add-mail-domain-dkim $user $domain
  1380. assert_success
  1381. refute_output
  1382. run grep "RECORD='_domainkey'" "${HESTIA}/data/users/${user}/dns/${domain}.conf"
  1383. assert_success
  1384. assert_output --partial "RECORD='_domainkey' TYPE='TXT'"
  1385. run grep "RECORD='mail._domainkey'" "${HESTIA}/data/users/${user}/dns/${domain}.conf"
  1386. assert_success
  1387. assert_output --partial "RECORD='mail._domainkey' TYPE='TXT'"
  1388. }
  1389. @test "MAIL: Delete DKIM but preserve custom dkim records" {
  1390. run v-add-dns-record $user $domain 'k2._domainkey' 'TXT' 'v=DKIM1; k=rsa; p=123456'
  1391. assert_success
  1392. refute_output
  1393. run v-delete-mail-domain-dkim $user $domain
  1394. assert_success
  1395. refute_output
  1396. run grep "RECORD='k2._domainkey'" "${HESTIA}/data/users/${user}/dns/${domain}.conf"
  1397. assert_success
  1398. assert_output --partial "RECORD='k2._domainkey' TYPE='TXT'"
  1399. }
  1400. #----------------------------------------------------------#
  1401. # Limit possibilities adding different owner domain #
  1402. #----------------------------------------------------------#
  1403. @test "Allow Users: User can't add user.user2.com " {
  1404. # Case: admin company.tld
  1405. # users should not be allowed to add user.company.tld
  1406. run v-add-user $user2 $user2 $user@hestiacp.com default "Super Test"
  1407. assert_success
  1408. refute_output
  1409. run v-add-web-domain $user2 $rootdomain
  1410. assert_success
  1411. refute_output
  1412. run v-add-web-domain $user $subdomain
  1413. assert_failure $E_EXISTS
  1414. }
  1415. @test "Allow Users: User can't add user.user2.com as alias" {
  1416. run v-add-web-domain-alias $user $domain $subdomain
  1417. assert_failure $E_EXISTS
  1418. }
  1419. @test "Allow Users: User can't add user.user2.com as mail domain" {
  1420. run v-add-mail-domain $user $subdomain
  1421. assert_failure $E_EXISTS
  1422. }
  1423. @test "Allow Users: User can't add user.user2.com as dns domain" {
  1424. run v-add-dns-domain $user $subdomain 198.18.0.125
  1425. assert_failure $E_EXISTS
  1426. }
  1427. @test "Allow Users: Set Allow users" {
  1428. # Allow user to yes allows
  1429. # Case: admin company.tld
  1430. # users are allowed to add user.company.tld
  1431. run v-add-web-domain-allow-users $user2 $rootdomain
  1432. assert_success
  1433. refute_output
  1434. }
  1435. @test "Allow Users: User can add user.user2.com" {
  1436. run v-add-web-domain $user $subdomain
  1437. assert_success
  1438. refute_output
  1439. }
  1440. @test "Allow Users: User can add user.user2.com as alias" {
  1441. run v-delete-web-domain $user $subdomain
  1442. assert_success
  1443. refute_output
  1444. run v-add-web-domain-alias $user $domain $subdomain
  1445. assert_success
  1446. refute_output
  1447. }
  1448. @test "Allow Users: User can add user.user2.com as mail domain" {
  1449. run v-add-mail-domain $user $subdomain
  1450. assert_success
  1451. refute_output
  1452. }
  1453. @test "Allow Users: User can add user.user2.com as dns domain" {
  1454. run v-add-dns-domain $user $subdomain 198.18.0.125
  1455. assert_success
  1456. refute_output
  1457. }
  1458. @test "Allow Users: Cleanup tests" {
  1459. run v-delete-dns-domain $user $subdomain
  1460. assert_success
  1461. refute_output
  1462. run v-delete-mail-domain $user $subdomain
  1463. assert_success
  1464. refute_output
  1465. }
  1466. @test "Allow Users: Set Allow users no" {
  1467. run v-delete-web-domain-alias $user $domain $subdomain
  1468. assert_success
  1469. refute_output
  1470. run v-delete-web-domain-allow-users $user2 $rootdomain
  1471. assert_success
  1472. refute_output
  1473. }
  1474. @test "Allow Users: User can't add user.user2.com again" {
  1475. run v-add-web-domain $user $subdomain
  1476. assert_failure $E_EXISTS
  1477. }
  1478. @test "Allow Users: user2 can add user.user2.com again" {
  1479. run v-add-web-domain $user2 $subdomain
  1480. assert_success
  1481. refute_output
  1482. }
  1483. #----------------------------------------------------------#
  1484. # DB #
  1485. #----------------------------------------------------------#
  1486. @test "MYSQL: Add database" {
  1487. run v-add-database $user database dbuser 1234 mysql
  1488. assert_success
  1489. refute_output
  1490. # validate_database mysql database_name database_user password
  1491. validate_database mysql $database $dbuser 1234
  1492. }
  1493. @test "MYSQL: Add Database (Duplicate)" {
  1494. run v-add-database $user database dbuser 1234 mysql
  1495. assert_failure $E_EXISTS
  1496. }
  1497. @test "MYSQL: Rebuild Database" {
  1498. run v-rebuild-database $user $database
  1499. assert_success
  1500. refute_output
  1501. }
  1502. @test "MYSQL: Change database user password" {
  1503. run v-change-database-password $user $database 123456
  1504. assert_success
  1505. refute_output
  1506. validate_database mysql $database $dbuser 123456
  1507. }
  1508. @test "MYSQL: Change database user" {
  1509. run v-change-database-user $user $database database
  1510. assert_success
  1511. refute_output
  1512. validate_database mysql $database $database 123456
  1513. }
  1514. @test "MYSQL: Suspend database" {
  1515. run v-suspend-database $user $database
  1516. assert_success
  1517. refute_output
  1518. }
  1519. @test "MYSQL: Unsuspend database" {
  1520. run v-unsuspend-database $user $database
  1521. assert_success
  1522. refute_output
  1523. }
  1524. @test "MYSQL: Delete database" {
  1525. run v-delete-database $user $database
  1526. assert_success
  1527. refute_output
  1528. }
  1529. @test "MYSQL: Delete missing database" {
  1530. run v-delete-database $user $database
  1531. assert_failure $E_NOTEXIST
  1532. }
  1533. @test "PGSQL: Add database invalid user" {
  1534. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1535. skip "PostGreSQL is not installed"
  1536. fi
  1537. run v-add-database "$user" "database" "dbuser" "1234ABCD" "pgsql"
  1538. assert_failure $E_INVALID
  1539. }
  1540. @test "PGSQL: Add database" {
  1541. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1542. skip "PostGreSQL is not installed"
  1543. fi
  1544. run v-add-user $pguser $pguser $user@hestiacp.com default "Super Test"
  1545. run v-add-database "$pguser" "database" "dbuser" "1234ABCD" "pgsql"
  1546. assert_success
  1547. refute_output
  1548. # validate_database pgsql $pgdatabase $pgdbuser "1234ABCD"
  1549. }
  1550. @test "PGSQL: Add Database (Duplicate)" {
  1551. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1552. skip "PostGreSQL is not installed"
  1553. fi
  1554. run v-add-database "$pguser" "database" "dbuser" "1234ABCD" "pgsql"
  1555. assert_failure $E_EXISTS
  1556. }
  1557. @test "PGSQL: Rebuild Database" {
  1558. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1559. skip "PostGreSQL is not installed"
  1560. fi
  1561. run v-rebuild-database $pguser $pgdatabase
  1562. assert_success
  1563. refute_output
  1564. }
  1565. @test "PGSQL: Change database user password" {
  1566. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1567. skip "PostGreSQL is not installed"
  1568. fi
  1569. run v-change-database-password $pguser $pgdatabase "123456"
  1570. assert_success
  1571. refute_output
  1572. # validate_database pgsql $pgdatabase $pgdbuser "123456"
  1573. }
  1574. @test "PGSQL: Suspend database" {
  1575. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1576. skip "PostGreSQL is not installed"
  1577. fi
  1578. run v-suspend-database $pguser $pgdatabase
  1579. assert_success
  1580. refute_output
  1581. }
  1582. @test "PGSQL: Unsuspend database" {
  1583. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1584. skip "PostGreSQL is not installed"
  1585. fi
  1586. run v-unsuspend-database $pguser $pgdatabase
  1587. assert_success
  1588. refute_output
  1589. }
  1590. @test "PGSQL: Change database user" {
  1591. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1592. skip "PostGreSQL is not installed"
  1593. fi
  1594. skip
  1595. run v-change-database-user $pguser $pgdatabase database
  1596. assert_success
  1597. refute_output
  1598. validate_database pgsql $pgdatabase $pgdatabase 123456
  1599. }
  1600. @test "PGSQL: Delete database" {
  1601. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1602. skip "PostGreSQL is not installed"
  1603. fi
  1604. run v-delete-database $pguser $pgdatabase
  1605. assert_success
  1606. refute_output
  1607. }
  1608. @test "PGSQL: Delete missing database" {
  1609. if [ -z "$(echo $DB_SYSTEM | grep -w "pgsql")" ]; then
  1610. skip "PostGreSQL is not installed"
  1611. fi
  1612. run v-delete-database $pguser $pgdatabase
  1613. assert_failure $E_NOTEXIST
  1614. run v-delete-user $pguser
  1615. }
  1616. #----------------------------------------------------------#
  1617. # System #
  1618. #----------------------------------------------------------#
  1619. @test "System: Set/Enable SMTP account for internal mail" {
  1620. run v-add-sys-smtp $domain 587 STARTTLS info@$domain 1234-test noreply@$domain
  1621. assert_success
  1622. refute_output
  1623. }
  1624. @test "System: Disable SMTP account for internal mail" {
  1625. run v-delete-sys-smtp
  1626. assert_success
  1627. refute_output
  1628. }
  1629. @test "System: Set/Enable SMTP relay" {
  1630. run v-add-sys-smtp-relay $domain info@$domain 1234-test 587
  1631. assert_success
  1632. refute_output
  1633. assert_file_exist /etc/exim4/smtp_relay.conf
  1634. }
  1635. @test "System: Delete SMTP relay" {
  1636. run v-delete-sys-smtp-relay
  1637. assert_success
  1638. refute_output
  1639. assert_file_not_exist /etc/exim4/smtp_relay.conf
  1640. }
  1641. #----------------------------------------------------------#
  1642. # Firewall #
  1643. #----------------------------------------------------------#
  1644. @test "Firewall: Add ip to banlist" {
  1645. run v-add-firewall-ban '1.2.3.4' 'HESTIA'
  1646. assert_success
  1647. refute_output
  1648. check_ip_banned '1.2.3.4' 'HESTIA'
  1649. }
  1650. @test "Firewall: Delete ip to banlist" {
  1651. run v-delete-firewall-ban '1.2.3.4' 'HESTIA'
  1652. assert_success
  1653. refute_output
  1654. check_ip_not_banned '1.2.3.4' 'HESTIA'
  1655. }
  1656. @test "Firewall: Add ip to banlist for ALL" {
  1657. run v-add-firewall-ban '1.2.3.4' 'HESTIA'
  1658. assert_success
  1659. refute_output
  1660. run v-add-firewall-ban '1.2.3.4' 'MAIL'
  1661. assert_success
  1662. refute_output
  1663. check_ip_banned '1.2.3.4' 'HESTIA'
  1664. }
  1665. @test "Firewall: Delete ip to banlist CHAIN = ALL" {
  1666. run v-delete-firewall-ban '1.2.3.4' 'ALL'
  1667. assert_success
  1668. refute_output
  1669. check_ip_not_banned '1.2.3.4' 'HESTIA'
  1670. }
  1671. @test "Test Whitelist Fail2ban" {
  1672. echo "1.2.3.4" >> $HESTIA/data/firewall/excludes.conf
  1673. run v-add-firewall-ban '1.2.3.4' 'HESTIA'
  1674. rm $HESTIA/data/firewall/excludes.conf
  1675. check_ip_not_banned '1.2.3.4' 'HESTIA'
  1676. }
  1677. @test "Test create ipset" {
  1678. run v-add-firewall-ipset "country-nl" "https://raw.githubusercontent.com/ipverse/rir-ip/master/country/nl/ipv4-aggregated.txt" v4 yes
  1679. assert_success
  1680. refute_output
  1681. }
  1682. @test "Create firewall with Ipset" {
  1683. run v-add-firewall-rule 'DROP' 'ipset:country-nl' '8083,22' 'TCP' 'Test'
  1684. assert_success
  1685. refute_output
  1686. }
  1687. @test "List firewall rules" {
  1688. run v-list-firewall csv
  1689. assert_success
  1690. assert_line --partial '11,DROP,TCP,8083,22,ipset:country-nl'
  1691. }
  1692. @test "Delete firewall with Ipset" {
  1693. run v-delete-firewall-rule '11'
  1694. assert_success
  1695. refute_output
  1696. }
  1697. @test "Test delete ipset" {
  1698. run v-delete-firewall-ipset "country-nl"
  1699. assert_success
  1700. refute_output
  1701. }
  1702. #----------------------------------------------------------#
  1703. # PACKAGE #
  1704. #----------------------------------------------------------#
  1705. @test "Package: Create new Package" {
  1706. cp $HESTIA/data/packages/default.pkg /tmp/package
  1707. run v-add-user-package /tmp/package hestiatest
  1708. assert_success
  1709. refute_output
  1710. }
  1711. @test "Package: Assign user to new Package" {
  1712. run v-change-user-package $user hestiatest
  1713. assert_success
  1714. refute_output
  1715. }
  1716. @test "Package: Create new package (Duplicate)" {
  1717. sed -i "s/BANDWIDTH='unlimited'/BANDWIDTH='100'/g" /tmp/package
  1718. run v-add-user-package /tmp/package hestiatest
  1719. assert_failure $E_EXISTS
  1720. }
  1721. @test "Package: Update new Package" {
  1722. sed -i "s/BANDWIDTH='unlimited'/BANDWIDTH='100'/g" /tmp/package
  1723. run v-add-user-package /tmp/package hestiatest yes
  1724. assert_success
  1725. refute_output
  1726. }
  1727. @test "Package: Update package of user" {
  1728. run v-change-user-package $user hestiatest
  1729. assert_success
  1730. refute_output
  1731. run grep "BANDWIDTH='100'" $HESTIA/data/users/$user/user.conf
  1732. assert_success
  1733. assert_output --partial "100"
  1734. }
  1735. @test "Package: Copy package Not Exists" {
  1736. run v-copy-user-package hestiadoesnotexists hestiatest2
  1737. assert_failure $E_NOTEXIST
  1738. }
  1739. @test "Package: Copy package" {
  1740. run v-copy-user-package hestiatest hestiatest2
  1741. assert_success
  1742. refute_output
  1743. }
  1744. @test "Package: Copy package Exists" {
  1745. run v-copy-user-package hestiatest hestiatest2
  1746. assert_failure $E_EXISTS
  1747. }
  1748. @test "Package: Delete package" {
  1749. run v-delete-user-package hestiatest
  1750. run v-delete-user-package hestiatest2
  1751. rm /tmp/package
  1752. assert_success
  1753. refute_output
  1754. run grep "BANDWIDTH='unlimited'" $HESTIA/data/users/$user/user.conf
  1755. assert_success
  1756. assert_output --partial "unlimited"
  1757. }
  1758. #----------------------------------------------------------#
  1759. # Backup user #
  1760. #----------------------------------------------------------#
  1761. @test "Backup: Backup user" {
  1762. run v-backup-user $user
  1763. assert_success
  1764. }
  1765. @test "Backup: List Backups" {
  1766. run v-list-user-backups $user plain
  1767. assert_success
  1768. assert_output --partial "$user"
  1769. }
  1770. @test "Backup: Delete backups" {
  1771. run v-delete-user-backup $user $(v-list-user-backups $user plain | cut -f1)
  1772. assert_success
  1773. run rm /backup/$user.log
  1774. }
  1775. #----------------------------------------------------------#
  1776. # Change owner scripts #
  1777. #----------------------------------------------------------#
  1778. @test "Change: Change domain owner" {
  1779. run v-change-domain-owner $domain $user2
  1780. assert_success
  1781. run v-restart-web
  1782. run v-restart-proxy
  1783. }
  1784. @test "Change: Add database" {
  1785. run v-add-database $user database dbuser 1234 mysql
  1786. assert_success
  1787. refute_output
  1788. # validate_database mysql database_name database_user password
  1789. validate_database mysql $database $dbuser 1234
  1790. }
  1791. @test "Change: Change database owner" {
  1792. run v-change-database-owner $database $user2
  1793. assert_success
  1794. validate_database mysql test-5286_database test-5286_dbuser 1234
  1795. }
  1796. @test "Change: Delete database" {
  1797. run v-delete-database $user2 test-5286_database
  1798. assert_success
  1799. refute_output
  1800. }
  1801. #----------------------------------------------------------#
  1802. # CLEANUP #
  1803. #----------------------------------------------------------#
  1804. @test "Mail: Delete domain" {
  1805. run v-delete-mail-domain $user2 $domain
  1806. assert_success
  1807. refute_output
  1808. }
  1809. @test "DNS: Delete domain" {
  1810. run v-delete-dns-domain $user2 $domain
  1811. assert_success
  1812. refute_output
  1813. }
  1814. @test "WEB: Delete domain" {
  1815. run v-delete-web-domain $user2 $domain
  1816. assert_success
  1817. refute_output
  1818. }
  1819. @test "Delete user" {
  1820. run v-delete-user $user
  1821. assert_success
  1822. refute_output
  1823. }
  1824. @test "Delete user2" {
  1825. run v-delete-user $user2
  1826. assert_success
  1827. refute_output
  1828. }
  1829. @test "Ip: Delete the test IP" {
  1830. run v-delete-sys-ip 198.18.0.125
  1831. assert_success
  1832. refute_output
  1833. }
  1834. @test 'assert()' {
  1835. touch '/var/log/test.log'
  1836. assert [ -e '/var/log/test.log' ]
  1837. }