From 1223ea149901221e90ca37f038bda93cbb4ac1f4 Mon Sep 17 00:00:00 2001 From: Richard Anderson Date: Sat, 22 Feb 2025 08:23:03 +0000 Subject: [PATCH] Fix .env Files for Isolated Users (#496) --- app/Actions/Site/UpdateEnv.php | 9 +++++---- app/Helpers/SSH.php | 4 +++- app/SSH/OS/OS.php | 22 ++++++++++++++++++++-- resources/views/ssh/os/edit-file.blade.php | 9 +++++++++ tests/Feature/ApplicationTest.php | 3 ++- 5 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 resources/views/ssh/os/edit-file.blade.php diff --git a/app/Actions/Site/UpdateEnv.php b/app/Actions/Site/UpdateEnv.php index c221e4d..fa138c8 100644 --- a/app/Actions/Site/UpdateEnv.php +++ b/app/Actions/Site/UpdateEnv.php @@ -2,19 +2,20 @@ namespace App\Actions\Site; -use App\Exceptions\SSHUploadFailed; +use App\Exceptions\SSHError; use App\Models\Site; class UpdateEnv { /** - * @throws SSHUploadFailed + * @throws SSHError */ public function update(Site $site, array $input): void { - $site->server->os()->editFile( + $site->server->os()->editFileAs( $site->path.'/.env', - $input['env'] + $site->user, + trim($input['env']), ); } } diff --git a/app/Helpers/SSH.php b/app/Helpers/SSH.php index 40e6bdc..06e7933 100755 --- a/app/Helpers/SSH.php +++ b/app/Helpers/SSH.php @@ -112,7 +112,9 @@ public function exec(string $command, string $log = '', ?int $siteId = null, ?bo try { if ($this->asUser) { - $command = 'sudo su - '.$this->asUser.' -c '.'"'.addslashes($command).'"'; + $command = addslashes($command); + $command = str_replace('\\\'', '\'', $command); + $command = 'sudo su - '.$this->asUser.' -c '.'"'.trim($command).'"'; } $this->connection->setTimeout(0); diff --git a/app/SSH/OS/OS.php b/app/SSH/OS/OS.php index 6e95b8d..f5b57fc 100644 --- a/app/SSH/OS/OS.php +++ b/app/SSH/OS/OS.php @@ -198,16 +198,34 @@ public function editFile(string $path, ?string $content = null): void } } + /** + * @throws SSHError + */ + public function editFileAs(string $path, string $user, ?string $content = null): void + { + $sudo = $user === 'root'; + $actualUser = $sudo ? $this->server->getSshUser() : $user; + + $this->server->ssh($actualUser)->exec( + view('ssh.os.edit-file', [ + 'path' => $path, + 'content' => $content, + 'sudo' => $sudo, + ]), + 'edit-file' + ); + } + /** * @throws SSHError */ public function readFile(string $path): string { - return $this->server->ssh()->exec( + return trim($this->server->ssh()->exec( view('ssh.os.read-file', [ 'path' => $path, ]) - ); + )); } /** diff --git a/resources/views/ssh/os/edit-file.blade.php b/resources/views/ssh/os/edit-file.blade.php new file mode 100644 index 0000000..63c2737 --- /dev/null +++ b/resources/views/ssh/os/edit-file.blade.php @@ -0,0 +1,9 @@ +@if($sudo) sudo @endif tee {!! $path !!} << 'VITO_SSH_EOF' > /dev/null +{!! $content !!} +VITO_SSH_EOF + +if [ $? -eq 0 ]; then + echo "Successfully wrote to {{ $path }}" +else + echo 'VITO_SSH_ERROR' && exit 1 +fi diff --git a/tests/Feature/ApplicationTest.php b/tests/Feature/ApplicationTest.php index 3811f90..5a63c63 100644 --- a/tests/Feature/ApplicationTest.php +++ b/tests/Feature/ApplicationTest.php @@ -202,7 +202,8 @@ public function test_update_env_file(): void ->assertSuccessful() ->assertNotified('.env updated!'); - SSH::assertFileUploaded('/home/vito/'.$this->site->domain.'/.env', 'APP_ENV="production"'); + SSH::assertExecutedContains('tee /home/vito/vito.test/.env << \'VITO_SSH_EOF\''); + SSH::assertExecutedContains('APP_ENV="production"'); } public function test_git_hook_deployment(): void