From 3bf3f7eebc45c40459c48f0ada736f53fb559dbb Mon Sep 17 00:00:00 2001 From: Saeed Vaziry <61919774+saeedvaziry@users.noreply.github.com> Date: Wed, 26 Feb 2025 20:46:07 +0100 Subject: [PATCH] Fix filemanager permissions (#508) * Fix filemanager permissions * fix filemanager permissions * fix tests warning --- .github/workflows/tests.yml | 3 ++ app/Facades/SSH.php | 3 ++ app/Helpers/SSH.php | 25 +++++++----- app/SSH/OS/OS.php | 40 +++---------------- app/SSH/Services/PHP/PHP.php | 2 +- .../Services/ProcessManager/Supervisor.php | 2 +- app/SSH/Services/Webserver/Nginx.php | 6 +-- app/Support/Testing/SSHFake.php | 2 +- app/Web/Pages/Servers/FileManager/Index.php | 2 +- .../Servers/FileManager/Widgets/FilesList.php | 3 +- app/Web/Pages/Servers/Page.php | 2 +- docker/publish.sh | 21 ++++++++++ 12 files changed, 56 insertions(+), 55 deletions(-) create mode 100644 docker/publish.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d89c2a2..3914070 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -40,5 +40,8 @@ jobs: - name: Create sqlite database run: touch storage/database-test.sqlite + - name: Set up the .env file + run: touch .env + - name: Run test suite run: php artisan test diff --git a/app/Facades/SSH.php b/app/Facades/SSH.php index 5cbb0a6..7d0cde3 100644 --- a/app/Facades/SSH.php +++ b/app/Facades/SSH.php @@ -14,6 +14,9 @@ * @method static setLog(?ServerLog $log) * @method static connect() * @method static string exec(string $command, string $log = '', int $siteId = null, ?bool $stream = false, callable $streamCallback = null) + * @method static string upload(string $local, string $remote, ?string $owner = null) + * @method static string download(string $local, string $remote) + * @method static string write(string $path, string $content, string $owner = null) * @method static string assertExecuted(array|string $commands) * @method static string assertExecutedContains(string $command) * @method static string assertFileUploaded(string $toPath, ?string $content = null) diff --git a/app/Helpers/SSH.php b/app/Helpers/SSH.php index 06e7933..db23335 100755 --- a/app/Helpers/SSH.php +++ b/app/Helpers/SSH.php @@ -157,7 +157,7 @@ public function exec(string $command, string $log = '', ?int $siteId = null, ?bo /** * @throws Throwable */ - public function upload(string $local, string $remote): void + public function upload(string $local, string $remote, ?string $owner = null): void { $this->log = null; @@ -165,7 +165,17 @@ public function upload(string $local, string $remote): void $this->connect(true); } - $this->connection->put($remote, $local, SFTP::SOURCE_LOCAL_FILE); + $tmpName = Str::random(10).strtotime('now'); + $tempPath = home_path($this->user).'/'.$tmpName; + + $this->connection->put($tempPath, $local, SFTP::SOURCE_LOCAL_FILE); + + $this->exec(sprintf('sudo mv %s %s', $tempPath, $remote)); + if (! $owner) { + $owner = $this->user; + } + $this->exec(sprintf('sudo chown %s:%s %s', $owner, $owner, $remote)); + $this->exec(sprintf('sudo chmod 644 %s', $remote)); } /** @@ -185,22 +195,15 @@ public function download(string $local, string $remote): void /** * @throws SSHError */ - public function write(string $remotePath, string $content, bool $sudo = false): void + public function write(string $remotePath, string $content, ?string $owner = null): void { $tmpName = Str::random(10).strtotime('now'); try { /** @var FilesystemAdapter $storageDisk */ $storageDisk = Storage::disk('local'); - $storageDisk->put($tmpName, $content); - - if ($sudo) { - $this->upload($storageDisk->path($tmpName), sprintf('/home/%s/%s', $this->server->ssh_user, $tmpName)); - $this->exec(sprintf('sudo mv /home/%s/%s %s', $this->server->ssh_user, $tmpName, $remotePath)); - } else { - $this->upload($storageDisk->path($tmpName), $remotePath); - } + $this->upload($storageDisk->path($tmpName), $remotePath, $owner); } catch (Throwable $e) { throw new SSHCommandError( message: $e->getMessage() diff --git a/app/SSH/OS/OS.php b/app/SSH/OS/OS.php index f5b57fc..934017a 100644 --- a/app/SSH/OS/OS.php +++ b/app/SSH/OS/OS.php @@ -3,14 +3,9 @@ namespace App\SSH\OS; use App\Exceptions\SSHError; -use App\Exceptions\SSHUploadFailed; use App\Models\Server; use App\Models\ServerLog; use App\Models\Site; -use Illuminate\Filesystem\FilesystemAdapter; -use Illuminate\Support\Facades\Storage; -use Illuminate\Support\Str; -use Throwable; class OS { @@ -178,27 +173,8 @@ public function reboot(): void } /** - * @throws SSHUploadFailed - */ - public function editFile(string $path, ?string $content = null): void - { - $tmpName = Str::random(10).strtotime('now'); - try { - /** @var FilesystemAdapter $storageDisk */ - $storageDisk = Storage::disk('local'); - $storageDisk->put($tmpName, $content); - $this->server->ssh()->upload( - $storageDisk->path($tmpName), - $path - ); - } catch (Throwable) { - throw new SSHUploadFailed; - } finally { - $this->deleteTempFile($tmpName); - } - } - - /** + * @deprecated use write() instead + * * @throws SSHError */ public function editFileAs(string $path, string $user, ?string $content = null): void @@ -349,9 +325,10 @@ public function ls(string $path, ?string $user = null): string */ public function write(string $path, string $content, ?string $user = null): void { - $this->server->ssh($user)->write( + $this->server->ssh()->write( $path, - $content + $content, + $user ); } @@ -362,11 +339,4 @@ public function mkdir(string $path, ?string $user = null): string { return $this->server->ssh($user)->exec('mkdir -p '.$path); } - - private function deleteTempFile(string $name): void - { - if (Storage::disk('local')->exists($name)) { - Storage::disk('local')->delete($name); - } - } } diff --git a/app/SSH/Services/PHP/PHP.php b/app/SSH/Services/PHP/PHP.php index 2c71a4c..43ff803 100644 --- a/app/SSH/Services/PHP/PHP.php +++ b/app/SSH/Services/PHP/PHP.php @@ -135,7 +135,7 @@ public function createFpmPool(string $user, string $version, $site_id): void 'user' => $user, 'version' => $version, ]), - true + 'root' ); $this->service->server->systemd()->restart($this->service->unit); diff --git a/app/SSH/Services/ProcessManager/Supervisor.php b/app/SSH/Services/ProcessManager/Supervisor.php index c2d81d2..c1b6e69 100644 --- a/app/SSH/Services/ProcessManager/Supervisor.php +++ b/app/SSH/Services/ProcessManager/Supervisor.php @@ -55,7 +55,7 @@ public function create( 'numprocs' => (string) $numprocs, 'logFile' => $logFile, ]), - true + 'root' ); $this->service->server->ssh()->exec( diff --git a/app/SSH/Services/Webserver/Nginx.php b/app/SSH/Services/Webserver/Nginx.php index 3c477de..4c6f0dd 100755 --- a/app/SSH/Services/Webserver/Nginx.php +++ b/app/SSH/Services/Webserver/Nginx.php @@ -26,7 +26,7 @@ public function install(): void view('ssh.services.webserver.nginx.nginx', [ 'user' => $this->service->server->getSshUser(), ]), - true + 'root' ); $this->service->server->systemd()->restart('nginx'); @@ -83,7 +83,7 @@ public function createVHost(Site $site): void view('ssh.services.webserver.nginx.vhost', [ 'site' => $site, ]), - true + 'root' ); $this->service->server->ssh()->exec( @@ -108,7 +108,7 @@ public function updateVHost(Site $site, ?string $vhost = null): void $vhost ?? view('ssh.services.webserver.nginx.vhost', [ 'site' => $site, ]), - true + 'root' ); $this->service->server->systemd()->restart('nginx'); diff --git a/app/Support/Testing/SSHFake.php b/app/Support/Testing/SSHFake.php index 5973d8f..3d5c4a3 100644 --- a/app/Support/Testing/SSHFake.php +++ b/app/Support/Testing/SSHFake.php @@ -82,7 +82,7 @@ public function exec(string $command, string $log = '', ?int $siteId = null, ?bo return $output; } - public function upload(string $local, string $remote): void + public function upload(string $local, string $remote, ?string $owner = null): void { $this->uploadedLocalPath = $local; $this->uploadedRemotePath = $remote; diff --git a/app/Web/Pages/Servers/FileManager/Index.php b/app/Web/Pages/Servers/FileManager/Index.php index a5f9412..ddad755 100644 --- a/app/Web/Pages/Servers/FileManager/Index.php +++ b/app/Web/Pages/Servers/FileManager/Index.php @@ -14,7 +14,7 @@ class Index extends Page public function mount(): void { - $this->authorize('update', $this->server); + $this->authorize('manage', $this->server); } public function getWidgets(): array diff --git a/app/Web/Pages/Servers/FileManager/Widgets/FilesList.php b/app/Web/Pages/Servers/FileManager/Widgets/FilesList.php index 244900d..11c3310 100644 --- a/app/Web/Pages/Servers/FileManager/Widgets/FilesList.php +++ b/app/Web/Pages/Servers/FileManager/Widgets/FilesList.php @@ -269,9 +269,10 @@ protected function uploadAction(): Action ->after(function (array $data) { run_action($this, function () use ($data) { foreach ($data['file'] as $file) { - $this->server->ssh($this->serverUser)->upload( + $this->server->ssh()->upload( Storage::disk('tmp')->path($file), $this->path.'/'.$file, + $this->serverUser ); } $this->refresh(); diff --git a/app/Web/Pages/Servers/Page.php b/app/Web/Pages/Servers/Page.php index 9b38077..42c0ccc 100644 --- a/app/Web/Pages/Servers/Page.php +++ b/app/Web/Pages/Servers/Page.php @@ -60,7 +60,7 @@ public function getSubNavigation(): array ->url(DatabasesIndex::getUrl(parameters: ['server' => $this->server])); } - if (auth()->user()->can('update', $this->server)) { + if (auth()->user()->can('manage', $this->server)) { $items[] = NavigationItem::make(FileManagerIndex::getNavigationLabel()) ->icon('heroicon-o-folder') ->isActiveWhen(fn () => request()->routeIs(FileManagerIndex::getRouteName().'*')) diff --git a/docker/publish.sh b/docker/publish.sh new file mode 100644 index 0000000..23a5564 --- /dev/null +++ b/docker/publish.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +TAG=$1 + +if [ -z "$TAG" ]; then + echo "No tag provided" + exit 1 +fi + +rm -rf /tmp/vito + +git clone git@github.com:vitodeploy/vito.git /tmp/vito + +cd /tmp/vito || exit + +docker buildx build . \ + -f docker/Dockerfile \ + -t vitodeploy/vito:"$TAG" \ + --platform linux/amd64,linux/arm64 \ + --no-cache \ + --push