From 12c500e125e82e786abf1e82738fc2e9988804c2 Mon Sep 17 00:00:00 2001 From: Saeed Vaziry <61919774+saeedvaziry@users.noreply.github.com> Date: Fri, 5 Apr 2024 19:45:09 +0200 Subject: [PATCH] Bug fixes (#155) --- app/Actions/SSL/CreateSSL.php | 2 - app/Actions/Site/CreateSite.php | 13 ++- app/Actions/Site/UpdateSourceControl.php | 49 +++++++++ app/Exceptions/SSHAuthenticationError.php | 4 +- app/Exceptions/SSLCreationException.php | 4 +- app/Helpers/SSH.php | 2 +- .../Controllers/ApplicationController.php | 18 ++- app/Http/Controllers/SiteController.php | 27 ++++- .../Controllers/SiteSettingController.php | 10 ++ .../application/auto-deployment.blade.php | 1 + .../application/deployment-script.blade.php | 2 + resources/views/application/php-app.blade.php | 1 + resources/views/console/index.blade.php | 3 +- .../partials/connect.blade.php | 11 ++ resources/views/site-settings/index.blade.php | 4 + .../partials/update-source-control.blade.php | 32 ++++++ resources/views/sites/installing.blade.php | 15 +++ .../create/fields/source-control.blade.php | 2 +- .../views/sites/partials/show-site.blade.php | 17 --- resources/views/sites/show.blade.php | 2 +- routes/server.php | 2 + tests/Feature/SitesTest.php | 103 ++++++++++++++++++ 22 files changed, 288 insertions(+), 36 deletions(-) create mode 100644 app/Actions/Site/UpdateSourceControl.php create mode 100644 resources/views/site-settings/partials/update-source-control.blade.php create mode 100644 resources/views/sites/installing.blade.php delete mode 100644 resources/views/sites/partials/show-site.blade.php diff --git a/app/Actions/SSL/CreateSSL.php b/app/Actions/SSL/CreateSSL.php index 3835659..5a41232 100644 --- a/app/Actions/SSL/CreateSSL.php +++ b/app/Actions/SSL/CreateSSL.php @@ -34,8 +34,6 @@ public function create(Site $site, array $input): void $ssl->status = SslStatus::CREATED; $ssl->save(); $site->type()->edit(); - })->catch(function () use ($ssl) { - $ssl->delete(); }); } diff --git a/app/Actions/Site/CreateSite.php b/app/Actions/Site/CreateSite.php index d1aca35..f1be5b2 100755 --- a/app/Actions/Site/CreateSite.php +++ b/app/Actions/Site/CreateSite.php @@ -3,6 +3,8 @@ namespace App\Actions\Site; use App\Enums\SiteStatus; +use App\Exceptions\RepositoryNotFound; +use App\Exceptions\RepositoryPermissionDenied; use App\Exceptions\SourceControlIsNotConnected; use App\Facades\Notifier; use App\Models\Server; @@ -19,7 +21,6 @@ class CreateSite { /** - * @throws SourceControlIsNotConnected * @throws ValidationException */ public function create(Server $server, array $input): Site @@ -47,7 +48,15 @@ public function create(Server $server, array $input): Site } } catch (SourceControlIsNotConnected) { throw ValidationException::withMessages([ - 'source_control' => __('Source control is not connected'), + 'source_control' => 'Source control is not connected', + ]); + } catch (RepositoryPermissionDenied) { + throw ValidationException::withMessages([ + 'repository' => 'You do not have permission to access this repository', + ]); + } catch (RepositoryNotFound) { + throw ValidationException::withMessages([ + 'repository' => 'Repository not found', ]); } diff --git a/app/Actions/Site/UpdateSourceControl.php b/app/Actions/Site/UpdateSourceControl.php new file mode 100644 index 0000000..02edbab --- /dev/null +++ b/app/Actions/Site/UpdateSourceControl.php @@ -0,0 +1,49 @@ +validate($input); + + $site->source_control_id = $input['source_control']; + try { + if ($site->sourceControl()) { + $site->sourceControl()->getRepo($site->repository); + } + } catch (SourceControlIsNotConnected) { + throw ValidationException::withMessages([ + 'source_control' => 'Source control is not connected', + ]); + } catch (RepositoryPermissionDenied) { + throw ValidationException::withMessages([ + 'repository' => 'You do not have permission to access this repository', + ]); + } catch (RepositoryNotFound) { + throw ValidationException::withMessages([ + 'repository' => 'Repository not found', + ]); + } + $site->save(); + } + + private function validate(array $input): void + { + Validator::make($input, [ + 'source_control' => [ + 'required', + Rule::exists('source_controls', 'id'), + ], + ])->validate(); + } +} diff --git a/app/Exceptions/SSHAuthenticationError.php b/app/Exceptions/SSHAuthenticationError.php index 45c447d..1cfe299 100755 --- a/app/Exceptions/SSHAuthenticationError.php +++ b/app/Exceptions/SSHAuthenticationError.php @@ -2,9 +2,7 @@ namespace App\Exceptions; -use Exception; - -class SSHAuthenticationError extends Exception +class SSHAuthenticationError extends SSHError { // } diff --git a/app/Exceptions/SSLCreationException.php b/app/Exceptions/SSLCreationException.php index 22034af..4ec5d9c 100644 --- a/app/Exceptions/SSLCreationException.php +++ b/app/Exceptions/SSLCreationException.php @@ -2,9 +2,7 @@ namespace App\Exceptions; -use Exception; - -class SSLCreationException extends Exception +class SSLCreationException extends SSHError { // } diff --git a/app/Helpers/SSH.php b/app/Helpers/SSH.php index 3536f3e..e6a5dc8 100755 --- a/app/Helpers/SSH.php +++ b/app/Helpers/SSH.php @@ -133,7 +133,7 @@ public function exec(string $command, string $log = '', ?int $siteId = null, ?bo $this->log?->write($output); if (Str::contains($output, 'VITO_SSH_ERROR')) { - throw new Exception('SSH command failed with an error'); + throw new SSHCommandError('SSH command failed with an error'); } return $output; diff --git a/app/Http/Controllers/ApplicationController.php b/app/Http/Controllers/ApplicationController.php index bb6ac01..47ce228 100644 --- a/app/Http/Controllers/ApplicationController.php +++ b/app/Http/Controllers/ApplicationController.php @@ -7,6 +7,8 @@ use App\Actions\Site\UpdateDeploymentScript; use App\Actions\Site\UpdateEnv; use App\Exceptions\DeploymentScriptIsEmptyException; +use App\Exceptions\RepositoryNotFound; +use App\Exceptions\RepositoryPermissionDenied; use App\Exceptions\SourceControlIsNotConnected; use App\Facades\Toast; use App\Helpers\HtmxResponse; @@ -24,12 +26,14 @@ public function deploy(Server $server, Site $site): HtmxResponse app(Deploy::class)->run($site); Toast::success('Deployment started!'); - } catch (SourceControlIsNotConnected $e) { - Toast::error($e->getMessage()); - - return htmx()->redirect(route('source-controls')); + } catch (SourceControlIsNotConnected) { + Toast::error('Source control is not connected. Check site\'s settings.'); } catch (DeploymentScriptIsEmptyException) { Toast::error('Deployment script is empty!'); + } catch (RepositoryPermissionDenied) { + Toast::error('You do not have permission to access this repository!'); + } catch (RepositoryNotFound) { + Toast::error('Repository not found!'); } return htmx()->back(); @@ -83,6 +87,12 @@ public function enableAutoDeployment(Server $server, Site $site): HtmxResponse Toast::success('Auto deployment has been enabled.'); } catch (SourceControlIsNotConnected) { Toast::error('Source control is not connected. Check site\'s settings.'); + } catch (DeploymentScriptIsEmptyException) { + Toast::error('Deployment script is empty!'); + } catch (RepositoryPermissionDenied) { + Toast::error('You do not have permission to access this repository!'); + } catch (RepositoryNotFound) { + Toast::error('Repository not found!'); } } diff --git a/app/Http/Controllers/SiteController.php b/app/Http/Controllers/SiteController.php index 4b57cb7..1ad175d 100644 --- a/app/Http/Controllers/SiteController.php +++ b/app/Http/Controllers/SiteController.php @@ -4,6 +4,7 @@ use App\Actions\Site\CreateSite; use App\Actions\Site\DeleteSite; +use App\Enums\SiteStatus; use App\Enums\SiteType; use App\Facades\Toast; use App\Helpers\HtmxResponse; @@ -42,14 +43,38 @@ public function create(Server $server): View ]); } - public function show(Server $server, Site $site): View + public function show(Server $server, Site $site, Request $request): View|RedirectResponse|HtmxResponse { + if (in_array($site->status, [SiteStatus::INSTALLING, SiteStatus::INSTALLATION_FAILED])) { + if ($request->hasHeader('HX-Request')) { + return htmx()->redirect(route('servers.sites.installing', [$server, $site])); + } + + return redirect()->route('servers.sites.installing', [$server, $site]); + } + return view('sites.show', [ 'server' => $server, 'site' => $site, ]); } + public function installing(Server $server, Site $site, Request $request): View|RedirectResponse|HtmxResponse + { + if (! in_array($site->status, [SiteStatus::INSTALLING, SiteStatus::INSTALLATION_FAILED])) { + if ($request->hasHeader('HX-Request')) { + return htmx()->redirect(route('servers.sites.show', [$server, $site])); + } + + return redirect()->route('servers.sites.show', [$server, $site]); + } + + return view('sites.installing', [ + 'server' => $server, + 'site' => $site, + ]); + } + public function destroy(Server $server, Site $site): RedirectResponse { app(DeleteSite::class)->delete($site); diff --git a/app/Http/Controllers/SiteSettingController.php b/app/Http/Controllers/SiteSettingController.php index b2b940f..9a037a9 100644 --- a/app/Http/Controllers/SiteSettingController.php +++ b/app/Http/Controllers/SiteSettingController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Actions\Site\UpdateSourceControl; use App\Facades\Toast; use App\Helpers\HtmxResponse; use App\Models\Server; @@ -63,4 +64,13 @@ public function updatePHPVersion(Server $server, Site $site, Request $request): return htmx()->back(); } + + public function updateSourceControl(Server $server, Site $site, Request $request): HtmxResponse + { + $site = app(UpdateSourceControl::class)->update($site, $request->input()); + + Toast::success('Source control updated successfully!'); + + return htmx()->back(); + } } diff --git a/resources/views/application/auto-deployment.blade.php b/resources/views/application/auto-deployment.blade.php index 797220f..69de8f6 100644 --- a/resources/views/application/auto-deployment.blade.php +++ b/resources/views/application/auto-deployment.blade.php @@ -4,6 +4,7 @@ {{ __("Auto Deployment") }} + diff --git a/resources/views/application/deployment-script.blade.php b/resources/views/application/deployment-script.blade.php index 1be5df4..1bedfcb 100644 --- a/resources/views/application/deployment-script.blade.php +++ b/resources/views/application/deployment-script.blade.php @@ -12,6 +12,8 @@ class="p-6" {{ __("Deployment Script") }} +
A bash script that will be executed when you run the deployment process.
+
diff --git a/resources/views/application/php-app.blade.php b/resources/views/application/php-app.blade.php index 79c48a6..beaa17a 100644 --- a/resources/views/application/php-app.blade.php +++ b/resources/views/application/php-app.blade.php @@ -19,6 +19,7 @@ {{ __("Manage") }} + diff --git a/resources/views/console/index.blade.php b/resources/views/console/index.blade.php index 8204e2d..e40fafa 100644 --- a/resources/views/console/index.blade.php +++ b/resources/views/console/index.blade.php @@ -10,7 +10,7 @@ runUrl: '{{ route("servers.console.run", ["server" => $server]) }}', async run() { this.running = true - this.output = 'Running...\n' + this.output = this.command + '\n' const fetchOptions = { method: 'POST', headers: { @@ -23,6 +23,7 @@ }), } + this.command = '' const response = await fetch(this.runUrl, fetchOptions) const reader = response.body.getReader() const decoder = new TextDecoder('utf-8') diff --git a/resources/views/settings/source-controls/partials/connect.blade.php b/resources/views/settings/source-controls/partials/connect.blade.php index b492ab3..b1280e5 100644 --- a/resources/views/settings/source-controls/partials/connect.blade.php +++ b/resources/views/settings/source-controls/partials/connect.blade.php @@ -38,6 +38,17 @@ class="p-6" @endif @endforeach + + Check + + here + + to see what permissions you need + @error("provider") @enderror diff --git a/resources/views/site-settings/index.blade.php b/resources/views/site-settings/index.blade.php index a623076..4588f6d 100644 --- a/resources/views/site-settings/index.blade.php +++ b/resources/views/site-settings/index.blade.php @@ -3,6 +3,10 @@ @include("site-settings.partials.change-php-version") + @if ($site->source_control_id) + @include("site-settings.partials.update-source-control") + @endif + @include("site-settings.partials.update-v-host") diff --git a/resources/views/site-settings/partials/update-source-control.blade.php b/resources/views/site-settings/partials/update-source-control.blade.php new file mode 100644 index 0000000..9bba670 --- /dev/null +++ b/resources/views/site-settings/partials/update-source-control.blade.php @@ -0,0 +1,32 @@ + + {{ __("Update Source Control") }} + + + {{ __("You can switch the source control profile (token) in case of token expiration. Keep in mind that it must be the same account and provider") }} + + +
$server, "site" => $site]) }}" + hx-swap="outerHTML" + hx-select="#update-source-control" + hx-ext="disable-element" + hx-disable-element="#btn-update-source-control" + class="space-y-6" + > + @include( + "sites.partials.create.fields.source-control", + [ + "sourceControls" => \App\Models\SourceControl::query() + ->where("provider", $site->sourceControl()?->provider) + ->get(), + ] + ) +
+ + + + {{ __("Save") }} + + +
diff --git a/resources/views/sites/installing.blade.php b/resources/views/sites/installing.blade.php new file mode 100644 index 0000000..6d90ae8 --- /dev/null +++ b/resources/views/sites/installing.blade.php @@ -0,0 +1,15 @@ + + {{ $site->domain }} + + + @if ($site->status === \App\Enums\SiteStatus::INSTALLING) + @include("sites.partials.installing", ["site" => $site]) + @endif + + @if ($site->status === \App\Enums\SiteStatus::INSTALLATION_FAILED) + @include("sites.partials.installation-failed", ["site" => $site]) + @endif + + + @include("server-logs.partials.logs-list", ["server" => $site->server, "site" => $site]) + diff --git a/resources/views/sites/partials/create/fields/source-control.blade.php b/resources/views/sites/partials/create/fields/source-control.blade.php index b9cf00c..7bbb844 100644 --- a/resources/views/sites/partials/create/fields/source-control.blade.php +++ b/resources/views/sites/partials/create/fields/source-control.blade.php @@ -6,7 +6,7 @@ @foreach ($sourceControls as $sourceControl)