Skip to content

Commit 3a9f926

Browse files
authored
Merge pull request hestiacp#629 from Lupul/dev-0727-app-wizard
Web App Installer
2 parents a848955 + 6d3874a commit 3a9f926

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1850
-6
lines changed

bin/v-extract-fs-archive

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
#!/bin/bash
22
# info: archive to directory
3-
# options: USER ARCHIVE DIRECTORY
3+
# options: USER ARCHIVE DIRECTORY [SELECTED_DIR] [STRIP] [TEST]
44
#
55
# The function extracts archive into directory on the file system
66

77
user=$1
88
src_file=$2
99
dst_dir=$3
1010
selected_dir=$4
11-
test=$5
11+
strip=$5
12+
test=$6
1213

1314
# Includes
1415
source $HESTIA/func/main.sh
@@ -17,7 +18,7 @@ source $HESTIA/func/main.sh
1718
# Verifications #
1819
#----------------------------------------------------------#
1920

20-
check_args '3' "$#" 'USER ARCHIVE DIRECTORY [SELECTED_DIR] [TEST]'
21+
check_args '3' "$#" 'USER ARCHIVE DIRECTORY [SELECTED_DIR] [STRIP] [TEST]'
2122
is_format_valid 'user'
2223
is_object_valid 'user' 'USER' "$user"
2324

@@ -48,12 +49,16 @@ if [ -z "$(echo $rpath |egrep "^/tmp|^$homedir")" ]; then
4849
exit 2
4950
fi
5051

52+
if [ ! -z "$strip" ]; then
53+
is_int_format_valid "$strip" 'strip-components'
54+
tar_strip_level="--strip-components $strip"
55+
fi
5156
# Extracting gziped archive
5257
if [ ! -z "$(echo $src_file |egrep -i '.tgz|.tar.gz')" ]; then
5358
x='yes'
5459
if [ -z "$test" ] || [ "$test" = "no" ]; then
5560
setpriv --init-groups --reuid "$user" --regid "$user" -- mkdir -p "$dst_dir" >/dev/null 2>&1
56-
setpriv --init-groups --reuid "$user" --regid "$user" -- tar -xzf "$src_file" -C "$dst_dir" --no-wildcards "$selected_dir" >/dev/null 2>&1
61+
setpriv --init-groups --reuid "$user" --regid "$user" -- tar -xzf "$src_file" -C "$dst_dir" --no-wildcards "$selected_dir" $tar_strip_level >/dev/null 2>&1
5762
rc=$?
5863
else
5964
setpriv --init-groups --reuid "$user" --regid "$user" -- tar -tf "$src_file" --no-wildcards "$selected_dir" >/dev/null 2>&1
@@ -67,7 +72,7 @@ if [ ! -z "$(echo $src_file |egrep -i '.tbz|.tar.bz')" ]; then
6772
x='yes'
6873
if [ -z "$test" ] || [ "$test" = "no" ]; then
6974
setpriv --init-groups --reuid "$user" --regid "$user" -- mkdir -p "$dst_dir" >/dev/null 2>&1
70-
setpriv --init-groups --reuid "$user" --regid "$user" -- tar -xjf "$src_file" -C "$dst_dir" --no-wildcards "$selected_dir" >/dev/null 2>&1
75+
setpriv --init-groups --reuid "$user" --regid "$user" -- tar -xjf "$src_file" -C "$dst_dir" --no-wildcards "$selected_dir" $tar_strip_level >/dev/null 2>&1
7176
rc=$?
7277
else
7378
setpriv --init-groups --reuid "$user" --regid "$user" -- tar -tf "$src_file" --no-wildcards "$selected_dir" >/dev/null 2>&1
@@ -111,7 +116,7 @@ if [ ! -z "$(echo $src_file |grep -i '.tar')" ] && [ -z "$x" ]; then
111116
x='yes'
112117
if [ -z "$test" ] || [ "$test" = "no" ]; then
113118
setpriv --init-groups --reuid "$user" --regid "$user" -- mkdir -p "$dst_dir" >/dev/null 2>&1
114-
setpriv --init-groups --reuid "$user" --regid "$user" -- tar -xf "$src_file" -C "$dst_dir" --no-wildcards "$selected_dir" >/dev/null 2>&1
119+
setpriv --init-groups --reuid "$user" --regid "$user" -- tar -xf "$src_file" -C "$dst_dir" --no-wildcards "$selected_dir" $tar_strip_level >/dev/null 2>&1
115120
rc=$?
116121
else
117122
setpriv --init-groups --reuid "$user" --regid "$user" -- tar -tf "$src_file" --no-wildcards "$selected_dir" >/dev/null 2>&1

bin/v-run-cli-cmd

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/bin/bash
2+
# info: run cli command
3+
# options: USER FILE
4+
#
5+
# The function runs a limited list of cli commands with dropped privileges as the specific hestia user
6+
7+
user=$1
8+
clicmd=$2
9+
10+
# Includes
11+
source $HESTIA/func/main.sh
12+
13+
#----------------------------------------------------------#
14+
# Verifications #
15+
#----------------------------------------------------------#
16+
17+
check_args '2' "$#" 'USER CMD [ARGS]'
18+
is_format_valid 'user'
19+
is_object_valid 'user' 'USER' "$user"
20+
21+
# Checking user homedir
22+
homedir=$(grep "^$user:" /etc/passwd | cut -f 6 -d :)
23+
if [ -z $homedir ]; then
24+
check_result $E_NOTEXIST "Error: user home directory doesn't exist"
25+
fi
26+
27+
if [ "$clicmd" = "composer" ]; then
28+
realcmd="$homedir/.composer/composer"
29+
else
30+
realcmd="$(which "$clicmd")"
31+
check_result $? "Unknown cli command" $E_NOTEXIST
32+
fi
33+
34+
if [ ! -x "$realcmd" ]; then
35+
check_result $E_NOTEXIST "Error: Cli command does not exist"
36+
fi
37+
38+
if [ "$realcmd" != '/bin/ps' -a \
39+
"$realcmd" != '/bin/ls' -a \
40+
"$realcmd" != '/bin/tar' -a \
41+
"$realcmd" != '/bin/zip' -a \
42+
"$realcmd" != '/usr/bin/unzip' -a \
43+
"$realcmd" != '/bin/gzip' -a \
44+
"$realcmd" != '/bin/gunzip' -a \
45+
"$realcmd" != '/bin/mkdir' -a \
46+
"$realcmd" != '/usr/bin/find' -a \
47+
"$realcmd" != '/bin/grep' -a \
48+
"$realcmd" != '/bin/egrep' -a \
49+
"$realcmd" != '/bin/sed' -a \
50+
"$realcmd" != '/bin/cat' -a \
51+
"$realcmd" != '/usr/bin/php5.6' -a \
52+
"$realcmd" != '/usr/bin/php7.0' -a \
53+
"$realcmd" != '/usr/bin/php7.1' -a \
54+
"$realcmd" != '/usr/bin/php7.2' -a \
55+
"$realcmd" != '/usr/bin/php7.3' -a \
56+
"$realcmd" != '/usr/bin/php7.4' -a \
57+
"$realcmd" != '/usr/bin/php' -a \
58+
"$clicmd" != 'composer' ]; then
59+
check_result $E_FORBIDEN "Error: Cli command not enabled"
60+
fi
61+
62+
all_scriptargs=("$@")
63+
for ((I=3; I <= $# ; I++)); do
64+
cmdArgs="$cmdArgs ${all_scriptargs[${I}-1]}"
65+
done
66+
67+
setpriv --init-groups --reuid "$user" --regid "$user" -- $realcmd $cmdArgs
68+
if [ $? -ne 0 ]; then
69+
echo "Error: cmd exited with errors"
70+
exit 3
71+
fi
72+
73+
# Logging
74+
log_event "$OK" "$ARGUMENTS"
75+
76+
exit

install/deb/templates/web/nginx/php-fpm/opencart.stpl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ server {
3737
rewrite ^/(.+)$ /index.php?_route_=$1 last;
3838
}
3939

40+
location /storage/ {
41+
deny all;
42+
return 404;
43+
}
44+
4045
location /vstats/ {
4146
alias %home%/%user%/web/%domain%/stats/;
4247
include %home%/%user%/web/%domain%/stats/auth.conf*;

install/deb/templates/web/nginx/php-fpm/opencart.tpl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ server {
3131
rewrite ^/(.+)$ /index.php?_route_=$1 last;
3232
}
3333

34+
location /storage/ {
35+
deny all;
36+
return 404;
37+
}
38+
3439
location /vstats/ {
3540
alias %home%/%user%/web/%domain%/stats/;
3641
include %home%/%user%/web/%domain%/stats/auth.conf*;

web/add/webapp/index.php

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
ob_start();
3+
$TAB = 'WEB';
4+
5+
// Main include
6+
include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
7+
require_once $_SERVER['DOCUMENT_ROOT']."/src/init.php";
8+
9+
// Check domain argument
10+
if (empty($_GET['domain'])) {
11+
header("Location: /list/web/");
12+
exit;
13+
}
14+
15+
// Edit as someone else?
16+
if (($_SESSION['user'] == 'admin') && (!empty($_GET['user']))) {
17+
$user=escapeshellarg($_GET['user']);
18+
}
19+
20+
// Get all user domains
21+
exec (HESTIA_CMD."v-list-web-domains ".escapeshellarg($user)." json", $output, $return_var);
22+
$user_domains = json_decode(implode('', $output), true);
23+
$user_domains = array_keys($user_domains);
24+
unset($output);
25+
26+
// List domain
27+
$v_domain = $_GET['domain'];
28+
if(!in_array($v_domain, $user_domains)) {
29+
header("Location: /list/web/");
30+
exit;
31+
}
32+
33+
$v_web_apps = [
34+
[ 'name'=>'Wordpress', 'group'=>'cms', 'enabled'=>true, 'version'=>'5.2.4', 'thumbnail'=>'/images/webapps/wp-thumb.png' ],
35+
[ 'name'=>'Drupal', 'group'=>'cms', 'enabled'=>false,'version'=>'latest', 'thumbnail'=>'/images/webapps/drupal-thumb.png' ],
36+
[ 'name'=>'Joomla', 'group'=>'cms', 'enabled'=>false,'version'=>'latest', 'thumbnail'=>'/images/webapps/joomla-thumb.png' ],
37+
38+
[ 'name'=>'Opencart', 'group'=>'ecommerce', 'enabled'=>true, 'version'=>'3.0.3.2', 'thumbnail'=>'/images/webapps/opencart-thumb.png' ],
39+
[ 'name'=>'Prestashop', 'group'=>'ecommerce', 'enabled'=>true, 'version'=>'1.7.6.1', 'thumbnail'=>'/images/webapps/prestashop-thumb.png' ],
40+
[ 'name'=>'Magento', 'group'=>'ecommerce', 'enabled'=>false, 'version'=>'latest', 'thumbnail'=>'/images/webapps/magento-thumb.png' ],
41+
42+
[ 'name'=>'Laravel', 'group'=>'starter', 'enabled'=>true, 'version'=>'6.x', 'thumbnail'=>'/images/webapps/laravel-thumb.png' ],
43+
[ 'name'=>'Symfony', 'group'=>'starter', 'enabled'=>true, 'version'=>'4.3.x', 'thumbnail'=>'/images/webapps/symfony-thumb.png' ],
44+
];
45+
46+
// Check GET request
47+
if (!empty($_GET['app'])) {
48+
$app = basename($_GET['app']);
49+
50+
try {
51+
$hestia = new \Hestia\System\HestiaApp();
52+
$app_installer_class = '\Hestia\WebApp\Installers\\' . $app . 'Setup';
53+
$app_installer = new $app_installer_class($v_domain, $hestia);
54+
$installer = new \Hestia\WebApp\AppWizard($app_installer, $v_domain, $hestia);
55+
} catch (Exception $e) {
56+
$_SESSION['error_msg'] = $e->getMessage();
57+
header('Location: /add/webapp/?domain=' . $v_domain);
58+
exit();
59+
}
60+
$GLOBALS['WebappInstaller'] = $installer;
61+
}
62+
63+
// Check POST request
64+
if (!empty($_POST['ok']) && !empty($app) ) {
65+
66+
// Check token
67+
if ((!isset($_POST['token'])) || ($_SESSION['token'] != $_POST['token'])) {
68+
header('location: /login/');
69+
exit();
70+
}
71+
72+
if ($installer) {
73+
try{
74+
if (!$installer->execute($_POST)){
75+
$result = $installer->getStatus();
76+
if(!empty($result))
77+
$_SESSION['error_msg'] = implode(PHP_EOL, $result);
78+
} else {
79+
$_SESSION['ok_msg'] = htmlspecialchars($app) . " App was installed succesfully !";
80+
header('Location: /add/webapp/?domain=' . $v_domain);
81+
exit();
82+
}
83+
} catch (Exception $e) {
84+
$_SESSION['error_msg'] = $e->getMessage();
85+
header('Location: /add/webapp/?app='.rawurlencode($app).'&domain=' . $v_domain);
86+
exit();
87+
}
88+
}
89+
}
90+
91+
if(!empty($installer)) {
92+
render_page($user, $TAB, 'setup_webapp');
93+
} else {
94+
render_page($user, $TAB, 'add_webapp');
95+
}
96+
97+
98+
// Flush session messages
99+
unset($_SESSION['error_msg']);
100+
unset($_SESSION['ok_msg']);

web/css/styles.min.css

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,83 @@ form#vstobjects .alert {
11141114
width: 380px;
11151115
}
11161116

1117+
.app-list.cards {
1118+
xdisplay: flex;
1119+
xflex-wrap: wrap;
1120+
align-content: center;
1121+
margin-bottom: 10rem;
1122+
1123+
}
1124+
1125+
1126+
.card {
1127+
float:left;
1128+
overflow: hidden;
1129+
background-color: #f5f5f5;
1130+
border:1px solid #e6e6e6;
1131+
box-sizing: border-box;
1132+
width:200px;
1133+
min-height:260px;
1134+
margin-top:3em;
1135+
margin-right:3em;
1136+
box-shadow: 0px 0px 3px rgba(0,0,0,0.1);
1137+
color: #353535;
1138+
1139+
}
1140+
1141+
.card.disable {
1142+
color: #b6b6b6;
1143+
}
1144+
1145+
.card.disable .card-thumb {
1146+
filter: grayscale(100%);
1147+
opacity: 0.3;
1148+
}
1149+
1150+
.card:nth-child(4n+1) {
1151+
clear:left;
1152+
}
1153+
.card:nth-child(4n) {
1154+
margin-right:0;
1155+
}
1156+
1157+
.card .card-details {
1158+
font-size: 0.8rem;
1159+
padding: 0.5em 0.8em;
1160+
border-top: 1px solid #e6e6e6;
1161+
text-align: center;
1162+
1163+
}
1164+
.card .card-details p {
1165+
margin: 0 0 0.3em 0;
1166+
font-size: 1em;
1167+
text-align: left;
1168+
}
1169+
1170+
.card p.card-title {
1171+
font-size: 1.2em;
1172+
font-weight: 500;
1173+
}
1174+
1175+
.card .card-thumb {
1176+
background-color: #fff;
1177+
display: block;
1178+
height: 180px;
1179+
width: 200px;
1180+
text-align: center;
1181+
}
1182+
.card .card-thumb img {
1183+
max-height: 180px;
1184+
max-width: 200px;
1185+
height: auto;
1186+
width: auto;
1187+
1188+
}
1189+
1190+
.card button {
1191+
margin:0.3em;
1192+
}
1193+
11171194
.l-stat {
11181195
margin: 34px auto;
11191196
position: fixed;
19.5 KB
Loading
61.9 KB
Loading
5.33 KB
Loading
46.6 KB
Loading

0 commit comments

Comments
 (0)