Skip to content

Commit 1d4ca7f

Browse files
committed
Add composer installer method and allow web-backend to run composer commands with dropped privileges (as the logged-in user)
1 parent b4c663f commit 1d4ca7f

File tree

1 file changed

+54
-3
lines changed

1 file changed

+54
-3
lines changed

web/add/webapp/Hestia.php

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public function run(string $cmd, $args, &$cmd_result=null) : bool {
1919
$cli_arguments = escapeshellarg($args);
2020
}
2121

22-
exec ($cli_script . ' ' . $cli_arguments, $output, $exit_code);
22+
exec ($cli_script . ' ' . $cli_arguments . ' 2>&1', $output, $exit_code);
2323

2424
$result['code'] = $exit_code;
2525
$result['args'] = $cli_arguments;
@@ -34,13 +34,59 @@ public function run(string $cmd, $args, &$cmd_result=null) : bool {
3434
public function runUser(string $cmd, $args, &$cmd_result=null) : bool {
3535
if (!empty($args) && is_array($args)) {
3636
array_unshift($args, $this->user());
37-
}
38-
else {
37+
} else {
3938
$args = [$this->user(), $args];
4039
}
4140
return $this->run($cmd, $args, $cmd_result);
4241
}
4342

43+
public function installComposer() {
44+
45+
exec("curl https://composer.github.io/installer.sig", $output);
46+
47+
$signature = implode(PHP_EOL, $output);
48+
if (empty($signature)) {
49+
throw new Exception("Error reading composer signature");
50+
}
51+
52+
$composer_setup = self::TMPDIR_DOWNLOADS . DIRECTORY_SEPARATOR . 'composer-setup-' . $signature . '.php';
53+
54+
exec("wget https://getcomposer.org/installer --quiet -O " . escapeshellarg($composer_setup), $output, $return_code);
55+
if ($return_code !== 0 ) {
56+
throw new Exception("Error downloading composer");
57+
}
58+
59+
if ($signature !== hash_file('sha384', $composer_setup)) {
60+
unlink($composer_setup);
61+
throw new Exception("Invalid composer signature");
62+
}
63+
64+
$install_folder = $this->getUserHomeDir() . DIRECTORY_SEPARATOR . '.composer';
65+
$this->runUser('v-run-cli-cmd', ["/usr/bin/php", $composer_setup, "--quiet", "--install-dir=".$install_folder, "--filename=composer" ], $status);
66+
67+
unlink($composer_setup);
68+
69+
if ($status->code !== 0 ) {
70+
throw new Exception("Error installing composer");
71+
}
72+
}
73+
74+
public function runComposer($args, &$cmd_result=null) : bool {
75+
76+
$composer = $this->getUserHomeDir() . DIRECTORY_SEPARATOR . '.composer' . DIRECTORY_SEPARATOR . 'composer';
77+
if(!is_file($composer)) {
78+
$this->installComposer();
79+
}
80+
81+
if (!empty($args) && is_array($args)) {
82+
array_unshift($args, 'composer');
83+
} else {
84+
$args = ['composer', $args];
85+
}
86+
87+
return $this->runUser('v-run-cli-cmd', $args, $cmd_result);
88+
}
89+
4490
// Logged in user
4591
public function realuser() : string {
4692
return $_SESSION['user'];
@@ -59,6 +105,11 @@ public function user() : string {
59105
return $user;
60106
}
61107

108+
public function getUserHomeDir() {
109+
$info = posix_getpwnam($this->user());
110+
return $info['dir'];
111+
}
112+
62113
public function userOwnsDomain(string $domain) : bool {
63114
return $this->runUser('v-list-web-domain', [$domain, 'json']);
64115
}

0 commit comments

Comments
 (0)